comparison libmpdemux/demux_asf.c @ 23239:cc01eab9f3a9

For DVR-MS: extract timing information from the payload extension, set key frames, detect video frame boundaries, interpolate the average video frame time using the known informations from past frames and timestamps. Video data before the first video key frame is thrown away. Patch by John Donaghy johnfdonaghy gmail com
author nicodvb
date Mon, 07 May 2007 21:58:42 +0000
parents 4d81dbdf46b9
children ab885f928444
comparison
equal deleted inserted replaced
23238:dc442598a7d8 23239:cc01eab9f3a9
64 //if(i<len) memcpy(dst+i,src+i,len-i); 64 //if(i<len) memcpy(dst+i,src+i,len-i);
65 free(*src); 65 free(*src);
66 *src = dst; 66 *src = dst;
67 } 67 }
68 68
69 /*****************************************************************
70 * \brief initializes asf private data
71 *
72 */
73 static void init_priv (struct asf_priv* asf){
74 asf->last_vid_seq=-1;
75 asf->vid_ext_timing_index=-1;
76 asf->aud_ext_timing_index=-1;
77 asf->vid_ext_frame_index=-1;
78 }
79
69 #ifdef USE_LIBAVCODEC_SO 80 #ifdef USE_LIBAVCODEC_SO
70 #include <ffmpeg/avcodec.h> 81 #include <ffmpeg/avcodec.h>
71 #elif defined(USE_LIBAVCODEC) 82 #elif defined(USE_LIBAVCODEC)
72 #include "libavcodec/avcodec.h" 83 #include "libavcodec/avcodec.h"
73 #else 84 #else
147 memset(dp->buffer+dp->len+len, 0, FF_INPUT_BUFFER_PADDING_SIZE); 158 memset(dp->buffer+dp->len+len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
148 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len); 159 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len);
149 dp->len+=len; 160 dp->len+=len;
150 } 161 }
151 162
152 static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,int id,int seq,unsigned long time,unsigned short dur,int offs,int keyframe){ 163 static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,int id,int seq,uint64_t time,unsigned short dur,int offs,int keyframe){
153 struct asf_priv* asf = demux->priv; 164 struct asf_priv* asf = demux->priv;
154 demux_stream_t *ds=NULL; 165 demux_stream_t *ds=NULL;
155 int close_seg=0; 166 int close_seg=0;
156 int frame_end_pos=END_NOT_FOUND;
157 167
158 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"demux_asf.read_packet: id=%d seq=%d len=%d\n",id,seq,len); 168 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"demux_asf.read_packet: id=%d seq=%d len=%d\n",id,seq,len);
159 169
160 if(demux->video->id==-1) 170 if(demux->video->id==-1)
161 if(demux->v_streams[id]) 171 if(demux->v_streams[id])
185 if(ds){ 195 if(ds){
186 if(ds->asf_packet){ 196 if(ds->asf_packet){
187 demux_packet_t* dp=ds->asf_packet; 197 demux_packet_t* dp=ds->asf_packet;
188 198
189 if (ds==demux->video && asf->asf_is_dvr_ms) { 199 if (ds==demux->video && asf->asf_is_dvr_ms) {
190 frame_end_pos=mpeg1_find_frame_end(demux, data, len); 200 if (asf->new_vid_frame_seg) {
191
192 if (frame_end_pos != END_NOT_FOUND) {
193 dp->pos=demux->filepos; 201 dp->pos=demux->filepos;
194 if (frame_end_pos > 0) {
195 demux_asf_append_to_packet(dp,data,frame_end_pos,offs);
196 data += frame_end_pos;
197 len -= frame_end_pos;
198 }
199 close_seg = 1; 202 close_seg = 1;
200 if (asf->avg_vid_frame_time > 0.0 ) {
201 // correct the pts for the packet
202 // because dvr-ms files do not contain accurate
203 // pts values but we can deduce them using
204 // the average frame time
205 if (asf->dvr_last_vid_pts > 0.0)
206 dp->pts=asf->dvr_last_vid_pts+asf->avg_vid_frame_time;
207 asf->dvr_last_vid_pts = dp->pts;
208 }
209 } else seq = ds->asf_seq; 203 } else seq = ds->asf_seq;
210 } else close_seg = ds->asf_seq!=seq; 204 } else close_seg = ds->asf_seq!=seq;
211 205
212 if(close_seg){ 206 if(close_seg){
213 // closed segment, finalize packet: 207 // closed segment, finalize packet:
229 mp_msg(MSGT_DEMUX,MSGL_V,"warning! broken fragment, %d bytes missing \n",offs); 223 mp_msg(MSGT_DEMUX,MSGL_V,"warning! broken fragment, %d bytes missing \n",offs);
230 return 0; 224 return 0;
231 } 225 }
232 dp=new_demux_packet(len); 226 dp=new_demux_packet(len);
233 memcpy(dp->buffer,data,len); 227 memcpy(dp->buffer,data,len);
234 dp->pts=time*0.001f; 228 if (asf->asf_is_dvr_ms)
229 dp->pts=time*0.0000001f;
230 else
231 dp->pts=time*0.001f;
235 dp->flags=keyframe; 232 dp->flags=keyframe;
236 // if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur); 233 // if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur);
237 dp->pos=demux->filepos; 234 dp->pos=demux->filepos;
238 ds->asf_packet=dp; 235 ds->asf_packet=dp;
239 ds->asf_seq=seq; 236 ds->asf_seq=seq;
243 } 240 }
244 241
245 return 0; 242 return 0;
246 } 243 }
247 244
245 /*****************************************************************
246 * \brief read the replicated data associated with each segment
247 * \parameter pp reference to replicated data
248 * \parameter id stream number
249 * \parameter seq media object number
250 * \parameter keyframe key frame indicator - set to zero if keyframe, non-zero otherwise
251 * \parameter seg_time set to payload time when valid, if audio or new video frame payload, zero otherwise
252 *
253 */
254 static void get_payload_extension_data(demuxer_t *demux, unsigned char** pp, unsigned char id, unsigned int seq, int *keyframe, uint64_t *seg_time){
255 struct asf_priv* asf = demux->priv;
256 uint64_t payload_time; //100ns units
257 int i, ext_max, ext_timing_index;
258 uint8_t *pi = *pp+4;
259
260 if(demux->video->id==-1)
261 if(demux->v_streams[id])
262 demux->video->id=id;
263
264 if(demux->audio->id==-1)
265 if(demux->a_streams[id])
266 demux->audio->id=id;
267
268 if (id!=demux->video->id && id!=demux->audio->id) return;
269
270 if (id==demux->video->id) {
271 ext_max = asf->vid_repdata_count;
272 ext_timing_index = asf->vid_ext_timing_index;
273 } else {
274 ext_max = asf->aud_repdata_count;
275 ext_timing_index = asf->aud_ext_timing_index;
276 }
277
278 *seg_time=0.0;
279 asf->new_vid_frame_seg = 0;
280
281 for (i=0; i<ext_max; i++) {
282 uint16_t payextsize;
283 uint8_t segment_marker;
284
285 if (id==demux->video->id)
286 payextsize = asf->vid_repdata_sizes[i];
287 else
288 payextsize = asf->aud_repdata_sizes[i];
289
290 if (payextsize == 65535) {
291 payextsize = LOAD_LE16(pi);
292 pi+=2;
293 }
294
295 // if this is the timing info extension then read the payload time
296 if (i == ext_timing_index)
297 payload_time = (uint64_t) LOAD_LE32(pi+8) | (uint64_t)LOAD_LE32(pi+8 + 4) << 32;
298
299 // if this is the video frame info extension then
300 // set the keyframe indicator, the 'new frame segment' indicator
301 // and (initially) the 'frame time'
302 if (i == asf->vid_ext_frame_index && id==demux->video->id) {
303 segment_marker = pi[0];
304 // Known video stream segment_marker values that
305 // contain useful information:
306 //
307 // NTSC/ATSC (29.97fps): 0X4A 01001010
308 // 0X4B 01001011
309 // 0X49 01001001
310 //
311 // PAL/ATSC (25fps): 0X3A 00111010
312 // 0X3B 00111011
313 // 0X39 00111001
314 //
315 // ATSC progressive (29.97fps): 0X7A 01111010
316 // 0X7B 01111011
317 // 0X79 01111001
318 // 11111111
319 // ^ this is new video frame marker
320 //
321 // ^^^^ these bits indicate the framerate
322 // 0X4 is 29.97i, 0X3 is 25i, 0X7 is 29.97p, ???=25p
323 //
324 // ^^^ these bits indicate the frame type:
325 // 001 means I-frame
326 // 010 and 011 probably mean P and B
327
328 asf->new_vid_frame_seg = (0X08 & segment_marker) && seq != asf->last_vid_seq;
329
330 if (asf->new_vid_frame_seg) asf->last_vid_seq = seq;
331
332 if (asf->avg_vid_frame_time == 0) {
333 // set the average frame time initially (in 100ns units).
334 // This is based on what works for known samples.
335 // It can be extended if more samples of different types can be obtained.
336 if (((segment_marker & 0XF0) >> 4) == 4) {
337 asf->avg_vid_frame_time = (uint64_t)((1.001 / 30.0) * 10000000.0);
338 asf->know_frame_time=1;
339 } else if (((segment_marker & 0XF0) >> 4) == 3) {
340 asf->avg_vid_frame_time = (uint64_t)(0.04 * 10000000.0);
341 asf->know_frame_time=1;
342 } else if (((segment_marker & 0XF0) >> 4) == 6) {
343 asf->avg_vid_frame_time = (uint64_t)(0.02 * 10000000.0);
344 asf->know_frame_time=1;
345 } else if (((segment_marker & 0XF0) >> 4) == 7) {
346 asf->avg_vid_frame_time = (uint64_t)((1.001 / 60.0) * 10000000.0);
347 asf->know_frame_time=1;
348 } else {
349 // we dont know the frame time initially so
350 // make a guess and then recalculate as we go.
351 asf->avg_vid_frame_time = (uint64_t)((1.001 / 60.0) * 10000000.0);
352 asf->know_frame_time=0;
353 }
354 }
355 *keyframe = (asf->new_vid_frame_seg && (segment_marker & 0X07) == 1);
356 }
357 pi +=payextsize;
358 }
359
360 if (id==demux->video->id && asf->new_vid_frame_seg) {
361 asf->vid_frame_ct++;
362 // Some samples only have timings on key frames and
363 // the rest contain non-cronological timestamps. Interpolating
364 // the values between key frames works for all samples.
365 if (*keyframe) {
366 asf->found_first_key_frame=1;
367 if (!asf->know_frame_time && asf->last_key_payload_time > 0) {
368 // We dont know average frametime so recalculate.
369 // Giving precedence to the 'weight' of the existing
370 // average limits damage done to new value when there is
371 // a sudden time jump which happens occasionally.
372 asf->avg_vid_frame_time =
373 (0.9 * asf->avg_vid_frame_time) +
374 (0.1 * ((payload_time - asf->last_key_payload_time) / asf->vid_frame_ct));
375 }
376 asf->last_key_payload_time = payload_time;
377 asf->vid_frame_ct = 1;
378 *seg_time = payload_time;
379 } else
380 *seg_time = (asf->last_key_payload_time + (asf->avg_vid_frame_time * (asf->vid_frame_ct-1)));
381 }
382
383 if (id==demux->audio->id) {
384 if (payload_time != -1)
385 asf->last_aud_diff = payload_time - asf->last_aud_pts;
386 asf->last_aud_pts += asf->last_aud_diff;
387 *seg_time = asf->last_aud_pts;
388 }
389 }
248 //static int num_elementary_packets100=0; 390 //static int num_elementary_packets100=0;
249 //static int num_elementary_packets101=0; 391 //static int num_elementary_packets101=0;
250 392
251 // return value: 393 // return value:
252 // 0 = EOF or no stream found 394 // 0 = EOF or no stream found
355 unsigned int seq; 497 unsigned int seq;
356 unsigned int x; // offset or timestamp 498 unsigned int x; // offset or timestamp
357 unsigned int rlen; 499 unsigned int rlen;
358 // 500 //
359 int len; 501 int len;
360 unsigned int time2=0; 502 uint64_t time2=0;
361 int keyframe=0; 503 int keyframe=0;
362 504
363 if(p>=p_end) { 505 if(p>=p_end) {
364 mp_msg(MSGT_DEMUX,MSGL_V,"Warning! invalid packet 1, aborting parsing...\n"); 506 mp_msg(MSGT_DEMUX,MSGL_V,"Warning! invalid packet 1, aborting parsing...\n");
365 break; 507 break;
409 break; 551 break;
410 default: 552 default:
411 if(rlen>=8){ 553 if(rlen>=8){
412 p+=4; // skip object size 554 p+=4; // skip object size
413 time2=LOAD_LE32(p); // read PTS 555 time2=LOAD_LE32(p); // read PTS
556 if (asf->asf_is_dvr_ms)
557 get_payload_extension_data(demux, &p, streamno, seq, &keyframe, &time2);
414 p+=rlen-4; 558 p+=rlen-4;
415 } else { 559 } else {
416 mp_msg(MSGT_DEMUX,MSGL_V,"unknown segment type (rlen): 0x%02X \n",rlen); 560 mp_msg(MSGT_DEMUX,MSGL_V,"unknown segment type (rlen): 0x%02X \n",rlen);
417 time2=0; // unknown 561 time2=0; // unknown
418 p+=rlen; 562 p+=rlen;
455 } 599 }
456 break; 600 break;
457 default: 601 default:
458 // NO GROUPING: 602 // NO GROUPING:
459 //printf("fragment offset: %d \n",sh->x); 603 //printf("fragment offset: %d \n",sh->x);
460 demux_asf_read_packet(demux,p,len,streamno,seq,time2,duration,x,keyframe); 604 if (!asf->asf_is_dvr_ms || asf->found_first_key_frame)
605 demux_asf_read_packet(demux,p,len,streamno,seq,time2,duration,x,keyframe);
461 p+=len; 606 p+=len;
462 break; 607 break;
463 } 608 }
464 609
465 } // for segs 610 } // for segs
553 sh_audio_t *sh_audio=NULL; 698 sh_audio_t *sh_audio=NULL;
554 sh_video_t *sh_video=NULL; 699 sh_video_t *sh_video=NULL;
555 700
556 //---- ASF header: 701 //---- ASF header:
557 if(!asf) return NULL; 702 if(!asf) return NULL;
703 init_priv(asf);
558 if (!read_asf_header(demuxer,asf)) { 704 if (!read_asf_header(demuxer,asf)) {
559 free(asf); 705 free(asf);
560 return NULL; 706 return NULL;
561 } 707 }
562 stream_reset(demuxer->stream); 708 stream_reset(demuxer->stream);
568 mp_msg(MSGT_DEMUXER,MSGL_WARN,"ASF: " MSGTR_MissingVideoStream); 714 mp_msg(MSGT_DEMUXER,MSGL_WARN,"ASF: " MSGTR_MissingVideoStream);
569 demuxer->video->sh=NULL; 715 demuxer->video->sh=NULL;
570 //printf("ASF: missing video stream!? contact the author, it may be a bug :(\n"); 716 //printf("ASF: missing video stream!? contact the author, it may be a bug :(\n");
571 } else { 717 } else {
572 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video; 718 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
573 //sh_video->fps=1000.0f; sh_video->frametime=0.001f; // 1ms - now set when reading asf header 719 sh_video->fps=1000.0f; sh_video->frametime=0.001f;
574 //sh_video->i_bps=10*asf->packetsize; // FIXME! 720 //sh_video->i_bps=10*asf->packetsize; // FIXME!
575 721
576 if (asf->asf_is_dvr_ms) { 722 if (asf->asf_is_dvr_ms) {
577 sh_video->bih->biWidth = 0; 723 sh_video->bih->biWidth = 0;
578 sh_video->bih->biHeight = 0; 724 sh_video->bih->biHeight = 0;
594 demuxer->seekable=0; 740 demuxer->seekable=0;
595 741
596 return demuxer; 742 return demuxer;
597 } 743 }
598 744
745
746 static void demux_close_asf(demuxer_t *demuxer) {
747 struct asf_priv* asf = demuxer->priv;
748
749 if (!asf) return;
750
751 if (asf->aud_repdata_sizes)
752 free(asf->aud_repdata_sizes);
753
754 if (asf->vid_repdata_sizes)
755 free(asf->vid_repdata_sizes);
756
757 free(asf);
758 }
599 759
600 demuxer_desc_t demuxer_desc_asf = { 760 demuxer_desc_t demuxer_desc_asf = {
601 "ASF demuxer", 761 "ASF demuxer",
602 "asf", 762 "asf",
603 "ASF", 763 "ASF",
606 DEMUXER_TYPE_ASF, 766 DEMUXER_TYPE_ASF,
607 1, // safe autodetect 767 1, // safe autodetect
608 asf_check_header, 768 asf_check_header,
609 demux_asf_fill_buffer, 769 demux_asf_fill_buffer,
610 demux_open_asf, 770 demux_open_asf,
611 NULL, //demux_close_asf, 771 demux_close_asf,
612 demux_seek_asf, 772 demux_seek_asf,
613 demux_asf_control 773 demux_asf_control
614 }; 774 };