[FFmpeg-devel] [PATCH] avformat/mov: make STTS duration unsigned int

Gyan Doshi ffmpeg at gyani.pro
Fri Nov 19 18:02:43 EET 2021


Plan to push Monday afternoon.

On 2021-11-16 07:45 pm, Gyan Doshi wrote:
> As per 8.6.1.2.2 of ISO/IEC 14496-12:2015(E), STTS sample offsets
> are to be always stored as uint32_t. So far, they have been signed ints
> which led to desync in files with very large offsets.
>
> The MOVStts struct was used to store CTTS offsets as well. These can be
> negative in version 1. So a new struct MOVCtts was created and all
> declarations for CTTS usage changed to MOVCtts.
> ---
> The muxer should be adjusted to be able to write larger durations in the
> stts but that's a larger undertaking which I'll do later.
>
>   libavformat/isom.h   |  9 +++++++--
>   libavformat/mov.c    | 20 ++++++++++----------
>   libavformat/movenc.c |  2 +-
>   3 files changed, 18 insertions(+), 13 deletions(-)
>
> diff --git a/libavformat/isom.h b/libavformat/isom.h
> index f3c18c95be..ef8f19b18c 100644
> --- a/libavformat/isom.h
> +++ b/libavformat/isom.h
> @@ -55,9 +55,14 @@ struct AVAESCTR;
>   
>   typedef struct MOVStts {
>       unsigned int count;
> -    int duration;
> +    unsigned int duration;
>   } MOVStts;
>   
> +typedef struct MOVCtts {
> +    unsigned int count;
> +    int duration;
> +} MOVCtts;
> +
>   typedef struct MOVStsc {
>       int first;
>       int count;
> @@ -168,7 +173,7 @@ typedef struct MOVStreamContext {
>       uint8_t *sdtp_data;
>       unsigned int ctts_count;
>       unsigned int ctts_allocated_size;
> -    MOVStts *ctts_data;
> +    MOVCtts *ctts_data;
>       unsigned int stsc_count;
>       MOVStsc *stsc_data;
>       unsigned int stsc_index;
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 8a910a3165..451cb78bbf 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -77,7 +77,7 @@ typedef struct MOVParseTableEntry {
>   
>   static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
>   static int mov_read_mfra(MOVContext *c, AVIOContext *f);
> -static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
> +static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
>                                 int count, int duration);
>   
>   static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
> @@ -2938,7 +2938,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>           return AVERROR(ENOMEM);
>   
>       for (i = 0; i < entries && !pb->eof_reached; i++) {
> -        int sample_duration;
> +        unsigned int sample_duration;
>           unsigned int sample_count;
>           unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
>           MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
> @@ -3191,7 +3191,7 @@ static int get_edit_list_entry(MOVContext *mov,
>   static int find_prev_closest_index(AVStream *st,
>                                      AVIndexEntry *e_old,
>                                      int nb_old,
> -                                   MOVStts* ctts_data,
> +                                   MOVCtts* ctts_data,
>                                      int64_t ctts_count,
>                                      int64_t timestamp_pts,
>                                      int flag,
> @@ -3342,17 +3342,17 @@ static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_
>    * Append a new ctts entry to ctts_data.
>    * Returns the new ctts_count if successful, else returns -1.
>    */
> -static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
> +static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
>                                 int count, int duration)
>   {
> -    MOVStts *ctts_buf_new;
> -    const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
> +    MOVCtts *ctts_buf_new;
> +    const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);
>       const size_t requested_size =
>           min_size_needed > *allocated_size ?
>           FFMAX(min_size_needed, 2 * (*allocated_size)) :
>           min_size_needed;
>   
> -    if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
> +    if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)
>           return -1;
>   
>       ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
> @@ -3486,7 +3486,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
>       int nb_old = sti->nb_index_entries;
>       const AVIndexEntry *e_old_end = e_old + nb_old;
>       const AVIndexEntry *current = NULL;
> -    MOVStts *ctts_data_old = msc->ctts_data;
> +    MOVCtts *ctts_data_old = msc->ctts_data;
>       int64_t ctts_index_old = 0;
>       int64_t ctts_sample_old = 0;
>       int64_t ctts_count_old = msc->ctts_count;
> @@ -3793,7 +3793,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
>       unsigned int stps_index = 0;
>       unsigned int i, j;
>       uint64_t stream_size = 0;
> -    MOVStts *ctts_data_old = sc->ctts_data;
> +    MOVCtts *ctts_data_old = sc->ctts_data;
>       unsigned int ctts_count_old = sc->ctts_count;
>   
>       if (sc->elst_count) {
> @@ -4754,7 +4754,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>       AVStream *st = NULL;
>       FFStream *sti = NULL;
>       MOVStreamContext *sc;
> -    MOVStts *ctts_data;
> +    MOVCtts *ctts_data;
>       uint64_t offset;
>       int64_t dts, pts = AV_NOPTS_VALUE;
>       int data_offset = 0;
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index 37d4403f7a..233aee62d4 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -2434,7 +2434,7 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
>   static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
>   {
>       MOVMuxContext *mov = s->priv_data;
> -    MOVStts *ctts_entries;
> +    MOVCtts *ctts_entries;
>       uint32_t entries = 0;
>       uint32_t atom_size;
>       int i;



More information about the ffmpeg-devel mailing list