static void mov_read_chapters(AVFormatContext *s)

{

    MOVContext *mov = s->priv_data;

    AVStream *st = NULL;

    MOVStreamContext *sc;

    int64_t cur_pos;

    int i;



    for (i = 0; i < s->nb_streams; i++)

        if (s->streams[i]->id == mov->chapter_track) {

            st = s->streams[i];

            break;

        }

    if (!st) {

        av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");

        return;

    }



    st->discard = AVDISCARD_ALL;

    sc = st->priv_data;

    cur_pos = avio_tell(sc->pb);



    for (i = 0; i < st->nb_index_entries; i++) {

        AVIndexEntry *sample = &st->index_entries[i];

        int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;

        uint8_t *title;

        uint16_t ch;

        int len, title_len;



        if (end < sample->timestamp) {

            av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");

            end = AV_NOPTS_VALUE;

        }



        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {

            av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);

            goto finish;

        }



        // the first two bytes are the length of the title

        len = avio_rb16(sc->pb);

        if (len > sample->size-2)

            continue;

        title_len = 2*len + 1;

        if (!(title = av_mallocz(title_len)))

            goto finish;



        // The samples could theoretically be in any encoding if there's an encd

        // atom following, but in practice are only utf-8 or utf-16, distinguished

        // instead by the presence of a BOM

        if (!len) {

            title[0] = 0;

        } else {

            ch = avio_rb16(sc->pb);

            if (ch == 0xfeff)

                avio_get_str16be(sc->pb, len, title, title_len);

            else if (ch == 0xfffe)

                avio_get_str16le(sc->pb, len, title, title_len);

            else {

                AV_WB16(title, ch);

                if (len == 1 || len == 2)

                    title[len] = 0;

                else

                    avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);

            }

        }



        avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);

        av_freep(&title);

    }

finish:

    avio_seek(sc->pb, cur_pos, SEEK_SET);

}

static void mov_read_chapters(AVFormatContext *s)

{

    MOVContext *mov = s->priv_data;

    AVStream *st = NULL;

    MOVStreamContext *sc;

    int64_t cur_pos;

    int i;



    for (i = 0; i < s->nb_streams; i++)

        if (s->streams[i]->id == mov->chapter_track) {

            st = s->streams[i];

            break;

        }

    if (!st) {

        av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");

        return;

    }



    st->discard = AVDISCARD_ALL;

    sc = st->priv_data;

    cur_pos = avio_tell(sc->pb);



    for (i = 0; i < st->nb_index_entries; i++) {

        AVIndexEntry *sample = &st->index_entries[i];

        int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;

        uint8_t *title;

        uint16_t ch;

        int len, title_len;



        if (end < sample->timestamp) {

            av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");

            end = AV_NOPTS_VALUE;

        }



        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {

            av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);

            goto finish;

        }



        

        len = avio_rb16(sc->pb);

        if (len > sample->size-2)

            continue;

        title_len = 2*len + 1;

        if (!(title = av_mallocz(title_len)))

            goto finish;



        

        

        

        if (!len) {

            title[0] = 0;

        } else {

            ch = avio_rb16(sc->pb);

            if (ch == 0xfeff)

                avio_get_str16be(sc->pb, len, title, title_len);

            else if (ch == 0xfffe)

                avio_get_str16le(sc->pb, len, title, title_len);

            else {

                AV_WB16(title, ch);

                if (len == 1 || len == 2)

                    title[len] = 0;

                else

                    avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);

            }

        }



        avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);

        av_freep(&title);

    }

finish:

    avio_seek(sc->pb, cur_pos, SEEK_SET);

}

static void FUNC_0(AVFormatContext *VAR_0)

