AOMediaCodec / av1-avif

AV1 Image File Format Specification - ISO-BMFF/HEIF derivative
https://aomediacodec.github.io/av1-avif/
BSD 2-Clause "Simplified" License
451 stars 40 forks source link

How to determine repetition count for the AVIFS image sequence? #73

Closed ledyba-z closed 4 years ago

ledyba-z commented 4 years ago

Hi, I'm currently working on supporting AVIF and AVIFS, and I have a question.

How can I determine the repetition count (infinite loop, fixed time loop, no loop) for the AVIFS image sequence?

I checked ISOBMFF, MIAF, HEIF, and av1-isobmff, but I can't find how many times the avifs should be repeated.

(It looks sample_delta field in stts box determine the display time, but it is unsigned, so I think it can't be used to represent infinite loop.)

cconcolato commented 4 years ago

The text in 23008-12:2017 Clause 9.6 :

To indicate that media is repeated, an enhancement to the EditListBox is used. The edit list maps the media timeline to the presentation timeline. The semantics of the flags field of the EditListBox as defined in ISO/IEC 14496-12 are extended as follows. When (flags & 1) is equal to 1, the entire edit list is repeated a sufficient number of times to equal the track duration. NOTE The number of times the edit list is repeated does not need to be an integer. In other words, the last repetition of the edit list may be cut to match the track duration. If the track duration is unknown/indefinite, the edit list is repeated indefinitely.

ledyba-z commented 4 years ago

Thank you for your reply!

I have additional question. Where EditListBox should be stored in? There seems no information about the container (, mandatory and quantity) of this EditListBox in 23008-12:2017.


To tell you the truth, because I'm mainly working for non-animated AVIF until today. it looks very complex to me and I think I didn't understand enough yet.

Anyway, I will also check ISO/IEC 14496-12. Thanks.

I think I will ask additinal questions, so please let me leave this issue open.

novomesk commented 4 years ago

I'd like to share my experience with AVIF animated sequences. My qt-avif-image-plugin plays animation from the AVIFS test files, but in my first implementation there is infinite loop and delay between frames is calculated only as int delay_ms = 1000.0 * m_decoder->duration / m_decoder->imageCount; so far. I felt I have little understanding about the format, that's why I asked How to create .avifs (image/avif-sequence) files? so I can get more experiences and correct my implementation in the future. I would appreciate more AVIFS testfiles together with some example movies (to compare timing) so everyone have similar output.

cconcolato commented 4 years ago

The group thinks this issue can be closed as the question has been answered. Please reopen if needed.

shivamidow commented 3 years ago

I am working on repeating avif sequences. Although I read multiple threads related to avifs, I don't still know how to get the track duration from libavif. Is avifDecoder->duration the track duration? Or else, doesn't libavif support the track duration and the flags for repetition yet?

The text in 23008-12:2017 Clause 9.6 :

To indicate that media is repeated, an enhancement to the EditListBox is used. The edit list maps the media timeline to the presentation timeline. The semantics of the flags field of the EditListBox as defined in ISO/IEC 14496-12 are extended as follows. When (flags & 1) is equal to 1, the entire edit list is repeated a sufficient number of times to equal the track duration. NOTE The number of times the edit list is repeated does not need to be an integer. In other words, the last repetition of the edit list may be cut to match the track duration. If the track duration is unknown/indefinite, the edit list is repeated indefinitely.

wantehchang commented 3 years ago

Hi ChangSeok,

You can use https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc as a reference. Search for "SetDuration" in that file. I use the avifDecoderNthImageTiming() function.

For repetition count, I just use kAnimationLoopInfinite.

shivamidow commented 3 years ago

@wantehchang Thanks for your reply. That is not the answer that I am looking for. I saw chromium was indefinitely repeating avifs but cconcolato's comment sounds like the avif sequence image can repeat for certain times (i.e., loop count = repetition count) as other animated image formats (e.g., apng, gif, webp) do. So, I am looking for the way how the repetition count can be calculated unless libavif directly provides the repetition count.

wantehchang commented 3 years ago

Hi ChangSeok,

I am sorry I misunderstood your question. libavif does not provide the repetition count.

As for avifDecoder->duration, I think it is the track duration. Here is the relevant source code in libavif/src/read.c:

        // Image sequence timing
        decoder->imageIndex = -1;
        decoder->imageCount = colorTile->input->samples.count;
        decoder->timescale = colorTrack->mediaTimescale;
        decoder->durationInTimescales = colorTrack->mediaDuration;
        if (colorTrack->mediaTimescale) {
            decoder->duration = (double)decoder->durationInTimescales / (double)colorTrack->mediaTimescale;
        } else {
            decoder->duration = 0;
        }

and

static avifBool avifParseMediaHeaderBox(avifTrack * track, const uint8_t * raw, size_t rawLen)
{
    BEGIN_STREAM(s, raw, rawLen);

    uint8_t version;
    CHECK(avifROStreamReadVersionAndFlags(&s, &version, NULL));

    uint32_t ignored32, mediaTimescale, mediaDuration32;
    uint64_t ignored64, mediaDuration64;
    if (version == 1) {
        CHECK(avifROStreamReadU64(&s, &ignored64));       // unsigned int(64) creation_time;
        CHECK(avifROStreamReadU64(&s, &ignored64));       // unsigned int(64) modification_time;
        CHECK(avifROStreamReadU32(&s, &mediaTimescale));  // unsigned int(32) timescale;
        CHECK(avifROStreamReadU64(&s, &mediaDuration64)); // unsigned int(64) duration;
        track->mediaDuration = mediaDuration64;
    } else if (version == 0) {
        CHECK(avifROStreamReadU32(&s, &ignored32));       // unsigned int(32) creation_time;
        CHECK(avifROStreamReadU32(&s, &ignored32));       // unsigned int(32) modification_time;
        CHECK(avifROStreamReadU32(&s, &mediaTimescale));  // unsigned int(32) timescale;
        CHECK(avifROStreamReadU32(&s, &mediaDuration32)); // unsigned int(32) duration;
        track->mediaDuration = (uint64_t)mediaDuration32;
    } else {
        // Unsupported version
        return AVIF_FALSE;
    }

    track->mediaTimescale = mediaTimescale;
    return AVIF_TRUE;
}

Searching for 'elst' (the boxtype for EditListBox) in libavif, I don't see any hit. So libavif does not read the flags field of the EditListBox.