提交 986ebcdb 编写于 作者: M Michael Niedermayer

audio timestamp drift compensation

Originally committed as revision 3272 to svn://svn.ffmpeg.org/ffmpeg/trunk
上级 b9d2085b
......@@ -201,7 +201,8 @@ static int bitexact = 0;
static char *pass_logfilename = NULL;
static int audio_stream_copy = 0;
static int video_stream_copy = 0;
static int sync_method= 1;
static int video_sync_method= 1;
static int audio_sync_method= 0;
static int copy_ts= 0;
static int rate_emu = 0;
......@@ -432,6 +433,22 @@ static void do_audio_out(AVFormatContext *s,
enc = &ost->st->codec;
if(audio_sync_method){
double delta = ost->sync_ipts * enc->sample_rate - ost->sync_opts
- fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2);
//FIXME resample delay
if(fabs(delta) > 50){
int comp= clip(delta, -audio_sync_method, audio_sync_method);
assert(ost->audio_resample);
if(verbose > 2)
fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
// fprintf(stderr, "drift:%f len:%d opts:%lld ipts:%lld fifo:%d\n", delta, len/4, ost->sync_opts, (int64_t)(ost->sync_ipts * enc->sample_rate), fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2));
av_resample_compensate(*(struct AVResampleContext**)ost->resample, delta, enc->sample_rate);
}
}else
ost->sync_opts= lrintf(ost->sync_ipts * enc->sample_rate)
- fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2); //FIXME wrong
if (ost->audio_resample) {
buftmp = audio_buf;
......@@ -467,10 +484,15 @@ static void do_audio_out(AVFormatContext *s,
pkt.pts= enc->coded_frame->pts;
pkt.flags |= PKT_FLAG_KEY;
av_interleaved_write_frame(s, &pkt);
ost->sync_opts += enc->frame_size;
}
} else {
AVPacket pkt;
av_init_packet(&pkt);
ost->sync_opts += size_out / enc->channels;
/* output a pcm frame */
/* XXX: change encoding codec API to avoid this ? */
switch(enc->codec->id) {
......@@ -588,7 +610,7 @@ static void do_video_out(AVFormatContext *s,
AVOutputStream *ost,
AVInputStream *ist,
AVFrame *in_picture,
int *frame_size, AVOutputStream *audio_sync)
int *frame_size)
{
int nb_frames, i, ret;
AVFrame *final_picture, *formatted_picture;
......@@ -610,7 +632,7 @@ static void do_video_out(AVFormatContext *s,
*frame_size = 0;
if(sync_method){
if(video_sync_method){
double vdelta;
vdelta = ost->sync_ipts * enc->frame_rate / enc->frame_rate_base - ost->sync_opts;
//FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
......@@ -1018,11 +1040,11 @@ static int output_packet(AVInputStream *ist, int ist_index,
AVFrame picture;
short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
void *buffer_to_free;
//fprintf(stderr, "output_packet %d, dts:%lld\n", pkt->stream_index, pkt->dts);
if (pkt && pkt->dts != AV_NOPTS_VALUE) { //FIXME seems redundant, as libavformat does this too
ist->next_pts = ist->pts = pkt->dts;
} else {
ist->pts = ist->next_pts;
assert(ist->pts == ist->next_pts);
}
if (pkt == NULL) {
......@@ -1134,7 +1156,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
printf("%d: got pts=%0.3f %0.3f\n", i,
(double)pkt->pts / AV_TIME_BASE,
((double)ist->pts / AV_TIME_BASE) -
((double)ost->st->pts.val * ost->time_base.num / ost->time_base.den));
((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den));
#endif
/* set the input output pts pairs */
ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index])/ AV_TIME_BASE;
......@@ -1159,7 +1181,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
}
}
do_video_out(os, ost, ist, &picture, &frame_size, audio_sync);
do_video_out(os, ost, ist, &picture, &frame_size);
video_size += frame_size;
if (do_vstats && frame_size)
do_video_stats(os, ost, frame_size);
......@@ -1460,27 +1482,20 @@ static int av_encode(AVFormatContext **output_files,
ost->audio_resample = 0;
else {
ost->audio_resample = 1;
ost->resample = audio_resample_init(codec->channels, icodec->channels,
codec->sample_rate,
icodec->sample_rate);
if(!ost->resample)
{
printf("Can't resample. Aborting.\n");
av_abort();
}
}
/* Request specific number of channels */
icodec->channels = codec->channels;
} else {
ost->audio_resample = 1;
ost->resample = audio_resample_init(codec->channels, icodec->channels,
codec->sample_rate,
icodec->sample_rate);
if(!ost->resample)
{
printf("Can't resample. Aborting.\n");
av_abort();
}
}
}
if(audio_sync_method)
ost->audio_resample = 1;
if(ost->audio_resample){
ost->resample = audio_resample_init(codec->channels, icodec->channels,
codec->sample_rate, icodec->sample_rate);
if(!ost->resample){
printf("Can't resample. Aborting.\n");
av_abort();
}
}
ist->decoding_needed = 1;
......@@ -2010,11 +2025,6 @@ static void opt_verbose(const char *arg)
av_log_set_level(atoi(arg));
}
static void opt_sync_method(const char *arg)
{
sync_method = atoi(arg);
}
static void opt_frame_rate(const char *arg)
{
if (parse_frame_rate(&frame_rate, &frame_rate_base, arg) < 0) {
......@@ -3626,7 +3636,8 @@ const OptionDef options[] = {
{ "v", HAS_ARG, {(void*)opt_verbose}, "control amount of logging", "verbose" },
{ "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\" or \"dvd\")", "type" },
{ "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
{ "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync_method}, "sync method", "" },
{ "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
{ "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
{ "copyts", OPT_BOOL | OPT_EXPERT, {(void*)&copy_ts}, "copy timestamps" },
/* video options */
......
......@@ -9,7 +9,7 @@ ffmpeg regression test
360251 ./data/b-libav.rm
e0a9ed22a34e0277ec77c84e8b64afd9 *./data/b-libav.mpg
387072 ./data/b-libav.mpg
./data/b-libav.mpg CRC=ac661eb1
./data/b-libav.mpg CRC=723a4225
57a8dfc7926802bb337a9d8918de94a8 *./data/b-libav.swf
41816 ./data/b-libav.swf
./data/b-libav.swf CRC=2b273fea
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册