{

    MOVContext *mov = VAR_0->priv_data;

    AVStream *st = NULL;

    MOVStreamContext *sc;

    int64_t cur_pos;

    int VAR_1;



    for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++)

        if (VAR_0->streams[VAR_1]->id == mov->chapter_track) {

            st = VAR_0->streams[VAR_1];

            break;

        }

    if (!st) {

        av_log(VAR_0, AV_LOG_ERROR, "Referenced QT chapter track not found\n");

        return;

    }



    st->discard = AVDISCARD_ALL;

    sc = st->priv_data;

    cur_pos = avio_tell(sc->pb);



    for (VAR_1 = 0; VAR_1 < st->nb_index_entries; VAR_1++) {

        AVIndexEntry *sample = &st->index_entries[VAR_1];

        int64_t end = VAR_1+1 < st->nb_index_entries ? st->index_entries[VAR_1+1].timestamp : st->duration;

        uint8_t *title;

        uint16_t ch;

        int len, title_len;



        if (end < sample->timestamp) {

            av_log(VAR_0, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");

            end = AV_NOPTS_VALUE;

        }



        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {

            av_log(VAR_0, AV_LOG_ERROR, "Chapter %d not found in file\n", VAR_1);

            goto finish;

        }



        

        len = avio_rb16(sc->pb);

        if (len > sample->size-2)

            continue;

        title_len = 2*len + 1;

        if (!(title = av_mallocz(title_len)))

            goto finish;



        

        

        

        if (!len) {

            title[0] = 0;

        } else {

            ch = avio_rb16(sc->pb);

            if (ch == 0xfeff)

                avio_get_str16be(sc->pb, len, title, title_len);

            else if (ch == 0xfffe)

                avio_get_str16le(sc->pb, len, title, title_len);

            else {

                AV_WB16(title, ch);

                if (len == 1 || len == 2)

                    title[len] = 0;

                else

                    avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);

            }

        }



        avpriv_new_chapter(VAR_0, VAR_1, st->time_base, sample->timestamp, end, title);

        av_freep(&title);

    }

finish:

    avio_seek(sc->pb, cur_pos, SEEK_SET);

}

static void FUNC_0(AVFormatContext *VAR_0)
{ MOVContext *mov = VAR_0->priv_data; AVStream *st = NULL; MOVStreamContext *sc; int64_t cur_pos; int VAR_1; for (VAR_1 = 0; VAR_1 < VAR_0->nb_streams; VAR_1++) if (VAR_0->streams[VAR_1]->id == mov->chapter_track) { st = VAR_0->streams[VAR_1]; break; } if (!st) { av_log(VAR_0, AV_LOG_ERROR, "Referenced QT chapter track not found\n"); return; } st->discard = AVDISCARD_ALL; sc = st->priv_data; cur_pos = avio_tell(sc->pb); for (VAR_1 = 0; VAR_1 < st->nb_index_entries; VAR_1++) { AVIndexEntry *sample = &st->index_entries[VAR_1]; int64_t end = VAR_1+1 < st->nb_index_entries ? st->index_entries[VAR_1+1].timestamp : st->duration; uint8_t *title; uint16_t ch; int len, title_len; if (end < sample->timestamp) { av_log(VAR_0, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n"); end = AV_NOPTS_VALUE; } if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { av_log(VAR_0, AV_LOG_ERROR, "Chapter %d not found in file\n", VAR_1); goto finish; } len = avio_rb16(sc->pb); if (len > sample->size-2)
continue; title_len = 2*len + 1; if (!(title = av_mallocz(title_len)))
goto finish; if (!len) { title[0] = 0; } else { ch = avio_rb16(sc->pb); if (ch == 0xfeff)
avio_get_str16be(sc->pb, len, title, title_len); else if (ch == 0xfffe)
avio_get_str16le(sc->pb, len, title, title_len); else { AV_WB16(title, ch); if (len == 1 || len == 2)
title[len] = 0; else
avio_get_str(sc->pb, INT_MAX, title + 2, len - 1); } } avpriv_new_chapter(VAR_0, VAR_1, st->time_base, sample->timestamp, end, title); av_freep(&title); } finish:
avio_seek(sc->pb, cur_pos, SEEK_SET); }