Add 'ask' param back to HashSWF, expose HandlePacket as RTMP_ClientPacket
authorhyc <hyc@400ebc74-4327-4243-bc38-086b20814532>
Wed, 30 Dec 2009 08:17:27 +0000 (08:17 +0000)
committerhyc <hyc@400ebc74-4327-4243-bc38-086b20814532>
Wed, 30 Dec 2009 08:17:27 +0000 (08:17 +0000)
git-svn-id: svn://svn.mplayerhq.hu/rtmpdump/trunk@144 400ebc74-4327-4243-bc38-086b20814532

hashswf.c
rtmp.c
rtmp.h
rtmpdump.c
rtmpsuck.c
streams.c

index 8ad006b..779d606 100644 (file)
--- a/hashswf.c
+++ b/hashswf.c
@@ -222,7 +222,7 @@ leave:
 #define HEX2BIN(a)      (((a)&0x40)?((a)&0xf)+9:((a)&0xf))
 
 int
-RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash)
+RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, int ask)
 {
   FILE *f = NULL;
   char *path, *home, date[64];
@@ -291,6 +291,9 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash)
         }
     }
 
+  if (got && !ask)
+    return 0;
+
   in.first = 1;
   in.date = date;
   HMAC_CTX_init(&ctx);
diff --git a/rtmp.c b/rtmp.c
index 061007f..2efa0a8 100644 (file)
--- a/rtmp.c
+++ b/rtmp.c
@@ -93,7 +93,6 @@ static bool SendPlay(RTMP * r);
 static bool SendSeek(RTMP * r, double dTime);
 static bool SendBytesReceived(RTMP * r);
 
-static int HandlePacket(RTMP * r, RTMPPacket * packet);
 static int HandleInvoke(RTMP * r, const char *body, unsigned int nBodySize);
 static bool HandleMetadata(RTMP * r, char *body, unsigned int len);
 static void HandleChangeChunkSize(RTMP * r, const RTMPPacket * packet);
@@ -495,7 +494,7 @@ RTMP_ConnectStream(RTMP * r, double seekTime, uint32_t dLength)
              break;
            }
 
-         HandlePacket(r, &packet);
+         RTMP_ClientPacket(r, &packet);
          RTMPPacket_Free(&packet);
        }
     }
@@ -555,7 +554,7 @@ RTMP_GetNextMediaPacket(RTMP * r, RTMPPacket * packet)
          continue;
        }
 
-      bHasMediaPacket = HandlePacket(r, packet);
+      bHasMediaPacket = RTMP_ClientPacket(r, packet);
 
       if (!bHasMediaPacket)
        {
@@ -587,8 +586,8 @@ RTMP_GetNextMediaPacket(RTMP * r, RTMPPacket * packet)
   return bHasMediaPacket;
 }
 
-static int
-HandlePacket(RTMP * r, RTMPPacket * packet)
+int
+RTMP_ClientPacket(RTMP * r, RTMPPacket * packet)
 {
   int bHasMediaPacket = 0;
   switch (packet->m_packetType)
diff --git a/rtmp.h b/rtmp.h
index c08f386..98fd66e 100644 (file)
--- a/rtmp.h
+++ b/rtmp.h
@@ -198,6 +198,7 @@ bool RTMP_ConnectStream(RTMP *r, double seekTime, uint32_t dLength);
 bool RTMP_ReconnectStream(RTMP *r, int bufferTime, double seekTime, uint32_t dLength);
 void RTMP_DeleteStream(RTMP *r);
 int RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet);
+int RTMP_ClientPacket(RTMP *r, RTMPPacket *packet);
 
 void RTMP_Init(RTMP *r);
 void RTMP_Close(RTMP *r);
@@ -211,7 +212,7 @@ bool RTMP_FindFirstMatchingProperty(AMFObject *obj, const AVal *name,
 /* hashswf.c */
 #define HASHLEN        32
 
-int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash);
+int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, int ask);
 #endif
 
 #endif
index d27e272..1d857d6 100644 (file)
@@ -1284,7 +1284,7 @@ main(int argc, char **argv)
          }
         case 'W':
          STR2AVAL(swfUrl, optarg);
