Mercurial > libavformat.hg
comparison mmst.c @ 6294:43d0fb52419d libavformat
Allow the ASF header to be transferred split over multiple packets, as some
servers happen to do. For this, we also move several header-size-related
variables to the MMSTContext.
Patch by Zhentan Feng <spyfeng gmail com>.
author | rbultje |
---|---|
date | Tue, 20 Jul 2010 15:14:15 +0000 |
parents | 130d730d1c5e |
children | 270f6c8aeac5 |
comparison
equal
deleted
inserted
replaced
6293:130d730d1c5e | 6294:43d0fb52419d |
---|---|
118 /*@{*/ | 118 /*@{*/ |
119 uint8_t *asf_header; ///< Stored ASF header. | 119 uint8_t *asf_header; ///< Stored ASF header. |
120 int asf_header_size; ///< Size of stored ASF header. | 120 int asf_header_size; ///< Size of stored ASF header. |
121 int header_parsed; ///< The header has been received and parsed. | 121 int header_parsed; ///< The header has been received and parsed. |
122 int asf_packet_len; | 122 int asf_packet_len; |
123 int asf_header_read_size; | |
123 /*@}*/ | 124 /*@}*/ |
124 | 125 |
125 int stream_num; ///< stream numbers. | 126 int stream_num; ///< stream numbers. |
126 int is_playing; | 127 int is_playing; |
127 } MMSContext; | 128 } MMSContext; |
299 } | 300 } |
300 } else { | 301 } else { |
301 int length_remaining; | 302 int length_remaining; |
302 int packet_id_type; | 303 int packet_id_type; |
303 int tmp; | 304 int tmp; |
304 | |
305 assert(mms->remaining_in_len==0); | |
306 | 305 |
307 // note we cache the first 8 bytes, | 306 // note we cache the first 8 bytes, |
308 // then fill up the buffer with the others | 307 // then fill up the buffer with the others |
309 tmp = AV_RL16(mms->in_buffer + 6); | 308 tmp = AV_RL16(mms->in_buffer + 6); |
310 length_remaining = (tmp - 8) & 0xffff; | 309 length_remaining = (tmp - 8) & 0xffff; |
342 memcpy(mms->asf_header + mms->asf_header_size, | 341 memcpy(mms->asf_header + mms->asf_header_size, |
343 mms->read_in_ptr, | 342 mms->read_in_ptr, |
344 mms->remaining_in_len); | 343 mms->remaining_in_len); |
345 mms->asf_header_size += mms->remaining_in_len; | 344 mms->asf_header_size += mms->remaining_in_len; |
346 } | 345 } |
346 // 0x04 means asf header is sent in multiple packets. | |
347 if (mms->incoming_flags == 0x04) | |
348 continue; | |
347 } else if(packet_id_type == mms->packet_id) { | 349 } else if(packet_id_type == mms->packet_id) { |
348 packet_type = SC_PKT_ASF_MEDIA; | 350 packet_type = SC_PKT_ASF_MEDIA; |
349 } else { | 351 } else { |
350 dprintf(NULL, "packet id type %d is old.", packet_id_type); | 352 dprintf(NULL, "packet id type %d is old.", packet_id_type); |
351 continue; | 353 continue; |
438 | 440 |
439 static int asf_header_parser(MMSContext *mms) | 441 static int asf_header_parser(MMSContext *mms) |
440 { | 442 { |
441 uint8_t *p = mms->asf_header; | 443 uint8_t *p = mms->asf_header; |
442 uint8_t *end; | 444 uint8_t *end; |
443 int flags, stream_id, real_header_size; | 445 int flags, stream_id; |
444 mms->stream_num = 0; | 446 mms->stream_num = 0; |
445 | 447 |
446 if (mms->asf_header_size < sizeof(ff_asf_guid) * 2 + 22 || | 448 if (mms->asf_header_size < sizeof(ff_asf_guid) * 2 + 22 || |
447 memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) | 449 memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) |
448 return -1; | 450 return -1; |
449 | 451 |
450 real_header_size = AV_RL64(p + sizeof(ff_asf_guid)); | 452 end = mms->asf_header + mms->asf_header_size; |
451 end = mms->asf_header + real_header_size; | |
452 | 453 |
453 p += sizeof(ff_asf_guid) + 14; | 454 p += sizeof(ff_asf_guid) + 14; |
454 while(end - p >= sizeof(ff_asf_guid) + 8) { | 455 while(end - p >= sizeof(ff_asf_guid) + 8) { |
455 uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid)); | 456 uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid)); |
456 if (!chunksize || chunksize > end - p) { | 457 if (!chunksize || chunksize > end - p) { |
517 } | 518 } |
518 | 519 |
519 /** Read at most one media packet (or a whole header). */ | 520 /** Read at most one media packet (or a whole header). */ |
520 static int read_mms_packet(MMSContext *mms, uint8_t *buf, int buf_size) | 521 static int read_mms_packet(MMSContext *mms, uint8_t *buf, int buf_size) |
521 { | 522 { |
522 int result = 0, read_header_size = 0; | 523 int result = 0; |
523 int size_to_copy; | 524 int size_to_copy; |
524 | 525 |
525 do { | 526 do { |
526 if(read_header_size < mms->asf_header_size && !mms->is_playing) { | 527 if(mms->asf_header_read_size < mms->asf_header_size && !mms->is_playing) { |
527 /* Read from ASF header buffer */ | 528 /* Read from ASF header buffer */ |
528 size_to_copy= FFMIN(buf_size, | 529 size_to_copy= FFMIN(buf_size, |
529 mms->asf_header_size - read_header_size); | 530 mms->asf_header_size - mms->asf_header_read_size); |
530 memcpy(buf, mms->asf_header + read_header_size, size_to_copy); | 531 memcpy(buf, mms->asf_header + mms->asf_header_read_size, size_to_copy); |
531 read_header_size += size_to_copy; | 532 mms->asf_header_read_size += size_to_copy; |
532 result += size_to_copy; | 533 result += size_to_copy; |
533 dprintf(NULL, "Copied %d bytes from stored header. left: %d\n", | 534 dprintf(NULL, "Copied %d bytes from stored header. left: %d\n", |
534 size_to_copy, mms->asf_header_size - read_header_size); | 535 size_to_copy, mms->asf_header_size - mms->asf_header_read_size); |
535 if (mms->asf_header_size == read_header_size) { | 536 if (mms->asf_header_size == mms->asf_header_read_size) { |
536 av_freep(&mms->asf_header); | 537 av_freep(&mms->asf_header); |
537 mms->is_playing = 1; | 538 mms->is_playing = 1; |
538 } | 539 } |
539 } else if(mms->remaining_in_len) { | 540 } else if(mms->remaining_in_len) { |
540 /* Read remaining packet data to buffer. | 541 /* Read remaining packet data to buffer. |