From 9c61dd225cb45e8489c7a024fe8b483aef9e1c24 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Mon, 31 Jul 2017 15:15:58 -0700
Subject: [PATCH] [mov] Remove concept of ctts entries with count > 1.

Previous ctts patches have all changed the system to always using
count=1 since we expect ctts data to be 1:1 with samples. This deletes
the concept of count>1 samples for clarity and performance.

Signed-off-by: Dale Curtis <dalecurtis@chromium.org>
---
 libavformat/isom.h |   3 +-
 libavformat/mov.c  | 110 ++++++++++++-----------------------------------------
 2 files changed, 25 insertions(+), 88 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index fdd98c28f5..67cdbaf008 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -138,7 +138,7 @@ typedef struct MOVStreamContext {
     MOVStts *stts_data;
     unsigned int ctts_count;
     unsigned int ctts_allocated_size;
-    MOVStts *ctts_data;
+    int *ctts_data;  ///< dts offset for each pts value. 1:1 with samples.
     unsigned int stsc_count;
     MOVStsc *stsc_data;
     int stsc_index;
@@ -148,7 +148,6 @@ typedef struct MOVStreamContext {
     MOVElst *elst_data;
     unsigned int elst_count;
     int ctts_index;
-    int ctts_sample;
     unsigned int sample_size; ///< may contain value calculated from stsd or value from stsz atom
     unsigned int stsz_sample_size; ///< always contains sample size from stsz atom
     unsigned int sample_count;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 89b2af7597..4a962e570a 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -74,8 +74,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,
-                              int count, int duration);
+static int64_t add_ctts_entry(int** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size, int duration);
 
 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
                                              unsigned len, const char *key)
@@ -2748,7 +2747,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
         /* Expand entries such that we have a 1-1 mapping with samples. */
         for (j = 0; j < count; j++)
-            add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size, 1, duration);
+            add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size, duration);
 
         av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
                 count, duration);
@@ -2947,30 +2946,24 @@ 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,
-                              int count, int duration)
+static int64_t add_ctts_entry(int** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size, int duration)
 {
-    MOVStts *ctts_buf_new;
-    const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
+    int *ctts_buf_new;
+    const size_t min_size_needed = (*ctts_count + 1) * sizeof(*ctts_buf_new);
     const size_t requested_size =
         min_size_needed > *allocated_size ?
         FFMAX(min_size_needed, 2 * (*allocated_size)) :
         min_size_needed;
 
-    if((unsigned)(*ctts_count) + 1 >= UINT_MAX / sizeof(MOVStts))
+    if ((unsigned)(*ctts_count) + 1 >= UINT_MAX / sizeof(*ctts_buf_new))
         return -1;
 
     ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
-
-    if(!ctts_buf_new)
+    if (!ctts_buf_new)
         return -1;
 
     *ctts_data = ctts_buf_new;
-
-    ctts_buf_new[*ctts_count].count = count;
-    ctts_buf_new[*ctts_count].duration = duration;
-
-    *ctts_count = (*ctts_count) + 1;
+    ctts_buf_new[(*ctts_count)++] = duration;
     return *ctts_count;
 }
 
@@ -3033,23 +3026,20 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
     int nb_old = st->nb_index_entries;
     const AVIndexEntry *e_old_end = e_old + nb_old;
     const AVIndexEntry *current = NULL;
-    MOVStts *ctts_data_old = msc->ctts_data;
+    int *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;
     int64_t edit_list_media_time = 0;
     int64_t edit_list_duration = 0;
     int64_t frame_duration = 0;
     int64_t edit_list_dts_counter = 0;
     int64_t edit_list_dts_entry_end = 0;
-    int64_t edit_list_start_ctts_sample = 0;
     int64_t curr_cts;
     int64_t curr_ctts = 0;
     int64_t min_corrected_pts = -1;
     int64_t empty_edits_sum_duration = 0;
     int64_t edit_list_index = 0;
     int64_t index;
-    int64_t index_ctts_count;
     int flags;
     int64_t start_dts = 0;
     int64_t edit_list_media_time_dts = 0;
@@ -3084,7 +3074,6 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
     msc->ctts_data = NULL;
     msc->ctts_count = 0;
     msc->ctts_index = 0;
-    msc->ctts_sample = 0;
     msc->ctts_allocated_size = 0;
 
     // If the dts_shift is positive (in case of negative ctts values in mov),
@@ -3158,21 +3147,8 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
         }
         current = e_old + index;
 
-        ctts_index_old = 0;
-        ctts_sample_old = 0;
-
         // set ctts_index properly for the found key frame
