[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