static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)

{

    struct sgpd_entry {

        int count;

        int16_t roll_distance;

        int group_description_index;

    };



    struct sgpd_entry *sgpd_entries = NULL;

    int entries = -1;

    int group = 0;

    int i, j;



    const int OPUS_SEEK_PREROLL_MS = 80;

    int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,

                                    (AVRational){1, 1000},

                                    (AVRational){1, 48000});



    if (track->entry) {

        sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));

        if (!sgpd_entries)

            return AVERROR(ENOMEM);

    }



    av_assert0(track->par->codec_id == AV_CODEC_ID_OPUS);



    for (i = 0; i < track->entry; i++) {

        int roll_samples_remaining = roll_samples;

        int distance = 0;

        for (j = i - 1; j >= 0; j--) {

            roll_samples_remaining -= get_cluster_duration(track, j);

            distance++;

            if (roll_samples_remaining <= 0)

                break;

        }

        /* We don't have enough preceeding samples to compute a valid

           roll_distance here, so this sample can't be independently

           decoded. */

        if (roll_samples_remaining > 0)

            distance = 0;

        /* Verify distance is a minimum of 2 (60ms) packets and a maximum of

           32 (2.5ms) packets. */

        av_assert0(distance == 0 || (distance >= 2 && distance <= 32));

        if (i && distance == sgpd_entries[entries].roll_distance) {

            sgpd_entries[entries].count++;

        } else {

            entries++;

            sgpd_entries[entries].count = 1;

            sgpd_entries[entries].roll_distance = distance;

            sgpd_entries[entries].group_description_index = distance ? ++group : 0;

        }

    }

    entries++;



    if (!group)

        return 0;



    /* Write sgpd tag */

    avio_wb32(pb, 24 + (group * 2)); /* size */

    ffio_wfourcc(pb, "sgpd");

    avio_wb32(pb, 1 << 24); /* fullbox */

    ffio_wfourcc(pb, "roll");

    avio_wb32(pb, 2); /* default_length */

    avio_wb32(pb, group); /* entry_count */

    for (i = 0; i < entries; i++) {

        if (sgpd_entries[i].group_description_index) {

            avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */

        }

    }



    /* Write sbgp tag */

    avio_wb32(pb, 20 + (entries * 8)); /* size */

    ffio_wfourcc(pb, "sbgp");

    avio_wb32(pb, 0); /* fullbox */

    ffio_wfourcc(pb, "roll");

    avio_wb32(pb, entries); /* entry_count */

    for (i = 0; i < entries; i++) {

        avio_wb32(pb, sgpd_entries[i].count); /* sample_count */

        avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */

    }



    av_free(sgpd_entries);

    return 0;

}

static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)

{

    struct sgpd_entry {

        int count;

        int16_t roll_distance;

        int group_description_index;

    };



    struct sgpd_entry *sgpd_entries = NULL;

    int entries = -1;

    int group = 0;

    int i, j;



    const int OPUS_SEEK_PREROLL_MS = 80;

    int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,

                                    (AVRational){1, 1000},

                                    (AVRational){1, 48000});



    if (track->entry) {

        sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));

        if (!sgpd_entries)

            return AVERROR(ENOMEM);

    }



    av_assert0(track->par->codec_id == AV_CODEC_ID_OPUS);



    for (i = 0; i < track->entry; i++) {

        int roll_samples_remaining = roll_samples;

        int distance = 0;

        for (j = i - 1; j >= 0; j--) {

            roll_samples_remaining -= get_cluster_duration(track, j);

            distance++;

            if (roll_samples_remaining <= 0)

                break;

        }

        





        if (roll_samples_remaining > 0)

            distance = 0;

        



        av_assert0(distance == 0 || (distance >= 2 && distance <= 32));

        if (i && distance == sgpd_entries[entries].roll_distance) {

            sgpd_entries[entries].count++;

        } else {

            entries++;

            sgpd_entries[entries].count = 1;

            sgpd_entries[entries].roll_distance = distance;

            sgpd_entries[entries].group_description_index = distance ? ++group : 0;

        }

    }

    entries++;



    if (!group)

        return 0;



    

    avio_wb32(pb, 24 + (group * 2)); 

    ffio_wfourcc(pb, "sgpd");

    avio_wb32(pb, 1 << 24); 

    ffio_wfourcc(pb, "roll");

    avio_wb32(pb, 2); 

    avio_wb32(pb, group); 

    for (i = 0; i < entries; i++) {

        if (sgpd_entries[i].group_description_index) {

            avio_wb16(pb, -sgpd_entries[i].roll_distance); 

        }

    }



    

    avio_wb32(pb, 20 + (entries * 8)); 

    ffio_wfourcc(pb, "sbgp");

    avio_wb32(pb, 0); 

    ffio_wfourcc(pb, "roll");

    avio_wb32(pb, entries); 

    for (i = 0; i < entries; i++) {

        avio_wb32(pb, sgpd_entries[i].count); 

        avio_wb32(pb, sgpd_entries[i].group_description_index); 

    }



    av_free(sgpd_entries);

    return 0;

}

    if (!group)
static int FUNC_0(AVIOContext *VAR_0, MOVTrack *VAR_1)