-        for (index_ctts_count = 0; index_ctts_count < index; index_ctts_count++) {
-            if (ctts_data_old && ctts_index_old < ctts_count_old) {
-                ctts_sample_old++;
-                if (ctts_data_old[ctts_index_old].count == ctts_sample_old) {
-                    ctts_index_old++;
-                    ctts_sample_old = 0;
-                }
-            }
-        }
-
-        edit_list_start_ctts_sample = ctts_sample_old;
+        ctts_index_old = FFMIN(ctts_count_old, index);
 
         // Iterate over index and arrange it according to edit list
         edit_list_start_encountered = 0;
@@ -3188,26 +3164,19 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
             curr_ctts = 0;
 
             if (ctts_data_old && ctts_index_old < ctts_count_old) {
-                curr_ctts = ctts_data_old[ctts_index_old].duration;
+                curr_ctts = ctts_data_old[ctts_index_old];
                 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
                        curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
                 curr_cts += curr_ctts;
-                ctts_sample_old++;
-                if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
-                    if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
-                                       &msc->ctts_allocated_size,
-                                       ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
-                                       ctts_data_old[ctts_index_old].duration) == -1) {
-                        av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
-                               ctts_index_old,
-                               ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
-                               ctts_data_old[ctts_index_old].duration);
-                        break;
-                    }
-                    ctts_index_old++;
-                    ctts_sample_old = 0;
-                    edit_list_start_ctts_sample = 0;
+                if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
+                                   &msc->ctts_allocated_size,
+                                   ctts_data_old[ctts_index_old]) == -1) {
+                    av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%d}\n",
+                           ctts_index_old,
+                           ctts_data_old[ctts_index_old]);
+                    break;
                 }
+                ctts_index_old++;
             }
 
             if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
@@ -3291,18 +3260,6 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
             // Break when found first key frame after edit entry completion
             if (((curr_cts + frame_duration) >= (edit_list_duration + edit_list_media_time)) &&
                 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
-
-                if (ctts_data_old && ctts_sample_old != 0) {
-                    if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
-                                       &msc->ctts_allocated_size,
-                                       ctts_sample_old - edit_list_start_ctts_sample,
-                                       ctts_data_old[ctts_index_old].duration) == -1) {
-                        av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
-                               ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
-                               ctts_data_old[ctts_index_old].duration);
-                        break;
-                    }
-                }
                 break;
             }
         }
@@ -4260,7 +4217,6 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     MOVFragment *frag = &c->fragment;
     AVStream *st = NULL;
     MOVStreamContext *sc;
-    MOVStts *ctts_data;
     uint64_t offset;
     int64_t dts;
     int data_offset = 0;
@@ -4346,7 +4302,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             unsigned int request_size = size_needed > sc->ctts_allocated_size ?
                 FFMAX(size_needed, 2 * sc->ctts_allocated_size) : size_needed;
             unsigned int old_ctts_size = sc->ctts_allocated_size;
-            ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, request_size);
+            int *ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, request_size);
             if (!ctts_data) {
                 av_freep(&sc->ctts_data);
                 return AVERROR(ENOMEM);
@@ -4368,8 +4324,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
                 }
             }
 
-            sc->ctts_data[ctts_index].count = 1;
-            sc->ctts_data[ctts_index].duration = ctts_duration;
+            sc->ctts_data[ctts_index] = ctts_duration;
             sc->ctts_count++;
         } else {
             av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
@@ -6552,14 +6507,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
         pkt->flags |= AV_PKT_FLAG_DISCARD;
     }
     if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
-        pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
-        /* update ctts context */
-        sc->ctts_sample++;
-        if (sc->ctts_index < sc->ctts_count &&
-            sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
-            sc->ctts_index++;
-            sc->ctts_sample = 0;
-        }
+        pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index++];
     } else {
         int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
             st->index_entries[sc->current_sample].timestamp : st->duration;
@@ -6648,18 +6596,8 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
     mov_current_sample_set(sc, sample);
     av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
     /* adjust ctts index */
-    if (sc->ctts_data) {
-        time_sample = 0;
-        for (i = 0; i < sc->ctts_count; i++) {
-            int next = time_sample + sc->ctts_data[i].count;
-            if (next > sc->current_sample) {
-                sc->ctts_index = i;
-                sc->ctts_sample = sc->current_sample - time_sample;
-                break;
-            }
-            time_sample = next;
-        }
-    }
+    if (sc->ctts_data)
+        sc->ctts_index = sc->current_sample;
 
     /* adjust stsd index */
     time_sample = 0;
-- 
2.14.1.342.g6490525c54-goog

