[FFmpeg-soc] [soc]: r5829 - mms/mmsh.c

spyfeng subversion at mplayerhq.hu
Thu Jun 10 19:34:02 CEST 2010


Author: spyfeng
Date: Thu Jun 10 19:34:01 2010
New Revision: 5829

Log:
make the code compile successfully.
TODO in soon:
1,complete handle_chunk_type() function(may use mmsh_open_cnx()).
2,test the code with mms links.

Modified:
   mms/mmsh.c

Modified: mms/mmsh.c
==============================================================================
--- mms/mmsh.c	Thu Jun 10 00:03:13 2010	(r5828)
+++ mms/mmsh.c	Thu Jun 10 19:34:01 2010	(r5829)
@@ -19,10 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
+#include "internal.h"
+#include "libavutil/intreadwrite.h"
 #include <string.h>
 
 #define CHUNK_TYPE_DATA        0x4424
 #define CHUNK_TYPE_ASF_HEADER  0x4824
+#define CHUNK_TYPE_END         0x4524
 
 #define USERAGENT "User-Agent: NSPlayer/4.1.0.3856\r\n"
 #define CLIENTGUID "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}\r\n"
@@ -65,17 +68,21 @@ typedef struct
     URLContext *mms_hd;
     uint8_t out_buffer[1024];             ///< Buffer for outgoing packet.
     uint8_t in_buffer[1024]; //TODO, maybe reused by out_buffer.
+    uint8_t *read_in_ptr;
+
     uint8_t *asf_header_pos;
     uint8_t *http_header_data;
     int content_length;
     int asf_header_len;
-    int asf_header_remaining_len;
+    int asf_header_read_size;
     int asf_data_remaining_len;
 
     char path[256];
     char host[128];
     int seekable;
     int stream_num;
+    int request_seq;
+    int chunk_seq;
 
     char stream_selection[10 * MAX_STREAMS];
 }MMSHContext;