{

    struct sgpd_entry {

        int count;

        int16_t roll_distance;

        int group_description_index;

    };



    struct sgpd_entry *VAR_2 = NULL;

    int VAR_3 = -1;

    int VAR_4 = 0;

    int VAR_5, VAR_6;



    const int VAR_7 = 80;

    int VAR_8 = av_rescale_q(VAR_7,

                                    (AVRational){1, 1000},

                                    (AVRational){1, 48000});



    if (VAR_1->entry) {

        VAR_2 = av_malloc_array(VAR_1->entry, sizeof(*VAR_2));

        if (!VAR_2)

            return AVERROR(ENOMEM);

    }



    av_assert0(VAR_1->par->codec_id == AV_CODEC_ID_OPUS);



    for (VAR_5 = 0; VAR_5 < VAR_1->entry; VAR_5++) {

        int roll_samples_remaining = VAR_8;

        int distance = 0;

        for (VAR_6 = VAR_5 - 1; VAR_6 >= 0; VAR_6--) {

            roll_samples_remaining -= get_cluster_duration(VAR_1, VAR_6);

            distance++;

            if (roll_samples_remaining <= 0)

                break;

        }

        





        if (roll_samples_remaining > 0)

            distance = 0;

        



        av_assert0(distance == 0 || (distance >= 2 && distance <= 32));

        if (VAR_5 && distance == VAR_2[VAR_3].roll_distance) {

            VAR_2[VAR_3].count++;

        } else {

            VAR_3++;

            VAR_2[VAR_3].count = 1;

            VAR_2[VAR_3].roll_distance = distance;

            VAR_2[VAR_3].group_description_index = distance ? ++VAR_4 : 0;

        }

    }

    VAR_3++;



    if (!VAR_4)

        return 0;



    

    avio_wb32(VAR_0, 24 + (VAR_4 * 2)); 

    ffio_wfourcc(VAR_0, "sgpd");

    avio_wb32(VAR_0, 1 << 24); 

    ffio_wfourcc(VAR_0, "roll");

    avio_wb32(VAR_0, 2); 

    avio_wb32(VAR_0, VAR_4); 

    for (VAR_5 = 0; VAR_5 < VAR_3; VAR_5++) {

        if (VAR_2[VAR_5].group_description_index) {

            avio_wb16(VAR_0, -VAR_2[VAR_5].roll_distance); 

        }

    }



    

    avio_wb32(VAR_0, 20 + (VAR_3 * 8)); 

    ffio_wfourcc(VAR_0, "sbgp");

    avio_wb32(VAR_0, 0); 

    ffio_wfourcc(VAR_0, "roll");

    avio_wb32(VAR_0, VAR_3); 

    for (VAR_5 = 0; VAR_5 < VAR_3; VAR_5++) {

        avio_wb32(VAR_0, VAR_2[VAR_5].count); 

        avio_wb32(VAR_0, VAR_2[VAR_5].group_description_index); 

    }



    av_free(VAR_2);

    return 0;

}

static int FUNC_0(AVIOContext *VAR_0, MOVTrack *VAR_1)
{ struct sgpd_entry { int count; int16_t roll_distance; int group_description_index; }; struct sgpd_entry *VAR_2 = NULL; int VAR_3 = -1; int VAR_4 = 0; int VAR_5, VAR_6; const int VAR_7 = 80; int VAR_8 = av_rescale_q(VAR_7,
(AVRational){1, 1000}, (AVRational){1, 48000}); if (VAR_1->entry) { VAR_2 = av_malloc_array(VAR_1->entry, sizeof(*VAR_2)); if (!VAR_2)
return AVERROR(ENOMEM); } av_assert0(VAR_1->par->codec_id == AV_CODEC_ID_OPUS); for (VAR_5 = 0; VAR_5 < VAR_1->entry; VAR_5++) { int roll_samples_remaining = VAR_8; int distance = 0; for (VAR_6 = VAR_5 - 1; VAR_6 >= 0; VAR_6--) { roll_samples_remaining -= get_cluster_duration(VAR_1, VAR_6); distance++; if (roll_samples_remaining <= 0)
break; } if (roll_samples_remaining > 0)
distance = 0; av_assert0(distance == 0 || (distance >= 2 && distance <= 32)); if (VAR_5 && distance == VAR_2[VAR_3].roll_distance) { VAR_2[VAR_3].count++; } else { VAR_3++; VAR_2[VAR_3].count = 1; VAR_2[VAR_3].roll_distance = distance; VAR_2[VAR_3].group_description_index = distance ? ++VAR_4 : 0; } } VAR_3++; if (!VAR_4)
return 0; avio_wb32(VAR_0, 24 + (VAR_4 * 2)); ffio_wfourcc(VAR_0, "sgpd"); avio_wb32(VAR_0, 1 << 24); ffio_wfourcc(VAR_0, "roll"); avio_wb32(VAR_0, 2); avio_wb32(VAR_0, VAR_4); for (VAR_5 = 0; VAR_5 < VAR_3; VAR_5++) { if (VAR_2[VAR_5].group_description_index) { avio_wb16(VAR_0, -VAR_2[VAR_5].roll_distance); } } avio_wb32(VAR_0, 20 + (VAR_3 * 8)); ffio_wfourcc(VAR_0, "sbgp"); avio_wb32(VAR_0, 0); ffio_wfourcc(VAR_0, "roll"); avio_wb32(VAR_0, VAR_3); for (VAR_5 = 0; VAR_5 < VAR_3; VAR_5++) { avio_wb32(VAR_0, VAR_2[VAR_5].count); avio_wb32(VAR_0, VAR_2[VAR_5].group_description_index); } av_free(VAR_2); return 0; }