[FFmpeg-soc] [soc]: r5892 - mms/mmsh.c
spyfeng
subversion at mplayerhq.hu
Thu Aug 12 17:08:58 CEST 2010
Author: spyfeng
Date: Thu Aug 12 17:08:57 2010
New Revision: 5892
Log:
update the mmsh.c to the version submitted in ffmpeg-dev list.
Modified:
mms/mmsh.c
Modified: mms/mmsh.c
==============================================================================
--- mms/mmsh.c Thu Aug 12 11:19:10 2010 (r5891)
+++ mms/mmsh.c Thu Aug 12 17:08:57 2010 (r5892)
@@ -18,6 +18,12 @@
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
+/*
+ * Reference
+ * Windows Media HTTP Streaming Protocol.
+ * http://msdn.microsoft.com/en-us/library/cc251059(PROT.10).aspx
+ */
#include "mms.h"
#include "internal.h"
#include "libavutil/intreadwrite.h"
@@ -27,17 +33,21 @@
#include "http.h"
#define DEBUG
-#define CHUNK_TYPE_DATA 0x4424
-#define CHUNK_TYPE_ASF_HEADER 0x4824
-#define CHUNK_TYPE_END 0x4524
-#define CHUNK_TYPE_STREAM_CHANGE 0x4324
+#define CHUNK_TYPE_DATA 0x4424
+#define CHUNK_TYPE_ASF_HEADER 0x4824
+#define CHUNK_TYPE_END 0x4524
+#define CHUNK_TYPE_STREAM_CHANGE 0x4324
-#define CHUNK_HEADER_LENGTH 4
-#define EXT_HEADER_LENGTH 8
+#define CHUNK_HEADER_LENGTH 4 // 2bytes chunk type and 2bytes chunk length.
+#define EXT_HEADER_LENGTH 8 // 4bytes seqence, 2bytes usless and 2bytes chunk length.
-#define USERAGENT "User-Agent: NSPlayer/4.1.0.3856\r\n"
+// see Ref 2.2.1.8
+#define USERAGENT "User-Agent: NSPlayer/4.1.0.3856\r\n"
+// see Ref 2.2.1.4.33
+// the guid value can be changed to any valid value.
#define CLIENTGUID "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}\r\n"
+// mmsh request messages.
static const char* mmsh_first_request =
"Accept: */*\r\n"
USERAGENT
@@ -70,7 +80,7 @@ static const char* mmsh_live_request =
typedef struct
{
- MMSContext *ff_ctx;
+ MMSContext mms;
char location[1024];
int seekable;
int stream_num;
@@ -80,26 +90,25 @@ typedef struct
static int mmsh_close(URLContext *h)
{
- MMSHContext *mmsh_ctx = (MMSHContext *)h->priv_data;
- MMSContext *mms = mmsh_ctx->ff_ctx;
+ MMSHContext *mmsh = (MMSHContext *)h->priv_data;
+ MMSContext *mms = &mmsh->mms;
if(mms->mms_hd)
url_close(mms->mms_hd);
av_freep(&mms->asf_header);
- av_freep(&mms);
av_freep(&h->priv_data);
return 0;
}
-static int get_chunk_header(MMSHContext *mmsh_ctx, int *len)
+static int get_chunk_header(MMSHContext *mmsh, int *len)
{
- MMSContext *mms = mmsh_ctx->ff_ctx;
+ MMSContext *mms = &mmsh->mms;
uint8_t chunk_header[CHUNK_HEADER_LENGTH];
uint8_t ext_header[EXT_HEADER_LENGTH];
int chunk_type;
int chunk_len, res, ext_header_len = 0;
res = url_read(mms->mms_hd, chunk_header, CHUNK_HEADER_LENGTH);
- if (res != CHUNK_HEADER_LENGTH) { // TODO extact common log code as macro define
+ if (res != CHUNK_HEADER_LENGTH) {
dprintf(NULL, "read data packet header failed!\n");
return AVERROR(EIO);
}
@@ -122,13 +131,13 @@ static int get_chunk_header(MMSHContext
}
*len = chunk_len - ext_header_len;
if (chunk_type == CHUNK_TYPE_END || chunk_type == CHUNK_TYPE_DATA)
- mmsh_ctx->chunk_seq = AV_RL32(ext_header);
+ mmsh->chunk_seq = AV_RL32(ext_header);
return chunk_type;
}
-static int read_data_packet(MMSHContext *mmsh_ctx, const int len)
+static int read_data_packet(MMSHContext *mmsh, const int len)
{
- MMSContext *mms = mmsh_ctx->ff_ctx;
+ MMSContext *mms = &mmsh->mms;
int res, pad_size = 0;
res = url_read_complete(mms->mms_hd, mms->in_buffer, len);
dprintf(NULL, "data packet len = %d\n", len);
@@ -148,15 +157,15 @@ static int read_data_packet(MMSHContext
return 0;
}
-static int get_http_header_data(MMSHContext *mmsh_ctx)
+static int get_http_header_data(MMSHContext *mmsh)
{
- MMSContext *mms = mmsh_ctx->ff_ctx;
+ MMSContext *mms = &mmsh->mms;
int res, len;
int chunk_type;
for (;;) {
len = 0;
- chunk_type = get_chunk_header(mmsh_ctx, &len);
+ chunk_type = get_chunk_header(mmsh, &len);
if (chunk_type < 0) {
return chunk_type;
} else if (chunk_type == CHUNK_TYPE_ASF_HEADER){
@@ -188,7 +197,7 @@ static int get_http_header_data(MMSHCont
}
} else if (chunk_type == CHUNK_TYPE_DATA) {
// read data packet and do padding
- return read_data_packet(mmsh_ctx, len);
+ return read_data_packet(mmsh, len);
break;
} else {
if (len) {
@@ -206,9 +215,9 @@ static int get_http_header_data(MMSHCont
return 0;
}
-static int mmsh_open_cnx(MMSHContext *mmsh_ctx)
+static int mmsh_open_cnx(MMSHContext *mmsh)
{
- MMSContext *mms = mmsh_ctx->ff_ctx;
+ MMSContext *mms = &mmsh->mms;
int i, port, err, offset = 0;
char httpname[256], path[256], host[128];
char stream_selection[10 * MAX_STREAMS];
@@ -219,7 +228,7 @@ static int mmsh_open_cnx(MMSHContext *mm
}
ff_url_split(NULL, 0, NULL, 0,
- host, sizeof(host), &port, path, sizeof(path), mmsh_ctx->location);
+ host, sizeof(host), &port, path, sizeof(path), mmsh->location);
if(port<0)
port = 80; // defaut mmsh protocol port
ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, path);
@@ -229,13 +238,13 @@ static int mmsh_open_cnx(MMSHContext *mm
}
snprintf (headers, sizeof(headers), mmsh_first_request,
- host, port, mmsh_ctx->request_seq++);
+ host, port, mmsh->request_seq++);
ff_http_set_headers(mms->mms_hd, headers);
if (url_connect(mms->mms_hd)) {
return AVERROR(EIO);
}
- err = get_http_header_data(mmsh_ctx);
+ err = get_http_header_data(mmsh);
if (err) {
dprintf(NULL, "get http header data fialed!\n");
return (err);
@@ -255,12 +264,12 @@ static int mmsh_open_cnx(MMSHContext *mm
offset += err;
}
// send paly request
- if (mmsh_ctx->seekable) {
+ if (mmsh->seekable) {
err = snprintf(headers, sizeof(headers), mmsh_seekable_request,
- host, port, 0, 0, 0, mmsh_ctx->request_seq++, 0, mms->stream_num, stream_selection);
+ host, port, 0, 0, 0, mmsh->request_seq++, 0, mms->stream_num, stream_selection);
} else {
err = snprintf(headers, sizeof(headers), mmsh_live_request,
- host, port, mmsh_ctx->request_seq++, mms->stream_num, stream_selection);
+ host, port, mmsh->request_seq++, mms->stream_num, stream_selection);
}
if (err < 0) {
dprintf(NULL, "build play request failed!\n");
@@ -273,7 +282,7 @@ static int mmsh_open_cnx(MMSHContext *mm
return AVERROR(EIO);
}
- err = get_http_header_data(mmsh_ctx);
+ err = get_http_header_data(mmsh);
if (err) {
dprintf(NULL, "get http header data fialed!\n");
return (err);
@@ -284,19 +293,15 @@ static int mmsh_open_cnx(MMSHContext *mm
static int mmsh_open(URLContext *h, const char *uri, int flags)
{
- MMSHContext *mmsh_ctx;
- MMSContext *mms;
+ MMSHContext *mmsh;
int err;
- mmsh_ctx = h->priv_data = av_mallocz(sizeof(MMSHContext));
+ mmsh = h->priv_data = av_mallocz(sizeof(MMSHContext));
if (!h->priv_data)
return AVERROR(ENOMEM);
- mms = mmsh_ctx->ff_ctx = av_mallocz(sizeof(MMSContext));
- if (!mmsh_ctx->ff_ctx)
- return AVERROR(ENOMEM);
- mmsh_ctx->request_seq = h->is_streamed = 1;
- av_strlcpy(mmsh_ctx->location, uri, sizeof(mmsh_ctx->location));
+ mmsh->request_seq = h->is_streamed = 1;
+ av_strlcpy(mmsh->location, uri, sizeof(mmsh->location));
- err =mmsh_open_cnx(mmsh_ctx);
+ err =mmsh_open_cnx(mmsh);
if (err) {
dprintf(NULL, "Leaving mmsh open (failure: %d)\n", err);
mmsh_close(h);
@@ -306,32 +311,32 @@ static int mmsh_open(URLContext *h, cons
return 0;
}
-static int handle_chunk_type(MMSHContext *mmsh_ctx)
+static int handle_chunk_type(MMSHContext *mmsh)
{
- MMSContext *mms = mmsh_ctx->ff_ctx;
+ MMSContext *mms = &mmsh->mms;
int res, len = 0;
int chunk_type;
- chunk_type = get_chunk_header(mmsh_ctx, &len);
+ chunk_type = get_chunk_header(mmsh, &len);
if(chunk_type == CHUNK_TYPE_END) {
- if (mmsh_ctx->chunk_seq == 0) {
+ if (mmsh->chunk_seq == 0) {
dprintf(NULL, "The stream is end.\n");
return -1;
}
// reconnect
- mmsh_ctx->request_seq = 1;
- if ((res = mmsh_open_cnx(mmsh_ctx)) !=0) {
+ mmsh->request_seq = 1;
+ if ((res = mmsh_open_cnx(mmsh)) !=0) {
dprintf(NULL, "Reconnect failed!\n");
return res;
}
} else if (chunk_type == CHUNK_TYPE_STREAM_CHANGE) {
mms->header_parsed = 0;
- if ((res = get_http_header_data(mmsh_ctx)) !=0) {
+ if ((res = get_http_header_data(mmsh)) !=0) {
dprintf(NULL,"stream changed! get new header failed!\n");
return res;
}
} else if (chunk_type == CHUNK_TYPE_DATA) {
- return read_data_packet(mmsh_ctx, len);
+ return read_data_packet(mmsh, len);
} else {
dprintf(NULL, "recv other type packet %d\n", chunk_type);
return -1;
@@ -342,8 +347,8 @@ static int handle_chunk_type(MMSHContext
static int mmsh_read(URLContext *h, uint8_t *buf, int size)
{
int res = 0;
- MMSHContext *mmsh_ctx = h->priv_data;
- MMSContext *mms = mmsh_ctx->ff_ctx;
+ MMSHContext *mmsh = h->priv_data;
+ MMSContext *mms = &mmsh->mms;
do{
if (mms->asf_header_read_size < mms->asf_header_size) {
// copy asf header into buffer
@@ -352,7 +357,7 @@ static int mmsh_read(URLContext *h, uint
res = ff_mms_read_data(mms, buf, size);
} else {
// read data packet from network
- res = handle_chunk_type(mmsh_ctx);
+ res = handle_chunk_type(mmsh);
if (res == 0) {
res = ff_mms_read_data(mms, buf, size);
} else {
More information about the FFmpeg-soc
mailing list