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.