@@ -95,7 +102,7 @@ static int send_pack(MMSHContext *mms)
 {
     int len, result;
     len = strlen(mms->out_buffer);
-    result = url_write(mms->mms_hd, mms->out_buffer, len)
+    result = url_write(mms->mms_hd, mms->out_buffer, len);
     if(result != len) {
         dprintf(NULL,"send pack failed!return len %d != %d\n", result, len);
         return AVERROR_IO;
@@ -107,7 +114,7 @@ static char* find_str(char * dst, const 
 {
     char *p = NULL;
     if(strncasecmp(dst, str, len) == 0) {
-        p=dst[len];
+        p = &dst[len];
         while(isspace(*p))
             p++;
     }
@@ -121,7 +128,7 @@ static int get_and_parse_http_header(MMS
     char content_type[128]={'\0'};
     char *p, *pos;
     for(;;) {
-        if(url_read(mms->mms_hd, mms->in_buffer[len], 1) != 1) {
+        if(url_read(mms->mms_hd, &mms->in_buffer[len], 1) != 1) {
             dprintf(NULL, "recv http header failed!\n");
             return AVERROR(EIO);
         }
@@ -164,8 +171,8 @@ static int get_and_parse_http_header(MMS
                         return -1;
                     }
                 } else if((p = find_str(mms->in_buffer, "Content-Length:", 15)) != NULL) {
-                    mms->content_length = atoi(*p);
-                } else if(p = find_str(mms->in_buffer, "Pragma:", 7) != NULL) {
+                    mms->content_length = atoi(p);
+                } else if((p = find_str(mms->in_buffer, "Pragma:", 7)) != NULL) {
                     pos = strstr(p, "features=");
                     if (pos){
                         if(strstr(pos, "seekable")) {
@@ -193,9 +200,11 @@ static uint16_t http_header_data_parser(
         chunk_type = AV_RL16(pos);
         chunk_len = AV_RL16(pos + 2);
         if(chunk_type == CHUNK_TYPE_ASF_HEADER) {
-            mms->asf_header_pos = pos + 4; // start from $H, ox4824
-            mms->asf_header_len = chunk_len;
+            mms->asf_header_pos = pos + 12; // start from asf header data
+            mms->asf_header_len = chunk_len - 8;
         }
+        if (chunk_type == CHUNK_TYPE_ASF_HEADER || chunk_type == CHUNK_TYPE_DATA)
+            mms->chunk_seq = AV_RL32(pos + 4);
         data_len -= chunk_len + 4;
         pos += chunk_len + 4;
         if (data_len <= 0) {
@@ -211,7 +220,7 @@ static uint16_t http_header_data_parser(
 
 static int get_http_header_data(MMSHContext *mms, const int flag)
 {
-    int res, len;
+    int res;
     if(mms->content_length && flag == 1) {
         mms->http_header_data = av_mallocz(mms->content_length);
         if (!mms->http_header_data)
@@ -273,6 +282,15 @@ static int get_http_answer(MMSHContext *
     return 0;
 }
 
+static int mmsh_open_cnx(URLContext *h)
+{
+    MMSHContext *mms = h->priv_data;
+    if (mms->mms_hd) {
+        url_close(mms->mms_hd);
+    }
+    return 0;
+}
+
 static int mmsh_open(URLContext *h, const char *uri, int flags)
 {
     MMSHContext *mms;
@@ -296,7 +314,7 @@ static int mmsh_open(URLContext *h, cons
         goto fail;
     // send describe request
     snprintf (mms->out_buffer, sizeof(mms->out_buffer), mmsh_first_request, mms->path,
-            mms->host, port, this->http_request_number++);
+            mms->host, port, mms->request_seq++);
     err = send_pack(mms);
     if (err)
         goto fail;
@@ -307,10 +325,10 @@ static int mmsh_open(URLContext *h, cons
     // send paly request
     if (mms->seekable) {
         snprintf(mms->out_buffer, sizeof(mms->out_buffer), mmsh_seekable_request, mms->path,
-            mms->host, port, 0, 0, 0, this->http_request_number++, 0, mms->stream_num, mms->stream_selection);
+            mms->host, port, 0, 0, 0, mms->request_seq++, 0, mms->stream_num, mms->stream_selection);
     } else {
-        snprintf(mms->out_buffer, sizeof(mms->out_buffer),, mmsh_live_request, mms->path,
-            mms->host, port, this->http_request_number++, mms->stream_num, mms->stream_selection);
+        snprintf(mms->out_buffer, sizeof(mms->out_buffer), mmsh_live_request, mms->path,
+            mms->host, port, mms->request_seq++, mms->stream_num, mms->stream_selection);
     }
     err = send_pack(mms);
     if (err)
@@ -327,37 +345,85 @@ fail:
 
 static int read_data(MMSHContext *mms, char *buf, int size)
 {
+    int read_size;
+    read_size = FFMIN(size, mms->asf_data_remaining_len);
+    memcpy(buf, mms->read_in_ptr, read_size);
+    mms->asf_data_remaining_len -= read_size;
+    mms->read_in_ptr      += read_size;
+    return read_size;
 }
 
-static int read_data_packet(MMSHContext *mms)
+static int handle_chunk_type(MMSHContext *mms)
 {
+    uint16_t chunk_type;
+    int chunk_len, res;
+    res = url_read(mms->mms_hd, mms->in_buffer, 4);
+    if (res != 4) { // TODO extact common log code as macro define
+        dprintf(NULL, "read data packet  header failed!\n");
+        return AVERROR(EIO);
+    }
+    chunk_type = AV_RL16(mms->in_buffer);
+    chunk_len = AV_RL16(mms->in_buffer + 2);
+    if (chunk_type == CHUNK_TYPE_END) {
+        //TODO
+    } else if (chunk_type == CHUNK_TYPE_ASF_HEADER) {
+        //TODO
+    } else if (chunk_type == CHUNK_TYPE_DATA){
+        //TODO
+    }
+    return 0;
 }
 
 static int mmsh_read(URLContext *h, uint8_t *buf, int size)
 {
-    int size_to_copy;
+    int res = 0;
     MMSHContext *mms = h->priv_data;
 
-    if (mms->asf_header_remaining_len != 0) {
+    if (mms->asf_header_read_size < mms->asf_header_len) {
         // copy asf header into buffer
         char *pos;
-        size_to_copy = FFMIN(size, mms->asf_header_remaining_len);
-        pos = mms->asf_header_pos + (mms->asf_header_len - mms->asf_header_remaining_len);
+        int size_to_copy;
+        int remaining_size = mms->asf_header_len - mms->asf_header_read_size;
+        size_to_copy = FFMIN(size, remaining_size);
+        pos = mms->asf_header_pos + mms->asf_header_read_size;
         memcpy(buf, pos, size_to_copy);
-        mms->asf_header_remaining_len -= size_to_copy;
-        if (mms->asf_header_remaining_len == 0) {
+        mms->asf_header_read_size += size_to_copy;
+        if (mms->asf_header_read_size == mms->asf_header_len) {
             av_freep(&mms->http_header_data); // which contains asf header
         }
     } else if (mms->asf_data_remaining_len){
-        read_data(mms, buf, size);
+        res =read_data(mms, buf, size);
     } else {
         // read data packet from network
-        read_data_packet(mms);
+            int len;
+            len = handle_chunk_type(mms);
+            if (len > 0) {
+                res = url_read_complete(mms->mms_hd, mms->in_buffer + 4, len);
+                if (res != len) {
+                    dprintf(NULL, "read data packet failed!\n");
+                    return AVERROR(EIO);
+                }
+                mms->read_in_ptr = mms->in_buffer;
+                mms->asf_data_remaining_len = len + 4;
+                res = read_data(mms, buf, size);
+            } else {
+                dprintf(NULL, "other situation!\n");
+            }
     }
+    return res;
 }
 
+URLProtocol mms_protocol = {
+    "mms",
+    mmsh_open,
+    mmsh_read,
+    NULL, // write
+    NULL, // seek
+    mmsh_close,
+};
+
 URLProtocol mmsh_protocol = {
-    "mmsh, mms",
+    "mmsh",
     mmsh_open,
     mmsh_read,
     NULL, // write


More information about the FFmpeg-soc mailing list