-          if (RTMP_HashSWF(optarg, &swfSize, hash) == 0)
+          if (RTMP_HashSWF(optarg, &swfSize, hash, 1) == 0)
             {
               swfHash.av_val = (char *)hash;
               swfHash.av_len = HASHLEN;
index a278a51..1e8a468 100644 (file)
@@ -110,6 +110,8 @@ FILE *netstackdump = NULL;
 FILE *netstackdump_read = NULL;
 #endif
 
+#define BUFFERTIME     (4*60*60*1000)  /* 4 hours */
+
 #define SAVC(x) static const AVal av_##x = AVC(#x)
 
 SAVC(app);
@@ -299,6 +301,11 @@ ServeInvoke(STREAMING_SERVER *server, RTMPPacket *pack, const char *body)
       for (p=file; *p; p++)
         if (*p == '/')
           *p = '_';
+        else if (*p == '?')
+          {
+            *p = '\0';
+            break;
+          }
       LogPrintf("Playpath: %.*s, writing to %s\n", server->rc.Link.playpath.av_len,
         server->rc.Link.playpath.av_val, file);
       server->out = fopen(file, "wb");
@@ -664,6 +671,7 @@ void doServe(STREAMING_SERVER * server,     // server socket and state (our listenin
   RTMPPacket pc = { 0 }, ps = { 0 };
   char *buf;
   unsigned int buflen = 131072;
+  bool paused = false;
 
   // timeout for http requests
   fd_set rfds;
@@ -708,8 +716,8 @@ void doServe(STREAMING_SERVER * server,     // server socket and state (our listenin
     }
 
   /* We have our own timeout in select() */
-  server->rc.Link.timeout = 1;
-  server->rs.Link.timeout = 1;
+  server->rc.Link.timeout = 10;
+  server->rs.Link.timeout = 10;
   while (RTMP_IsConnected(&server->rs) || RTMP_IsConnected(&server->rc))
     {
       int n;
@@ -738,12 +746,17 @@ void doServe(STREAMING_SERVER * server,   // server socket and state (our listenin
 
          if (select(n + 1, &rfds, NULL, NULL, &tv) <= 0)
            {
-              /* FIXME: Need to get the ToggleStream support in place */
-              /* if (!server->out || !RTMP_ToggleStream(&server->rc)) */
+              if (server->out && server->rc.m_mediaChannel && !paused)
                 {
-                 Log(LOGERROR, "Request timeout/select failed, ignoring request");
-                 goto cleanup;
+                  server->rc.m_pauseStamp = server->rc.m_channelTimestamp[server->rc.m_mediaChannel];
+                  if (RTMP_ToggleStream(&server->rc))
+                    {
+                      paused = true;
+                      continue;
+                    }
                 }
+             Log(LOGERROR, "Request timeout/select failed, ignoring request");
+             goto cleanup;
            }
           if (FD_ISSET(server->rs.m_socket, &rfds))
             sr = 1;
@@ -766,6 +779,31 @@ void doServe(STREAMING_SERVER * server,    // server socket and state (our listenin
                         server->rc.m_outChunkSize = server->rs.m_inChunkSize;
                       }
                   }
+                /* ctrl */
+                else if (ps.m_packetType == 0x04)
+                  {
+                    short nType = AMF_DecodeInt16(ps.m_body);
+                    /* UpdateBufferMS */
+                    if (nType == 0x03)
+                      {
+                        char *ptr = ps.m_body+2;
+                        int id;
+                        int len;
+                        id = AMF_DecodeInt32(ptr);
+                        /* Assume the interesting media is on a non-zero stream */
+                        if (id)
+                          {
+                            len = AMF_DecodeInt32(ptr+4);
+                            /* request a big buffer */
+                            if (len < BUFFERTIME)
+                              {
+                                AMF_EncodeInt32(ptr+4, ptr+8, BUFFERTIME);
+                              }
+                            Log(LOGDEBUG, "%s, client: BufferTime change in stream %d to %d", __FUNCTION__,
+                                id, len);
+                          }
+                      }
+                  }
                 else if (!server->out && (ps.m_packetType == 0x11 || ps.m_packetType == 0x14))
                   ServePacket(server, &ps);
                 RTMP_SendPacket(&server->rc, &ps, false);
@@ -779,6 +817,13 @@ void doServe(STREAMING_SERVER * server,    // server socket and state (our listenin
             if (RTMPPacket_IsReady(&pc))
               {
                 int sendit = 1;
+                if (paused)
+                  {
+                    if (pc.m_nTimeStamp <= server->rc.m_mediaStamp)
+                      continue;
+                    paused = 0;
+                    server->rc.m_pausing = 0;
+                  }
                 /* change chunk size */
                 if (pc.m_packetType == 0x01)
                   {
@@ -804,7 +849,8 @@ void doServe(STREAMING_SERVER * server,     // server socket and state (our listenin
                      pc.m_packetType == 0x08 ||
                      pc.m_packetType == 0x09 ||
                      pc.m_packetType == 0x12 ||
-                     pc.m_packetType == 0x16))
+                     pc.m_packetType == 0x16) &&
+                     RTMP_ClientPacket(&server->rc, &pc))
                   {
                     int len = WriteStream(&buf, &buflen, &server->stamp, &pc);
                     if (len > 0 && fwrite(buf, 1, len, server->out) != len)
@@ -814,11 +860,11 @@ void doServe(STREAMING_SERVER * server,   // server socket and state (our listenin
                      pc.m_packetType == 0x11 ||
                      pc.m_packetType == 0x14))
                   {
-                     if (ServePacket(server, &pc))
-                       {
-                         fclose(server->out);
-                         server->out = NULL;
-                       }
+                    if (ServePacket(server, &pc))
+                      {
+                        fclose(server->out);
+                        server->out = NULL;
+                      }
                   }
 
                 if (sendit && RTMP_IsConnected(&server->rs))
@@ -994,6 +1040,8 @@ main(int argc, char **argv)
   LogPrintf("RTMP Proxy Server %s\n", RTMPDUMP_PROXY_VERSION);
   LogPrintf("(c) 2009 Andrej Stepanchuk, Howard Chu; license: GPL\n\n");
 
+  debuglevel = LOGDEBUG;
+
   if (argc > 1 && !strcmp(argv[1], "-z"))
     debuglevel = LOGALL;
 
index 34b92c1..7067455 100644 (file)
--- a/streams.c
+++ b/streams.c
@@ -942,7 +942,7 @@ ParseOption(char opt, char *arg, RTMP_REQUEST * req)
         unsigned char hash[HASHLEN];
 
         STR2AVAL(req->swfUrl, arg);
-        if (RTMP_HashSWF(arg, &req->swfSize, hash) == 0)
+        if (RTMP_HashSWF(arg, &req->swfSize, hash, 1) == 0)
           {
             req->swfHash.av_val = malloc(HASHLEN);
             req->swfHash.av_len = HASHLEN;