[FFmpeg-soc] [soc]: r5851 - mms/mmst.c

spyfeng subversion at mplayerhq.hu
Thu Jul 8 18:08:56 CEST 2010


Author: spyfeng
Date: Thu Jul  8 18:08:56 2010
New Revision: 5851

Log:
fix a bug according link:
1)mmst://194.116.83.15/70s
2)mmst://61.139.126.90/mtv (not stable, sometimes failed.)
Because the server sends back header in multiple packets with incoming flag 0x04.
further we need parser the asf_stream_bitrate_properties guid.

Modified:
   mms/mmst.c

Modified: mms/mmst.c
==============================================================================
--- mms/mmst.c	Thu Jul  8 16:57:11 2010	(r5850)
+++ mms/mmst.c	Thu Jul  8 18:08:56 2010	(r5851)
@@ -26,9 +26,11 @@
 #include "libavcodec/bytestream.h"
 #include "network.h"
 #include "asf.h"
+#include <unistd.h>
 
 #define LOCAL_ADDRESS 0xc0a80081    // FIXME get and use correct local ip address.
 #define LOCAL_PORT    1037          // as above.
+#define RETRY_TIMES   10
 /** Client to server packet types. */
 typedef enum {
     CS_PKT_INITIAL                  = 0x01,
@@ -77,6 +79,7 @@ typedef enum {
 
 typedef struct {
     int id;
+    int rate;
 }MMSStream;
 
 typedef struct {
@@ -112,6 +115,7 @@ typedef struct {
     int asf_header_size;                 ///< Size of stored ASF header.
     int header_parsed;                   ///< The header has been received and parsed.
     int asf_packet_len;
+    int asf_header_read_size;
     /*@}*/
 
     int stream_num;                      ///< stream numbers.
@@ -179,6 +183,13 @@ static void mms_put_utf16(MMSContext *mm
     mms->write_out_ptr += len;
 }
 
+static int send_time_test_data(MMSContext *mms)
+{
+    start_command_packet(mms, CS_PKT_TIMING_DATA_REQUEST);
+    insert_command_prefixes(mms, 0xf0f0f0f1, 0x0004000b);
+    return send_command_packet(mms);
+}
+
 static int send_protocol_select(MMSContext *mms)
 {
     char data_string[256];
@@ -197,6 +208,7 @@ static int send_protocol_select(MMSConte
             LOCAL_PORT);
 
     mms_put_utf16(mms, data_string);
+    bytestream_put_le16(&mms->write_out_ptr, 0);
     return send_command_packet(mms);
 }
 
@@ -279,8 +291,6 @@ static MMSSCPacketType get_tcp_server_re
                 int packet_id_type;
                 int tmp;
 
-                assert(mms->remaining_in_len==0);
-
                 // note we cache the first 8 bytes,
                 // then fill up the buffer with the others
                 tmp                       = AV_RL16(mms->in_buffer + 6);
@@ -321,6 +331,8 @@ static MMSSCPacketType get_tcp_server_re
                                                  mms->remaining_in_len);
                             mms->asf_header_size += mms->remaining_in_len;
                         }
+                        if (mms->incoming_flags == 0x04)
+                            continue;
                     } else if(packet_id_type == mms->packet_id) {
                         packet_type = SC_PKT_ASF_MEDIA;
                     } else {
@@ -358,6 +370,7 @@ static int mms_safe_send_recv(MMSContext
                               const MMSSCPacketType expect_type)
 {
     MMSSCPacketType type;
+    int i;
     if(send_fun) {
         int ret = send_fun(mms);
         if (ret < 0) {
@@ -365,13 +378,16 @@ static int mms_safe_send_recv(MMSContext
             return ret;
         }
     }
-
+    for (i = 0; i < RETRY_TIMES; i++) {
     if ((type = get_tcp_server_response(mms)) != expect_type) {
         dprintf(NULL,"Unexpected packet type %d with type %d\n", type, expect_type);
-        return -1;
+        //return -1;
+        usleep(50000);
     } else {
         return 0;
     }
+    }
+    return -1;
 }
 
 static int send_media_header_request(MMSContext *mms)
@@ -417,22 +433,21 @@ static int asf_header_parser(MMSContext 
 {
     uint8_t *p = mms->asf_header;
     uint8_t *end;
-    int flags, stream_id, real_header_size;
+    int flags, stream_id, is_stream_num_known = 0;
     mms->stream_num = 0;
 
     if (mms->asf_header_size < sizeof(ff_asf_guid) * 2 + 22 ||
         memcmp(p, ff_asf_header, sizeof(ff_asf_guid)))
         return -1;
 
-    real_header_size = AV_RL64(p + sizeof(ff_asf_guid));
-    end = mms->asf_header + real_header_size;
+    end = mms->asf_header + mms->asf_header_size;
 
     p += sizeof(ff_asf_guid) + 14;
     while(end - p >= sizeof(ff_asf_guid) + 8) {
         uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid));
         if (!chunksize || chunksize > end - p) {
-            dprintf(NULL, "chunksize is exceptional value:%d!\n", chunksize);
-            return -1;
+            dprintf(NULL, "chunksize is exceptional value:%"PRId64"!\n", chunksize);
+            return 0;
         }
         if (!memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) {
             /* read packet size */
@@ -453,11 +468,38 @@ static int asf_header_parser(MMSContext 
             if (mms->stream_num < MAX_STREAMS &&
                     46 + mms->stream_num * 6 < sizeof(mms->out_buffer)) {
                 mms->streams[mms->stream_num].id = stream_id;
-                mms->stream_num++;
+                if (!is_stream_num_known)
+                    mms->stream_num++;
             } else {
-                dprintf(NULL,"Too many streams.\n");
+                dprintf(NULL, "Too many streams.\n");
                 return -1;
             }
+        } else if (!memcmp(p, ff_asf_head1_guid, sizeof(ff_asf_guid))) {
+            chunksize = 46;
+        } else if (!memcmp(p, ff_asf_stream_bitrate_properties, sizeof(ff_asf_guid))) {
+            int record_cnt = AV_RL16(p + sizeof(ff_asf_guid) + 8);
+            uint8_t *pos;
+            if (record_cnt*6 + 16 + 8 + 2 > chunksize) {
+                dprintf(NULL, "Too many stream record count.\n");
+                return -1;
+            }
+            if (mms->stream_num < MAX_STREAMS &&
+                  46 + mms->stream_num * 6 < sizeof(mms->out_buffer)) {
+                mms->stream_num = record_cnt;
+                is_stream_num_known = 1;
+            } else {
+                dprintf(NULL, "Too many streams(bitrate properties)\n");
+                return -1;
+            }
+            pos = p + 24 + 2;
+            while(record_cnt > 0) {
+                flags = AV_RL16(pos);
+                pos += 2;
+                stream_id = flags & 0x7F;
+                mms->streams[stream_id].rate = AV_RL32(pos);
+                pos += 4;
+                record_cnt--;
+            }
         }
         p += chunksize;
     }
@@ -497,20 +539,20 @@ static int read_data(MMSContext *mms, ui
 /** Read at most one media packet (or a whole header). */
 static int read_mms_packet(MMSContext *mms, uint8_t *buf, int buf_size)
 {
-    int result = 0, read_header_size = 0;
+    int result = 0;
     int size_to_copy;
 
     do {
-        if(read_header_size < mms->asf_header_size && !mms->is_playing) {
+        if(mms->asf_header_read_size < mms->asf_header_size && !mms->is_playing) {
             /* Read from ASF header buffer */
             size_to_copy= FFMIN(buf_size,
-                                mms->asf_header_size - read_header_size);
-            memcpy(buf, mms->asf_header + read_header_size, size_to_copy);
-            read_header_size += size_to_copy;
+                                mms->asf_header_size - mms->asf_header_read_size);
+            memcpy(buf, mms->asf_header + mms->asf_header_read_size, size_to_copy);
+            mms->asf_header_read_size += size_to_copy;
             result += size_to_copy;
             dprintf(NULL, "Copied %d bytes from stored header. left: %d\n",
-                   size_to_copy, mms->asf_header_size - read_header_size);
-            if (mms->asf_header_size == read_header_size) {
+                   size_to_copy, mms->asf_header_size - mms->asf_header_read_size);
+            if (mms->asf_header_size == mms->asf_header_read_size) {
                 av_freep(&mms->asf_header);
                 mms->is_playing = 1;
             }
@@ -581,7 +623,7 @@ static int mms_open(URLContext *h, const
         return AVERROR(ENOMEM);
 
     // only for MMS over TCP, so set proto = NULL
-    ff_url_split(NULL, 0, NULL, 0,
+    av_url_split(NULL, 0, NULL, 0,
             mms->host, sizeof(mms->host), &port, mms->path,
             sizeof(mms->path), uri);
 
@@ -599,6 +641,9 @@ static int mms_open(URLContext *h, const
     err = mms_safe_send_recv(mms, send_startup_packet, SC_PKT_CLIENT_ACCEPTED);
     if (err)
         goto fail;
+    err = mms_safe_send_recv(mms, send_time_test_data, SC_PKT_TIMING_TEST_REPLY);
+    if (err)
+        goto fail;
     err = mms_safe_send_recv(mms, send_protocol_select, SC_PKT_PROTOCOL_ACCEPTED);
     if (err)
         goto fail;


More information about the FFmpeg-soc mailing list