Mercurial > libavformat.hg
comparison nsvdec.c @ 1429:b0797563dfa6 libavformat
Fix A/V (de)sync with discontinuous NSV streams,
Patch by Joakim elupus A ecce P se
Original thread:
Subject: [Ffmpeg-devel] [PATCH]: A/V sync on nsv streams.
Date: October 27, 2006 3:18:54 AM CEDT
Actual committed patch:
Date: October 28, 2006 3:23:28 AM CEDT
author | gpoirier |
---|---|
date | Sat, 28 Oct 2006 17:28:04 +0000 |
parents | 3b00fb8ef8e4 |
children | f72de3879e6c |
comparison
equal
deleted
inserted
replaced
1428:7316227e64eb | 1429:b0797563dfa6 |
---|---|
175 AVPacket ahead[2]; /* [v, a] if .data is !NULL there is something */ | 175 AVPacket ahead[2]; /* [v, a] if .data is !NULL there is something */ |
176 /* cached */ | 176 /* cached */ |
177 int64_t duration; | 177 int64_t duration; |
178 uint32_t vtag, atag; | 178 uint32_t vtag, atag; |
179 uint16_t vwidth, vheight; | 179 uint16_t vwidth, vheight; |
180 int16_t avsync; | |
180 //DVDemuxContext* dv_demux; | 181 //DVDemuxContext* dv_demux; |
181 } NSVContext; | 182 } NSVContext; |
182 | 183 |
183 static const CodecTag nsv_codec_video_tags[] = { | 184 static const CodecTag nsv_codec_video_tags[] = { |
184 { CODEC_ID_VP3, MKTAG('V', 'P', '3', ' ') }, | 185 { CODEC_ID_VP3, MKTAG('V', 'P', '3', ' ') }, |
403 ByteIOContext *pb = &s->pb; | 404 ByteIOContext *pb = &s->pb; |
404 uint32_t vtag, atag; | 405 uint32_t vtag, atag; |
405 uint16_t vwidth, vheight; | 406 uint16_t vwidth, vheight; |
406 AVRational framerate; | 407 AVRational framerate; |
407 int i; | 408 int i; |
408 uint16_t unknown; | |
409 AVStream *st; | 409 AVStream *st; |
410 NSVStream *nst; | 410 NSVStream *nst; |
411 PRINT(("%s()\n", __FUNCTION__)); | 411 PRINT(("%s()\n", __FUNCTION__)); |
412 | 412 |
413 vtag = get_le32(pb); | 413 vtag = get_le32(pb); |
418 /* XXX how big must the table be ? */ | 418 /* XXX how big must the table be ? */ |
419 /* seems there is more to that... */ | 419 /* seems there is more to that... */ |
420 PRINT(("NSV NSVs framerate code %2x\n", i)); | 420 PRINT(("NSV NSVs framerate code %2x\n", i)); |
421 if(i&0x80) framerate= nsv_framerate_table[i & 0x7F]; | 421 if(i&0x80) framerate= nsv_framerate_table[i & 0x7F]; |
422 else framerate= (AVRational){i, 1}; | 422 else framerate= (AVRational){i, 1}; |
423 unknown = get_le16(pb); | 423 nsv->avsync = get_le16(pb); |
424 #ifdef DEBUG | 424 #ifdef DEBUG |
425 print_tag("NSV NSVs vtag", vtag, 0); | 425 print_tag("NSV NSVs vtag", vtag, 0); |
426 print_tag("NSV NSVs atag", atag, 0); | 426 print_tag("NSV NSVs atag", atag, 0); |
427 PRINT(("NSV NSVs vsize %dx%d\n", vwidth, vheight)); | 427 PRINT(("NSV NSVs vsize %dx%d\n", vwidth, vheight)); |
428 #endif | 428 #endif |
464 goto fail; | 464 goto fail; |
465 st->priv_data = nst; | 465 st->priv_data = nst; |
466 st->codec->codec_type = CODEC_TYPE_AUDIO; | 466 st->codec->codec_type = CODEC_TYPE_AUDIO; |
467 st->codec->codec_tag = atag; | 467 st->codec->codec_tag = atag; |
468 st->codec->codec_id = codec_get_id(nsv_codec_audio_tags, atag); | 468 st->codec->codec_id = codec_get_id(nsv_codec_audio_tags, atag); |
469 | |
470 st->need_parsing = 1; /* for PCM we will read a chunk later and put correct info */ | |
471 | |
472 /* set timebase to common denominator of ms and framerate */ | |
473 av_set_pts_info(st, 64, 1, framerate.num*1000); | |
469 st->start_time = 0; | 474 st->start_time = 0; |
470 // st->duration = nsv->duration; //FIXME | 475 st->duration = (int64_t)nsv->duration * framerate.num; |
471 | |
472 st->need_parsing = 1; /* for PCM we will read a chunk later and put correct info */ | |
473 /* XXX:FIXME */ | |
474 //st->codec->channels = 2; //XXX:channels; | |
475 //st->codec->sample_rate = 1000; | |
476 //av_set_pts_info(st, 64, 1, st->codec->sample_rate); | |
477 | |
478 #endif | 476 #endif |
479 } | 477 } |
480 #ifdef CHECK_SUBSEQUENT_NSVS | 478 #ifdef CHECK_SUBSEQUENT_NSVS |
481 } else { | 479 } else { |
482 if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) { | 480 if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) { |
596 nst = st[NSV_ST_VIDEO]->priv_data; | 594 nst = st[NSV_ST_VIDEO]->priv_data; |
597 pkt = &nsv->ahead[NSV_ST_VIDEO]; | 595 pkt = &nsv->ahead[NSV_ST_VIDEO]; |
598 av_get_packet(pb, pkt, vsize); | 596 av_get_packet(pb, pkt, vsize); |
599 pkt->stream_index = st[NSV_ST_VIDEO]->index;//NSV_ST_VIDEO; | 597 pkt->stream_index = st[NSV_ST_VIDEO]->index;//NSV_ST_VIDEO; |
600 pkt->dts = nst->frame_offset++; | 598 pkt->dts = nst->frame_offset++; |
601 pkt->flags |= PKT_FLAG_KEY; /* stupid format has no way to tell XXX: try the index */ | 599 pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */ |
602 /* | 600 /* |
603 for (i = 0; i < MIN(8, vsize); i++) | 601 for (i = 0; i < MIN(8, vsize); i++) |
604 PRINT(("NSV video: [%d] = %02x\n", i, pkt->data[i])); | 602 PRINT(("NSV video: [%d] = %02x\n", i, pkt->data[i])); |
605 */ | 603 */ |
606 } | 604 } |
628 st[NSV_ST_AUDIO]->codec->codec_id = CODEC_ID_PCM_U8; | 626 st[NSV_ST_AUDIO]->codec->codec_id = CODEC_ID_PCM_U8; |
629 samplerate /= 4;/* UGH ??? XXX */ | 627 samplerate /= 4;/* UGH ??? XXX */ |
630 channels = 1; | 628 channels = 1; |
631 st[NSV_ST_AUDIO]->codec->channels = channels; | 629 st[NSV_ST_AUDIO]->codec->channels = channels; |
632 st[NSV_ST_AUDIO]->codec->sample_rate = samplerate; | 630 st[NSV_ST_AUDIO]->codec->sample_rate = samplerate; |
633 av_set_pts_info(st[NSV_ST_AUDIO], 64, 1, | |
634 st[NSV_ST_AUDIO]->codec->sample_rate); | |
635 PRINT(("NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate)); | 631 PRINT(("NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate)); |
636 } | 632 } |
637 } | 633 } |
638 av_get_packet(pb, pkt, asize); | 634 av_get_packet(pb, pkt, asize); |
639 pkt->stream_index = st[NSV_ST_AUDIO]->index;//NSV_ST_AUDIO; | 635 pkt->stream_index = st[NSV_ST_AUDIO]->index;//NSV_ST_AUDIO; |
640 //pkt->dts = nst->frame_offset; | 636 pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */ |
641 //if (nst->sample_size) | 637 if( nsv->state == NSV_HAS_READ_NSVS && st[NSV_ST_VIDEO] ) { |
642 // pkt->dts /= nst->sample_size; | 638 /* on a nsvs frame we have new information on a/v sync */ |
643 nst->frame_offset += asize; // XXX: that's valid only for PCM !? | 639 pkt->dts = (((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1); |
644 } | 640 pkt->dts *= (int64_t)1000 * st[NSV_ST_VIDEO]->time_base.num; |
645 | 641 pkt->dts += (int64_t)nsv->avsync * st[NSV_ST_VIDEO]->time_base.den; |
646 //pkt->flags |= PKT_FLAG_KEY; | 642 PRINT(("NSV AUDIO: sync:%d, dts:%"PRId64, nsv->avsync, pkt->dts)); |
643 } | |
644 nst->frame_offset++; | |
645 } | |
646 | |
647 nsv->state = NSV_UNSYNC; | 647 nsv->state = NSV_UNSYNC; |
648 return 0; | 648 return 0; |
649 } | 649 } |
650 | 650 |
651 | 651 |