mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-18 05:11:09 +00:00
A/V sync patch from Gildas Bazin.
Originally committed as revision 2098 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
302898fcbe
commit
e7d0374f27
109
ffmpeg.c
109
ffmpeg.c
@ -205,7 +205,8 @@ typedef struct AVInputStream {
|
||||
|
||||
int64_t start; /* time when read started */
|
||||
unsigned long frame; /* current frame */
|
||||
AVFrac pts; /* synthetic pts for cases where pkt.pts == 0 */
|
||||
AVFrac next_pts; /* synthetic pts for cases where pkt.pts == 0 */
|
||||
int64_t pts; /* current pts */
|
||||
} AVInputStream;
|
||||
|
||||
typedef struct AVInputFile {
|
||||
@ -472,42 +473,33 @@ static void do_video_out(AVFormatContext *s,
|
||||
but not for the general case */
|
||||
if (audio_sync) {
|
||||
/* compute the A-V delay and duplicate/remove frames if needed */
|
||||
double adelta, vdelta, apts, vpts, av_delay;
|
||||
|
||||
if (audio_sync->sync_ipts != AV_NOPTS_VALUE &&
|
||||
ost->sync_ipts != AV_NOPTS_VALUE) {
|
||||
|
||||
adelta = (double)(ost->st->pts.val - audio_sync->sync_opts) *
|
||||
s->pts_num / s->pts_den;
|
||||
apts = audio_sync->sync_ipts + adelta;
|
||||
|
||||
vdelta = (double)(ost->st->pts.val - ost->sync_opts) *
|
||||
s->pts_num / s->pts_den;
|
||||
vpts = ost->sync_ipts + vdelta;
|
||||
|
||||
av_delay = apts - vpts;
|
||||
// printf("delay=%f\n", av_delay);
|
||||
if (av_delay < -AV_DELAY_MAX)
|
||||
nb_frames = 2;
|
||||
else if (av_delay > AV_DELAY_MAX)
|
||||
nb_frames = 0;
|
||||
}
|
||||
double adelta, vdelta, av_delay;
|
||||
|
||||
adelta = audio_sync->sync_ipts - ((double)audio_sync->sync_opts *
|
||||
s->pts_num / s->pts_den);
|
||||
|
||||
vdelta = ost->sync_ipts - ((double)ost->sync_opts *
|
||||
s->pts_num / s->pts_den);
|
||||
|
||||
av_delay = adelta - vdelta;
|
||||
// printf("delay=%f\n", av_delay);
|
||||
if (av_delay < -AV_DELAY_MAX)
|
||||
nb_frames = 2;
|
||||
else if (av_delay > AV_DELAY_MAX)
|
||||
nb_frames = 0;
|
||||
} else {
|
||||
double vdelta;
|
||||
|
||||
if (ost->sync_ipts != AV_NOPTS_VALUE) {
|
||||
vdelta = (double)(ost->st->pts.val) * s->pts_num / s->pts_den - (ost->sync_ipts - ost->sync_ipts_offset);
|
||||
if (vdelta < 100 && vdelta > -100 && ost->sync_ipts_offset) {
|
||||
if (vdelta < -AV_DELAY_MAX)
|
||||
nb_frames = 2;
|
||||
else if (vdelta > AV_DELAY_MAX)
|
||||
nb_frames = 0;
|
||||
} else {
|
||||
ost->sync_ipts_offset -= vdelta;
|
||||
if (!ost->sync_ipts_offset)
|
||||
ost->sync_ipts_offset = 0.000001; /* one microsecond */
|
||||
}
|
||||
|
||||
vdelta = (double)(ost->st->pts.val) * s->pts_num / s->pts_den - (ost->sync_ipts - ost->sync_ipts_offset);
|
||||
if (vdelta < 100 && vdelta > -100 && ost->sync_ipts_offset) {
|
||||
if (vdelta < -AV_DELAY_MAX)
|
||||
nb_frames = 2;
|
||||
else if (vdelta > AV_DELAY_MAX)
|
||||
nb_frames = 0;
|
||||
} else {
|
||||
ost->sync_ipts_offset -= vdelta;
|
||||
if (!ost->sync_ipts_offset)
|
||||
ost->sync_ipts_offset = 0.000001; /* one microsecond */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1108,13 +1100,14 @@ static int av_encode(AVFormatContext **output_files,
|
||||
for(i=0;i<nb_istreams;i++) {
|
||||
ist = ist_table[i];
|
||||
is = input_files[ist->file_index];
|
||||
ist->pts = 0;
|
||||
switch (ist->st->codec.codec_type) {
|
||||
case CODEC_TYPE_AUDIO:
|
||||
av_frac_init(&ist->pts,
|
||||
av_frac_init(&ist->next_pts,
|
||||
0, 0, is->pts_num * ist->st->codec.sample_rate);
|
||||
break;
|
||||
case CODEC_TYPE_VIDEO:
|
||||
av_frac_init(&ist->pts,
|
||||
av_frac_init(&ist->next_pts,
|
||||
0, 0, is->pts_num * ist->st->codec.frame_rate);
|
||||
break;
|
||||
default:
|
||||
@ -1220,10 +1213,6 @@ static int av_encode(AVFormatContext **output_files,
|
||||
len = pkt.size;
|
||||
ptr = pkt.data;
|
||||
while (len > 0) {
|
||||
int64_t ipts;
|
||||
|
||||
ipts = AV_NOPTS_VALUE;
|
||||
|
||||
/* decode the packet if needed */
|
||||
data_buf = NULL; /* fail safe */
|
||||
data_size = 0;
|
||||
@ -1233,8 +1222,15 @@ static int av_encode(AVFormatContext **output_files,
|
||||
/* NOTE2: even if the fraction is not initialized,
|
||||
av_frac_set can be used to set the integer part */
|
||||
if (ist->frame_decoded) {
|
||||
/* If pts is unavailable -- we have to use synthetic one */
|
||||
ipts = (pkt.pts == AV_NOPTS_VALUE) ? ist->pts.val : pkt.pts;
|
||||
/* If pts is unavailable -- we have to use synthetic one */
|
||||
if( pkt.pts != AV_NOPTS_VALUE )
|
||||
{
|
||||
ist->pts = ist->next_pts.val = pkt.pts;
|
||||
}
|
||||
else
|
||||
{
|
||||
ist->pts = ist->next_pts.val;
|
||||
}
|
||||
ist->frame_decoded = 0;
|
||||
}
|
||||
|
||||
@ -1255,7 +1251,7 @@ static int av_encode(AVFormatContext **output_files,
|
||||
continue;
|
||||
}
|
||||
data_buf = (uint8_t *)samples;
|
||||
av_frac_add(&ist->pts,
|
||||
av_frac_add(&ist->next_pts,
|
||||
is->pts_den * data_size / (2 * ist->st->codec.channels));
|
||||
break;
|
||||
case CODEC_TYPE_VIDEO:
|
||||
@ -1280,7 +1276,7 @@ static int av_encode(AVFormatContext **output_files,
|
||||
len -= ret;
|
||||
continue;
|
||||
}
|
||||
av_frac_add(&ist->pts,
|
||||
av_frac_add(&ist->next_pts,
|
||||
is->pts_den * ist->st->codec.frame_rate_base);
|
||||
}
|
||||
break;
|
||||
@ -1334,23 +1330,17 @@ static int av_encode(AVFormatContext **output_files,
|
||||
if (ost->source_index == ist_index) {
|
||||
os = output_files[ost->file_index];
|
||||
|
||||
if (ipts != AV_NOPTS_VALUE) {
|
||||
#if 0
|
||||
printf("%d: got pts=%f %f\n",
|
||||
i, pkt.pts / 90000.0,
|
||||
(ipts - ost->st->pts.val) / 90000.0);
|
||||
printf("%d: got pts=%f %f\n", i, pkt.pts / 90000.0,
|
||||
(ist->pts - ost->st->pts.val) / 90000.0);
|
||||
#endif
|
||||
/* set the input output pts pairs */
|
||||
ost->sync_ipts = (double)ipts * is->pts_num /
|
||||
is->pts_den;
|
||||
/* XXX: take into account the various fifos,
|
||||
in particular for audio */
|
||||
ost->sync_opts = ost->st->pts.val;
|
||||
//printf("ipts=%lld sync_ipts=%f sync_opts=%lld pts.val=%lld pkt.pts=%lld\n", ipts, ost->sync_ipts, ost->sync_opts, ost->st->pts.val, pkt.pts);
|
||||
} else {
|
||||
//printf("pts.val=%lld\n", ost->st->pts.val);
|
||||
ost->sync_ipts = AV_NOPTS_VALUE;
|
||||
}
|
||||
/* set the input output pts pairs */
|
||||
ost->sync_ipts = (double)ist->pts * is->pts_num /
|
||||
is->pts_den;
|
||||
/* XXX: take into account the various fifos,
|
||||
in particular for audio */
|
||||
ost->sync_opts = ost->st->pts.val;
|
||||
//printf("ipts=%lld sync_ipts=%f sync_opts=%lld pts.val=%lld pkt.pts=%lld\n", ist->pts, ost->sync_ipts, ost->sync_opts, ost->st->pts.val, pkt.pts);
|
||||
|
||||
if (ost->encoding_needed) {
|
||||
switch(ost->st->codec.codec_type) {
|
||||
@ -1397,7 +1387,6 @@ static int av_encode(AVFormatContext **output_files,
|
||||
}
|
||||
}
|
||||
av_free(buffer_to_free);
|
||||
ipts = AV_NOPTS_VALUE;
|
||||
}
|
||||
discard_packet:
|
||||
av_free_packet(&pkt);
|
||||
|
Loading…
Reference in New Issue
Block a user