Message ID | 20180322025536.98508-2-misty@brew.sh |
---|---|
State | Superseded |
Headers | show |
From: Misty De Meo <mistydemeo@gmail.com>
I've updated this so it applies on master.
This patch is still necessary; the wrong duration is most obvious when
remuxing Cinepak from FILM files without reencoding. For example, one
sample video I have has a timebase of 30, and most frames last for two
ticks. When remuxing in a format which uses the duration, this can leave
gaps in the time codes. Here's an example from an original video and one
remuxed using FFmpeg. The first number is the absolute timestamp, and the
second number is the duration value. In the first set, from the original
video, you can see that the timestamps increase by 2 each tick and the
time between frames also increases by 2 each tick.
In the second set, produced by FFmpeg, the timestamps still increase by
2 but the time between frames is now marked as 1. This is fixed by this
patch.
80000002 00000002
80000004 00000002
80000002 00000001
80000004 00000001
Misty De Meo (1):
Sega FILM: set dts and duration when demuxing
libavformat/segafilm.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index 11768823fc..03a639e034 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -270,6 +270,8 @@ static int film_read_packet(AVFormatContext *s, FilmDemuxContext *film = s->priv_data; AVIOContext *pb = s->pb; film_sample *sample; + film_sample *next_sample = NULL; + int next_sample_id; int ret = 0; if (film->current_sample >= film->sample_count) @@ -277,6 +279,20 @@ static int film_read_packet(AVFormatContext *s, sample = &film->sample_table[film->current_sample]; + /* Find the next sample from the same stream, assuming there is one; + * this is used to calculate the duration below */ + next_sample_id = film->current_sample + 1; + while (next_sample == NULL) { + if (next_sample_id >= film->sample_count) + break; + + next_sample = &film->sample_table[next_sample_id]; + if (next_sample->stream != sample->stream) { + next_sample = NULL; + next_sample_id++; + } + } + /* position the stream (will probably be there anyway) */ avio_seek(pb, sample->sample_offset, SEEK_SET); @@ -285,8 +301,11 @@ static int film_read_packet(AVFormatContext *s, ret = AVERROR(EIO); pkt->stream_index = sample->stream; + pkt->dts = sample->pts; pkt->pts = sample->pts; pkt->flags |= sample->keyframe; + if (next_sample != NULL) + pkt->duration = next_sample->pts - sample->pts; film->current_sample++;
From: Misty De Meo <mistydemeo@gmail.com> --- libavformat/segafilm.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)