[FFmpeg-devel] [PATCH 1/1] segafilm: fetch duration from the container

James Almer jamrial at gmail.com
Fri Apr 20 06:31:21 EEST 2018


On 4/18/2018 4:29 PM, misty at brew.sh wrote:
> From: Misty De Meo <mistydemeo at gmail.com>
> 
> ---
>  libavformat/segafilm.c | 20 +++-----------------
>  1 file changed, 3 insertions(+), 17 deletions(-)
> 
> diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
> index e72c26b144..1529fc385e 100644
> --- a/libavformat/segafilm.c
> +++ b/libavformat/segafilm.c
> @@ -43,6 +43,7 @@ typedef struct film_sample {
>    int64_t sample_offset;
>    unsigned int sample_size;
>    int64_t pts;
> +  uint32_t duration;
>    int keyframe;
>  } film_sample;
>  
> @@ -226,6 +227,7 @@ static int film_read_header(AVFormatContext *s)
>              ret = AVERROR_INVALIDDATA;
>              goto fail;
>          }
> +        film->sample_table[i].duration = AV_RB32(&scratch[12]);

While for video tracks this field seems to report the same packet
durations that were being calculated pre patch, this field for audio
tracks is always 1.

Before this patch a codec copy of the sample logo-capcom.cpk in the FATE
suite gave:

1,          0,          0,    22048,    44096, 0xafd250ae
0,          2,          2,        2,    11080, 0xac3a462b
0,          4,          4,        2,    11300, 0xd8ee7f3e
0,          6,          6,        2,    21612, 0x73c3a3f9, F=0x0
0,          8,          8,        2,    21628, 0x00a5b4b9, F=0x0
0,         10,         10,        2,    14772, 0x1332b44f
0,         12,         12,        2,    14744, 0x5ce5d59b
0,         14,         14,        2,    14736, 0xd5ac2877
1,      22048,      22048,    11028,    22056, 0xe08a0f01

Whereas after applying it becomes:

1,          0,          0,        1,    44096, 0xafd250ae
0,          2,          2,        2,    11080, 0xac3a462b
0,          4,          4,        2,    11300, 0xd8ee7f3e
0,          6,          6,        2,    21612, 0x73c3a3f9, F=0x0
0,          8,          8,        2,    21628, 0x00a5b4b9, F=0x0
0,         10,         10,        2,    14772, 0x1332b44f
0,         12,         12,        2,    14744, 0x5ce5d59b
0,         14,         14,        2,    14736, 0xd5ac2877
1,      22048,      22048,        1,    22056, 0xe08a0f01

For reference, decoding it always gives the following with or without
this patch:

0,          0,          0,        1,   215040, 0x067c5362
1,          0,          0,    22048,    88192, 0x23bb50ae
0,          2,          2,        1,   215040, 0xd9eacb98
0,          4,          4,        1,   215040, 0x3c8a4cbd
0,          6,          6,        1,   215040, 0xbdf996e1
0,          8,          8,        1,   215040, 0x1b7fa123
0,         10,         10,        1,   215040, 0x834b4a8d
0,         12,         12,        1,   215040, 0xf4b1bebe
0,         14,         14,        1,   215040, 0x088c3802
1,      22048,      22048,    11028,    44112, 0x79600f01

Is this change desired/intended?

Also, unrelated to this patch, but as you can see decoding outputs one
extra video frame at the beginning that codec copy doesn't. this is
because packet keyframes are being set wrong: A 0 in the top bit of the
sample info dword on each sample table entry signals an Intra coded
frame, whereas 1 signals an Inter coded frame. The demuxer is assuming
the opposite.

>          if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) {
>              film->sample_table[i].stream = film->audio_stream_index;
>              film->sample_table[i].pts = audio_frame_counter;
> @@ -270,7 +272,6 @@ 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;
>  
> @@ -279,20 +280,6 @@ 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);
>  
> @@ -304,8 +291,7 @@ static int film_read_packet(AVFormatContext *s,
>      pkt->dts = sample->pts;
>      pkt->pts = sample->pts;
>      pkt->flags |= sample->keyframe ? AV_PKT_FLAG_KEY : 0;
> -    if (next_sample != NULL)
> -        pkt->duration = next_sample->pts - sample->pts;
> +    pkt->duration = sample->duration;
>  
>      film->current_sample++;


More information about the ffmpeg-devel mailing list