[FFmpeg-devel] [PATCH] ffmpeg: Preserve input subtitle packet duration. v2
Philip Langdale
philipl at overt.org
Sun Sep 2 01:08:44 CEST 2012
My original implementation for setting out output packet duration
derived the value from the AVSubtitle object, but the value stored
in there has been rescaled to ASS 1/100s timebase, while the
normalized timebase for both input and output packets is 1/1000s,
so there's a gratuitous loss of precision, which results in output
durations not corresponding exactly to input durations - which can
impact subtitles where one is supposed to exactly follow another.
The simple solution is to carry the original input duration over
to the output packet (with rescaling, of course), and ignore the
AVSubtitle value.
Signed-off-by: Philip Langdale <philipl at overt.org>
---
ffmpeg.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/ffmpeg.c b/ffmpeg.c
index 2763db6..ffbac57 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -689,7 +689,8 @@ static void do_subtitle_out(AVFormatContext *s,
OutputStream *ost,
InputStream *ist,
AVSubtitle *sub,
- int64_t pts)
+ int64_t pts,
+ int32_t duration)
{
int subtitle_out_max_size = 1024 * 1024;
int subtitle_out_size, nb, i;
@@ -743,7 +744,7 @@ static void do_subtitle_out(AVFormatContext *s,
pkt.data = subtitle_out;
pkt.size = subtitle_out_size;
pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base);
- pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->st->time_base);
+ pkt.duration = av_rescale_q(duration, (AVRational){ 1, 1000 }, ost->st->time_base);
if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
/* XXX: the pts correction is handled here. Maybe handling
it in the codec would be better */
@@ -1653,6 +1654,7 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
{
AVSubtitle subtitle;
int64_t pts = pkt->pts;
+ int32_t duration = pkt->duration;
int i, ret = avcodec_decode_subtitle2(ist->st->codec,
&subtitle, got_output, pkt);
if (ret < 0 || !*got_output) {
@@ -1670,6 +1672,7 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
"Subtitle duration reduced from %d to %d\n",
ist->prev_sub.subtitle.end_display_time, end);
ist->prev_sub.subtitle.end_display_time = end;
+ duration = end;
}
}
FFSWAP(int64_t, pts, ist->prev_sub.pts);
@@ -1691,7 +1694,8 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
continue;
- do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle, pts);
+ do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist,
+ &subtitle, pts, duration);
}
avsubtitle_free(&subtitle);
--
1.7.9.5
More information about the ffmpeg-devel
mailing list