History

avformat/mov: merge stts and ctts arrays into one

Should reduce memory usage as well as remove code duplication.

James Almer committed 1 year ago

Commit 292c1df1 parent d7180a32 files · +249 −344Browse files

Showing the changes to libavformat (2 of 2 files). Show all

Unified · Split

2 files
  1. libavformat/isom.h +11 −4
  2. libavformat/mov.c +238 −340
libavformat/isom.h+11−4
@@ -54,6 +54,12 @@ struct AVAESCTR; · 53 unmodified lines
54 * Here we just use what is needed to read the chunks54 * Here we just use what is needed to read the chunks
55 */55 */
56 56
57typedef struct MOVTimeToSample {
58 unsigned int count;
59 unsigned int duration;
60 int offset;
61} MOVTimeToSample;
62
57typedef struct MOVStts {63typedef struct MOVStts {
58 unsigned int count;64 unsigned int count;
59 unsigned int duration;65 unsigned int duration;
@@ -173,6 +179,9 @@ typedef struct MOVStreamContext { · 113 unmodified lines
173 int next_chunk;179 int next_chunk;
174 unsigned int chunk_count;180 unsigned int chunk_count;
175 int64_t *chunk_offsets;181 int64_t *chunk_offsets;
182 unsigned int tts_count;
183 unsigned int tts_allocated_size;
184 MOVTimeToSample *tts_data;
176 unsigned int stts_count;185 unsigned int stts_count;
177 unsigned int stts_allocated_size;186 unsigned int stts_allocated_size;
178 MOVStts *stts_data;187 MOVStts *stts_data;
@@ -189,10 +198,8 @@ typedef struct MOVStreamContext { · 10 unmodified lines
189 unsigned *stps_data; ///< partial sync sample for mpeg-2 open gop198 unsigned *stps_data; ///< partial sync sample for mpeg-2 open gop
190 MOVElst *elst_data;199 MOVElst *elst_data;
191 unsigned int elst_count;200 unsigned int elst_count;
192 int stts_index;201 int tts_index;
193 int stts_sample;202 int tts_sample;
194 int ctts_index;
195 int ctts_sample;
196 unsigned int sample_size; ///< may contain value calculated from stsd or value from stsz atom203 unsigned int sample_size; ///< may contain value calculated from stsd or value from stsz atom
197 unsigned int stsz_sample_size; ///< always contains sample size from stsz atom204 unsigned int stsz_sample_size; ///< always contains sample size from stsz atom
198 unsigned int sample_count;205 unsigned int sample_count;
libavformat/mov.c+238−340
@@ -87,8 +87,6 @@ typedef struct MOVParseTableEntry { · 86 unmodified lines
87static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);87static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
88static int mov_read_mfra(MOVContext *c, AVIOContext *f);88static int mov_read_mfra(MOVContext *c, AVIOContext *f);
89static void mov_free_stream_context(AVFormatContext *s, AVStream *st);89static void mov_free_stream_context(AVFormatContext *s, AVStream *st);
90static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
91 int count, int duration);
92 90
93static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,91static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
94 unsigned len, const char *key)92 unsigned len, const char *key)
@@ -3666,6 +3664,12 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 3571 unmodified lines
3666 return AVERROR(ENOMEM);3664 return AVERROR(ENOMEM);
3667 3665
3668 for (i = 0; i < entries && !pb->eof_reached; i++) {3666 for (i = 0; i < entries && !pb->eof_reached; i++) {
3667 MOVCtts *ctts_data;
3668 const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3669 const size_t requested_size =
3670 min_size_needed > sc->ctts_allocated_size ?
3671 FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3672 min_size_needed;
3669 int count = avio_rb32(pb);3673 int count = avio_rb32(pb);
3670 int duration = avio_rb32(pb);3674 int duration = avio_rb32(pb);
3671 3675
@@ -3676,8 +3680,19 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 4 unmodified lines
3676 continue;3680 continue;
3677 }3681 }
3678 3682
3679 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,3683 if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3680 count, duration);3684 return AVERROR(ENOMEM);
3685
3686 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3687
3688 if (!ctts_data)
3689 return AVERROR(ENOMEM);
3690
3691 sc->ctts_data = ctts_data;
3692
3693 ctts_data[ctts_count].count = count;
3694 ctts_data[ctts_count].offset = duration;
3695 ctts_count++;
3681 3696
3682 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",3697 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3683 count, duration);3698 count, duration);
@@ -3871,24 +3886,19 @@ static int get_edit_list_entry(MOVContext *mov, · 187 unmodified lines
3871static int find_prev_closest_index(AVStream *st,3886static int find_prev_closest_index(AVStream *st,
3872 AVIndexEntry *e_old,3887 AVIndexEntry *e_old,
3873 int nb_old,3888 int nb_old,
3874 MOVStts* stts_data,3889 MOVTimeToSample *tts_data,
3875 int64_t stts_count,3890 int64_t tts_count,
3876 MOVCtts* ctts_data,
3877 int64_t ctts_count,
3878 int64_t timestamp_pts,3891 int64_t timestamp_pts,
3879 int flag,3892 int flag,
3880 int64_t* index,3893 int64_t* index,
3881 int64_t* stts_index,3894 int64_t* tts_index,
3882 int64_t* stts_sample,3895 int64_t* tts_sample)
3883 int64_t* ctts_index,
3884 int64_t* ctts_sample)
3885{3896{
3886 MOVStreamContext *msc = st->priv_data;3897 MOVStreamContext *msc = st->priv_data;
3887 FFStream *const sti = ffstream(st);3898 FFStream *const sti = ffstream(st);
3888 AVIndexEntry *e_keep = sti->index_entries;3899 AVIndexEntry *e_keep = sti->index_entries;
3889 int nb_keep = sti->nb_index_entries;3900 int nb_keep = sti->nb_index_entries;
3890 int64_t i = 0;3901 int64_t i = 0;
3891 int64_t index_ctts_count;
3892 3902
3893 av_assert0(index);3903 av_assert0(index);
3894 3904
@@ -3916,64 +3926,38 @@ static int find_prev_closest_index(AVStream *st, · 21 unmodified lines
3916 3926
3917 // If we have CTTS then refine the search, by searching backwards over PTS3927 // If we have CTTS then refine the search, by searching backwards over PTS
3918 // computed by adding corresponding CTTS durations to index timestamps.3928 // computed by adding corresponding CTTS durations to index timestamps.
3919 if (ctts_data && *index >= 0) {3929 if (msc->ctts_count && *index >= 0) {
3920 av_assert0(ctts_index);3930 av_assert0(tts_index);
3921 av_assert0(ctts_sample);3931 av_assert0(tts_sample);
3922 // Find out the ctts_index for the found frame.3932 // Find out the ctts_index for the found frame.
3923 *ctts_index = 0;3933 *tts_index = 0;
3924 *ctts_sample = 0;3934 *tts_sample = 0;
3925 3935 for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3926 if (stts_data) {3936 if (*tts_index < tts_count) {
3927 av_assert0(stts_index);3937 (*tts_sample)++;
3928 av_assert0(stts_sample);3938 if (tts_data[*tts_index].count == *tts_sample) {
3929 3939 (*tts_index)++;
3930 *stts_index = 0;3940 *tts_sample = 0;
3931 *stts_sample = 0;
3932 }
3933
3934 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3935 if (*ctts_index < ctts_count) {
3936 (*ctts_sample)++;
3937 if (ctts_data[*ctts_index].count == *ctts_sample) {
3938 (*ctts_index)++;
3939 *ctts_sample = 0;
3940 }
3941 }
3942 if (stts_data && *stts_index < stts_count) {
3943 (*stts_sample)++;
3944 if (stts_data[*stts_index].count == *stts_sample) {
3945 (*stts_index)++;
3946 *stts_sample = 0;
3947 }3941 }
3948 }3942 }
3949 }3943 }
3950 3944
3951 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {3945 while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3952 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).3946 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3953 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been3947 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3954 // compensated by dts_shift above.3948 // compensated by dts_shift above.
3955 if ((e_old[*index].timestamp + ctts_data[*ctts_index].offset) <= timestamp_pts &&3949 if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3956 (e_old[*index].flags & AVINDEX_KEYFRAME)) {3950 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3957 break;3951 break;
3958 }3952 }
3959 3953
3960 (*index)--;3954 (*index)--;
3961 if (*ctts_sample == 0) {3955 if (*tts_sample == 0) {
3962 (*ctts_index)--;3956 (*tts_index)--;
3963 if (*ctts_index >= 0)3957 if (*tts_index >= 0)
3964 *ctts_sample = ctts_data[*ctts_index].count - 1;3958 *tts_sample = tts_data[*tts_index].count - 1;
3965 } else {3959 } else {
3966 (*ctts_sample)--;3960 (*tts_sample)--;
3967 }
3968 if (stts_data) {
3969 if (*stts_sample == 0) {
3970 (*stts_index)--;
3971 if (*stts_index >= 0) {
3972 *stts_sample = stts_data[*stts_index].count - 1;
3973 }
3974 } else {
3975 (*stts_sample)--;
3976 }
3977 }3961 }
3978 }3962 }
3979 }3963 }
@@ -4048,62 +4032,32 @@ static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ · 68 unmodified lines
4048 }4032 }
4049}4033}
4050 4034
4051static int64_t add_stts_entry(MOVStts** stts_data, unsigned int* stts_count, unsigned int* allocated_size,4035static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4052 int count, int duration)4036 int count, int offset, unsigned int duration)
4053{
4054 MOVStts *stts_buf_new;
4055 const size_t min_size_needed = (*stts_count + 1) * sizeof(MOVStts);
4056 const size_t requested_size =
4057 min_size_needed > *allocated_size ?
4058 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4059 min_size_needed;
4060
4061 if ((unsigned)(*stts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
4062 return -1;
4063
4064 stts_buf_new = av_fast_realloc(*stts_data, allocated_size, requested_size);
4065
4066 if (!stts_buf_new)
4067 return -1;
4068
4069 *stts_data = stts_buf_new;
4070
4071 stts_buf_new[*stts_count].count = count;
4072 stts_buf_new[*stts_count].duration = duration;
4073
4074 *stts_count = (*stts_count) + 1;
4075 return *stts_count;
4076}
4077
4078/**
4079 * Append a new ctts entry to ctts_data.
4080 * Returns the new ctts_count if successful, else returns -1.
4081 */
4082static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
4083 int count, int offset)
4084{4037{
4085 MOVCtts *ctts_buf_new;4038 MOVTimeToSample *tts_buf_new;
4086 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);4039 const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4087 const size_t requested_size =4040 const size_t requested_size =
4088 min_size_needed > *allocated_size ?4041 min_size_needed > *allocated_size ?
4089 FFMAX(min_size_needed, 2 * (*allocated_size)) :4042 FFMAX(min_size_needed, 2 * (*allocated_size)) :
4090 min_size_needed;4043 min_size_needed;
4091 4044
4092 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)4045 if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4093 return -1;4046 return -1;
4094 4047
4095 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);4048 tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4096 4049
4097 if (!ctts_buf_new)4050 if (!tts_buf_new)
4098 return -1;4051 return -1;
4099 4052
4100 *ctts_data = ctts_buf_new;4053 *tts_data = tts_buf_new;
4101 4054
4102 ctts_buf_new[*ctts_count].count = count;4055 tts_buf_new[*tts_count].count = count;
4103 ctts_buf_new[*ctts_count].offset = offset;4056 tts_buf_new[*tts_count].offset = offset;
4057 tts_buf_new[*tts_count].duration = duration;
4104 4058
4105 *ctts_count = (*ctts_count) + 1;4059 *tts_count = (*tts_count) + 1;
4106 return *ctts_count;4060 return 0;
4107}4061}
4108 4062
4109#define MAX_REORDER_DELAY 164063#define MAX_REORDER_DELAY 16
@@ -4120,17 +4074,17 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st) · 10 unmodified lines
4120 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)4074 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4121 pts_buf[j] = INT64_MIN;4075 pts_buf[j] = INT64_MIN;
4122 4076
4123 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&4077 if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4124 st->codecpar->codec_id == AV_CODEC_ID_H264) {4078 st->codecpar->codec_id == AV_CODEC_ID_H264) {
4125 st->codecpar->video_delay = 0;4079 st->codecpar->video_delay = 0;
4126 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {4080 for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4127 // Point j to the last elem of the buffer and insert the current pts there.4081 // Point j to the last elem of the buffer and insert the current pts there.
4128 j = buf_start;4082 j = buf_start;
4129 buf_start = (buf_start + 1);4083 buf_start = (buf_start + 1);
4130 if (buf_start == MAX_REORDER_DELAY + 1)4084 if (buf_start == MAX_REORDER_DELAY + 1)
4131 buf_start = 0;4085 buf_start = 0;
4132 4086
4133 pts_buf[j] = sti->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].offset;4087 pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4134 4088
4135 // The timestamps that are already in the sorted buffer, and are greater than the4089 // The timestamps that are already in the sorted buffer, and are greater than the
4136 // current pts, are exactly the timestamps that need to be buffered to output PTS4090 // current pts, are exactly the timestamps that need to be buffered to output PTS
@@ -4153,7 +4107,7 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st) · 16 unmodified lines
4153 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);4107 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4154 4108
4155 ctts_sample++;4109 ctts_sample++;
4156 if (ctts_sample == msc->ctts_data[ctts_ind].count) {4110 if (ctts_sample == msc->tts_data[ctts_ind].count) {
4157 ctts_ind++;4111 ctts_ind++;
4158 ctts_sample = 0;4112 ctts_sample = 0;
4159 }4113 }
@@ -4223,21 +4177,16 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 63 unmodified lines
4223 int nb_old = sti->nb_index_entries;4177 int nb_old = sti->nb_index_entries;
4224 const AVIndexEntry *e_old_end = e_old + nb_old;4178 const AVIndexEntry *e_old_end = e_old + nb_old;
4225 const AVIndexEntry *current = NULL;4179 const AVIndexEntry *current = NULL;
4226 MOVStts *stts_data_old = msc->stts_data;4180 MOVTimeToSample *tts_data_old = msc->tts_data;
4227 int64_t stts_index_old = 0;4181 int64_t tts_index_old = 0;
4228 int64_t stts_sample_old = 0;4182 int64_t tts_sample_old = 0;
4229 int64_t stts_count_old = msc->stts_count;4183 int64_t tts_count_old = msc->tts_count;
4230 MOVCtts *ctts_data_old = msc->ctts_data;
4231 int64_t ctts_index_old = 0;
4232 int64_t ctts_sample_old = 0;
4233 int64_t ctts_count_old = msc->ctts_count;
4234 int64_t edit_list_media_time = 0;4184 int64_t edit_list_media_time = 0;
4235 int64_t edit_list_duration = 0;4185 int64_t edit_list_duration = 0;
4236 int64_t frame_duration = 0;4186 int64_t frame_duration = 0;
4237 int64_t edit_list_dts_counter = 0;4187 int64_t edit_list_dts_counter = 0;
4238 int64_t edit_list_dts_entry_end = 0;4188 int64_t edit_list_dts_entry_end = 0;
4239 int64_t edit_list_start_stts_sample = 0;4189 int64_t edit_list_start_tts_sample = 0;
4240 int64_t edit_list_start_ctts_sample = 0;
4241 int64_t curr_cts;4190 int64_t curr_cts;
4242 int64_t curr_ctts = 0;4191 int64_t curr_ctts = 0;
4243 int64_t empty_edits_sum_duration = 0;4192 int64_t empty_edits_sum_duration = 0;
@@ -4274,16 +4223,11 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 30 unmodified lines
4274 sti->nb_index_entries = 0;4223 sti->nb_index_entries = 0;
4275 4224
4276 // Clean time to sample fields of MOVStreamContext4225 // Clean time to sample fields of MOVStreamContext
4277 msc->stts_data = NULL;4226 msc->tts_data = NULL;
4278 msc->stts_count = 0;4227 msc->tts_count = 0;
4279 msc->stts_index = 0;4228 msc->tts_index = 0;
4280 msc->stts_sample = 0;4229 msc->tts_sample = 0;
4281 msc->stts_allocated_size = 0;4230 msc->tts_allocated_size = 0;
4282 msc->ctts_data = NULL;
4283 msc->ctts_count = 0;
4284 msc->ctts_index = 0;
4285 msc->ctts_sample = 0;
4286 msc->ctts_allocated_size = 0;
4287 4231
4288 // Reinitialize min_corrected_pts so that it can be computed again.4232 // Reinitialize min_corrected_pts so that it can be computed again.
4289 msc->min_corrected_pts = -1;4233 msc->min_corrected_pts = -1;
@@ -4336,26 +4280,23 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 46 unmodified lines
4336 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);4280 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4337 }4281 }
4338 4282
4339 if (find_prev_closest_index(st, e_old, nb_old, stts_data_old, stts_count_old, ctts_data_old, ctts_count_old, search_timestamp, 0,4283 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4340 &index, &stts_index_old, &stts_sample_old, &ctts_index_old, &ctts_sample_old) < 0) {4284 &index, &tts_index_old, &tts_sample_old) < 0) {
4341 av_log(mov->fc, AV_LOG_WARNING,4285 av_log(mov->fc, AV_LOG_WARNING,
4342 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",4286 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4343 st->index, edit_list_index, search_timestamp);4287 st->index, edit_list_index, search_timestamp);
4344 if (find_prev_closest_index(st, e_old, nb_old, stts_data_old, stts_count_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,4288 if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4345 &index, &stts_index_old, &stts_sample_old, &ctts_index_old, &ctts_sample_old) < 0) {4289 &index, &tts_index_old, &tts_sample_old) < 0) {
4346 av_log(mov->fc, AV_LOG_WARNING,4290 av_log(mov->fc, AV_LOG_WARNING,
4347 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",4291 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4348 st->index, edit_list_index, search_timestamp);4292 st->index, edit_list_index, search_timestamp);
4349 index = 0;4293 index = 0;
4350 stts_index_old = 0;4294 tts_index_old = 0;
4351 stts_sample_old = 0;4295 tts_sample_old = 0;
4352 ctts_index_old = 0;
4353 ctts_sample_old = 0;
4354 }4296 }
4355 }4297 }
4356 current = e_old + index;4298 current = e_old + index;
4357 edit_list_start_ctts_sample = ctts_sample_old;4299 edit_list_start_tts_sample = tts_sample_old;
4358 edit_list_start_stts_sample = stts_sample_old;
4359 4300
4360 // Iterate over index and arrange it according to edit list4301 // Iterate over index and arrange it according to edit list
4361 edit_list_start_encountered = 0;4302 edit_list_start_encountered = 0;
@@ -4371,44 +4312,26 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 9 unmodified lines
4371 curr_cts = current->timestamp + msc->dts_shift;4312 curr_cts = current->timestamp + msc->dts_shift;
4372 curr_ctts = 0;4313 curr_ctts = 0;
4373 4314
4374 if (stts_data_old && stts_index_old < stts_count_old) {4315 if (tts_data_old && tts_index_old < tts_count_old) {
4375 stts_sample_old++;4316 curr_ctts = tts_data_old[tts_index_old].offset;
4376 if (stts_sample_old == stts_data_old[stts_index_old].count) {4317 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4377 if (add_stts_entry(&msc->stts_data, &msc->stts_count,4318 curr_cts, curr_ctts, tts_index_old, tts_count_old);
4378 &msc->stts_allocated_size,
4379 stts_data_old[stts_index_old].count - edit_list_start_stts_sample,
4380 stts_data_old[stts_index_old].duration) == -1) {
4381 av_log(mov->fc, AV_LOG_ERROR, "Cannot add STTS entry %"PRId64" - {%"PRId64", %d}\n",
4382 stts_index_old,
4383 stts_data_old[stts_index_old].count - edit_list_start_stts_sample,
4384 stts_data_old[stts_index_old].duration);
4385 break;
4386 }
4387 stts_index_old++;
4388 stts_sample_old = 0;
4389 edit_list_start_stts_sample = 0;
4390 }
4391 }
4392 if (ctts_data_old && ctts_index_old < ctts_count_old) {
4393 curr_ctts = ctts_data_old[ctts_index_old].offset;
4394 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
4395 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
4396 curr_cts += curr_ctts;4319 curr_cts += curr_ctts;
4397 ctts_sample_old++;4320 tts_sample_old++;
4398 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {4321 if (tts_sample_old == tts_data_old[tts_index_old].count) {
4399 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,4322 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4400 &msc->ctts_allocated_size,4323 &msc->tts_allocated_size,
4401 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,4324 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4402 ctts_data_old[ctts_index_old].offset) == -1) {4325 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4403 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",4326 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4404 ctts_index_old,4327 tts_index_old,
4405 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,4328 tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4406 ctts_data_old[ctts_index_old].offset);4329 tts_data_old[tts_index_old].offset);
4407 break;4330 break;
4408 }4331 }
4409 ctts_index_old++;4332 tts_index_old++;
4410 ctts_sample_old = 0;4333 tts_sample_old = 0;
4411 edit_list_start_ctts_sample = 0;4334 edit_list_start_tts_sample = 0;
4412 }4335 }
4413 }4336 }
4414 4337
@@ -4494,7 +4417,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 79 unmodified lines
4494 // Break when found first key frame after edit entry completion4417 // Break when found first key frame after edit entry completion
4495 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&4418 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4496 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {4419 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
4497 if (ctts_data_old) {4420 if (msc->ctts_count) {
4498 // If we have CTTS and this is the first keyframe after edit elist,4421 // If we have CTTS and this is the first keyframe after edit elist,
4499 // wait for one more, because there might be trailing B-frames after this I-frame4422 // wait for one more, because there might be trailing B-frames after this I-frame
4500 // that do belong to the edit.4423 // that do belong to the edit.
@@ -4502,24 +4425,14 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 1 unmodified line
4502 found_keyframe_after_edit = 1;4425 found_keyframe_after_edit = 1;
4503 continue;4426 continue;
4504 }4427 }
4505 if (ctts_sample_old != 0) {4428 if (tts_sample_old != 0) {
4506 if (stts_data_old &&4429 if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4507 add_stts_entry(&msc->stts_data, &msc->stts_count,4430 &msc->tts_allocated_size,
4508 &msc->stts_allocated_size,4431 tts_sample_old - edit_list_start_tts_sample,
4509 stts_sample_old - edit_list_start_stts_sample,4432 tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4510 stts_data_old[stts_index_old].duration) == -1) {4433 av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4511 av_log(mov->fc, AV_LOG_ERROR, "Cannot add STTS entry %"PRId64" - {%"PRId64", %d}\n",4434 tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4512 stts_index_old, stts_sample_old - edit_list_start_stts_sample,4435 tts_data_old[tts_index_old].offset);
4513 stts_data_old[stts_index_old].duration);
4514 break;
4515 }
4516 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4517 &msc->ctts_allocated_size,
4518 ctts_sample_old - edit_list_start_ctts_sample,
4519 ctts_data_old[ctts_index_old].offset) == -1) {
4520 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4521 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
4522 ctts_data_old[ctts_index_old].offset);
4523 break;4436 break;
4524 }4437 }
4525 }4438 }
@@ -4550,8 +4463,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 24 unmodified lines
4550 4463
4551 // Free the old index and the old CTTS structures4464 // Free the old index and the old CTTS structures
4552 av_free(e_old);4465 av_free(e_old);
4553 av_free(stts_data_old);4466 av_free(tts_data_old);
4554 av_free(ctts_data_old);
4555 av_freep(&frame_duration_buffer);4467 av_freep(&frame_duration_buffer);
4556 4468
4557 // Null terminate the index ranges array4469 // Null terminate the index ranges array
@@ -4633,6 +4545,76 @@ static int build_open_gop_key_points(AVStream *st) · 75 unmodified lines
4633 return 0;4545 return 0;
4634}4546}
4635 4547
4548#define MOV_MERGE_CTTS 1
4549#define MOV_MERGE_STTS 2
4550/*
4551 * Merge stts and ctts arrays into a new combined array.
4552 * stts_count and ctts_count may be left untouched as they will be
4553 * used to check for the presence of either of them.
4554 */
4555static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4556{
4557 MOVStreamContext *sc = st->priv_data;
4558 int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4559 int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4560 int idx = 0;
4561
4562 if (!sc->ctts_data && !sc->stts_data)
4563 return 0;
4564 // Expand time to sample entries such that we have a 1-1 mapping with samples
4565 if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4566 return -1;
4567
4568 if (ctts) {
4569 sc->tts_data = av_fast_realloc(NULL, &sc->tts_allocated_size,
4570 sc->sample_count * sizeof(*sc->tts_data));
4571 if (!sc->tts_data)
4572 return -1;
4573
4574 memset(sc->tts_data, 0, sc->tts_allocated_size);
4575
4576 for (int i = 0; i < sc->ctts_count &&
4577 idx < sc->sample_count; i++)
4578 for (int j = 0; j < sc->ctts_data[i].count &&
4579 idx < sc->sample_count; j++) {
4580 sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4581 sc->tts_data[idx++].count = 1;
4582 }
4583
4584 sc->tts_count = idx;
4585 } else
4586 sc->ctts_count = 0;
4587 av_freep(&sc->ctts_data);
4588 sc->ctts_allocated_size = 0;
4589
4590 idx = 0;
4591 if (stts) {
4592 MOVTimeToSample *tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
4593 sc->sample_count * sizeof(*sc->tts_data));
4594 if (!tts_data)
4595 return -1;
4596
4597 if (!sc->tts_data)
4598 memset(tts_data, 0, sc->tts_allocated_size);
4599 sc->tts_data = tts_data;
4600
4601 for (int i = 0; i < sc->stts_count &&
4602 idx < sc->sample_count; i++)
4603 for (int j = 0; j < sc->stts_data[i].count &&
4604 idx < sc->sample_count; j++) {
4605 sc->tts_data[idx].duration = sc->stts_data[i].duration;
4606 sc->tts_data[idx++].count = 1;
4607 }
4608
4609 sc->tts_count = FFMAX(sc->tts_count, idx);
4610 } else
4611 sc->stts_count = 0;
4612 av_freep(&sc->stts_data);
4613 sc->stts_allocated_size = 0;
4614
4615 return 0;
4616}
4617
4636static void mov_build_index(MOVContext *mov, AVStream *st)4618static void mov_build_index(MOVContext *mov, AVStream *st)
4637{4619{
4638 MOVStreamContext *sc = st->priv_data;4620 MOVStreamContext *sc = st->priv_data;
@@ -4645,10 +4627,6 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 6 unmodified lines
4645 unsigned int stps_index = 0;4627 unsigned int stps_index = 0;
4646 unsigned int i, j;4628 unsigned int i, j;
4647 uint64_t stream_size = 0;4629 uint64_t stream_size = 0;
4648 MOVStts *stts_data_old = sc->stts_data;
4649 MOVCtts *ctts_data_old = sc->ctts_data;
4650 unsigned int stts_count_old = sc->stts_count;
4651 unsigned int ctts_count_old = sc->ctts_count;
4652 4630
4653 int ret = build_open_gop_key_points(st);4631 int ret = build_open_gop_key_points(st);
4654 if (ret < 0)4632 if (ret < 0)
@@ -4728,54 +4706,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 73 unmodified lines
4728 }4706 }
4729 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);4707 sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4730 4708
4731 if (ctts_data_old) {4709 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS | MOV_MERGE_STTS);
4732 // Expand ctts entries such that we have a 1-1 mapping with samples4710 if (ret < 0)
4733 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))4711 return;
4734 return;
4735 sc->ctts_count = 0;
4736 sc->ctts_allocated_size = 0;
4737 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
4738 sc->sample_count * sizeof(*sc->ctts_data));
4739 if (!sc->ctts_data) {
4740 av_free(ctts_data_old);
4741 return;
4742 }
4743
4744 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
4745
4746 for (i = 0; i < ctts_count_old &&
4747 sc->ctts_count < sc->sample_count; i++)
4748 for (j = 0; j < ctts_data_old[i].count &&
4749 sc->ctts_count < sc->sample_count; j++)
4750 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
4751 &sc->ctts_allocated_size, 1,
4752 ctts_data_old[i].offset);
4753 av_free(ctts_data_old);
4754 }
4755 if (stts_data_old) {
4756 // Expand stts entries such that we have a 1-1 mapping with samples
4757 if (sc->sample_count >= UINT_MAX / sizeof(*sc->stts_data))
4758 return;
4759 sc->stts_count = 0;
4760 sc->stts_allocated_size = 0;
4761 sc->stts_data = av_fast_realloc(NULL, &sc->stts_allocated_size,
4762 sc->sample_count * sizeof(*sc->stts_data));
4763 if (!sc->stts_data) {
4764 av_free(stts_data_old);
4765 return;
4766 }
4767
4768 memset((uint8_t*)(sc->stts_data), 0, sc->stts_allocated_size);
4769
4770 for (i = 0; i < stts_count_old &&
4771 sc->stts_count < sc->sample_count; i++)
4772 for (j = 0; j < stts_data_old[i].count &&
4773 sc->stts_count < sc->sample_count; j++)
4774 add_stts_entry(&sc->stts_data, &sc->stts_count,
4775 &sc->stts_allocated_size, 1,
4776 stts_data_old[i].duration);
4777 av_free(stts_data_old);
4778 }
4779 4712
4780 for (i = 0; i < sc->chunk_count; i++) {4713 for (i = 0; i < sc->chunk_count; i++) {
4781 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;4714 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
@@ -4856,12 +4789,12 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 74 unmodified lines
4856 current_offset += sample_size;4789 current_offset += sample_size;
4857 stream_size += sample_size;4790 stream_size += sample_size;
4858 4791
4859 current_dts += sc->stts_data[stts_index].duration;4792 current_dts += sc->tts_data[stts_index].duration;
4860 4793
4861 distance++;4794 distance++;
4862 stts_sample++;4795 stts_sample++;
4863 current_sample++;4796 current_sample++;
4864 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {4797 if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4865 stts_sample = 0;4798 stts_sample = 0;
4866 stts_index++;4799 stts_index++;
4867 }4800 }
@@ -4872,6 +4805,10 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 4 unmodified lines
4872 } else {4805 } else {
4873 unsigned chunk_samples, total = 0;4806 unsigned chunk_samples, total = 0;
4874 4807
4808 ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS);
4809 if (ret < 0)
4810 return;
4811
4875 if (!sc->chunk_count)4812 if (!sc->chunk_count)
4876 return;4813 return;
4877 4814
@@ -4979,8 +4916,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 101 unmodified lines
4979 // Update start time of the stream.4916 // Update start time of the stream.
4980 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries > 0) {4917 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries > 0) {
4981 st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;4918 st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4982 if (sc->ctts_data) {4919 if (sc->tts_data) {
4983 st->start_time += sc->ctts_data[0].offset;4920 st->start_time += sc->tts_data[0].offset;
4984 }4921 }
4985 }4922 }
4986 4923
@@ -5254,14 +5191,14 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 267 unmodified lines
5254 }5191 }
5255 5192
5256#if FF_API_R_FRAME_RATE5193#if FF_API_R_FRAME_RATE
5257 for (int i = 1; sc->stts_count && i < sc->stts_count - 1; i++) {5194 for (int i = 1; sc->stts_count && i < sc->tts_count - 1; i++) {
5258 if (sc->stts_data[i].duration == sc->stts_data[0].duration)5195 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5259 continue;5196 continue;
5260 stts_constant = 0;5197 stts_constant = 0;
5261 }5198 }
5262 if (stts_constant)5199 if (stts_constant)
5263 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,5200 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
5264 sc->time_scale, sc->stts_data[0].duration, INT_MAX);5201 sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5265#endif5202#endif
5266 }5203 }
5267 5204
@@ -5292,8 +5229,8 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 24 unmodified lines
5292 if (st->codecpar->codec_id == AV_CODEC_ID_MP35229 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5293 && sc->time_scale == st->codecpar->sample_rate) {5230 && sc->time_scale == st->codecpar->sample_rate) {
5294 int stts_constant = 1;5231 int stts_constant = 1;
5295 for (int i = 1; i < sc->stts_count; i++) {5232 for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5296 if (sc->stts_data[i].duration == sc->stts_data[0].duration)5233 if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5297 continue;5234 continue;
5298 stts_constant = 0;5235 stts_constant = 0;
5299 }5236 }
@@ -5776,8 +5713,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 476 unmodified lines
5776 AVStream *st = NULL;5713 AVStream *st = NULL;
5777 FFStream *sti = NULL;5714 FFStream *sti = NULL;
5778 MOVStreamContext *sc;5715 MOVStreamContext *sc;
5779 MOVStts *stts_data;5716 MOVTimeToSample *tts_data;
5780 MOVCtts *ctts_data;
5781 uint64_t offset;5717 uint64_t offset;
5782 int64_t dts, pts = AV_NOPTS_VALUE;5718 int64_t dts, pts = AV_NOPTS_VALUE;
5783 int data_offset = 0;5719 int data_offset = 0;
@@ -5833,7 +5769,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 49 unmodified lines
5833 entries = avio_rb32(pb);5769 entries = avio_rb32(pb);
5834 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);5770 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5835 5771
5836 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))5772 if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5837 return AVERROR_INVALIDDATA;5773 return AVERROR_INVALIDDATA;
5838 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);5774 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5839 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);5775 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
@@ -5906,52 +5842,39 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 66 unmodified lines
5906 return AVERROR(ENOMEM);5842 return AVERROR(ENOMEM);
5907 sti->index_entries= new_entries;5843 sti->index_entries= new_entries;
5908 5844
5909 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data);5845 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5910 old_allocated_size = sc->ctts_allocated_size;5846 old_allocated_size = sc->tts_allocated_size;
5911 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,5847 tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5912 requested_size);5848 requested_size);
5913 if (!ctts_data)5849 if (!tts_data)
5914 return AVERROR(ENOMEM);5850 return AVERROR(ENOMEM);
5915 sc->ctts_data = ctts_data;5851 sc->tts_data = tts_data;
5916 5852
5917 // In case there were samples without ctts entries, ensure they get5853 // In case there were samples without time to sample entries, ensure they get
5918 // zero valued entries. This ensures clips which mix boxes with and5854 // zero valued entries. This ensures clips which mix boxes with and
5919 // without ctts entries don't pickup uninitialized data.5855 // without time to sample entries don't pickup uninitialized data.
5920 memset((uint8_t*)(sc->ctts_data) + old_allocated_size, 0,5856 memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5921 sc->ctts_allocated_size - old_allocated_size);5857 sc->tts_allocated_size - old_allocated_size);
5922
5923 requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->stts_data);
5924 old_allocated_size = sc->stts_allocated_size;
5925 stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
5926 requested_size);
5927 if (!stts_data)
5928 return AVERROR(ENOMEM);
5929 sc->stts_data = stts_data;
5930
5931 // See the comment for ctts above.
5932 memset((uint8_t*)(sc->stts_data) + old_allocated_size, 0,
5933 sc->stts_allocated_size - old_allocated_size);
5934 5858
5935 if (index_entry_pos < sti->nb_index_entries) {5859 if (index_entry_pos < sti->nb_index_entries) {
5936 // Make hole in index_entries and ctts_data for new samples5860 // Make hole in index_entries and tts_data for new samples
5937 memmove(sti->index_entries + index_entry_pos + entries,5861 memmove(sti->index_entries + index_entry_pos + entries,
5938 sti->index_entries + index_entry_pos,5862 sti->index_entries + index_entry_pos,
5939 sizeof(*sti->index_entries) *5863 sizeof(*sti->index_entries) *
5940 (sti->nb_index_entries - index_entry_pos));5864 (sti->nb_index_entries - index_entry_pos));
5941 memmove(sc->ctts_data + index_entry_pos + entries,5865 memmove(sc->tts_data + index_entry_pos + entries,
5942 sc->ctts_data + index_entry_pos,5866 sc->tts_data + index_entry_pos,
5943 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));5867 sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5944 memmove(sc->stts_data + index_entry_pos + entries,
5945 sc->stts_data + index_entry_pos,
5946 sizeof(*sc->stts_data) * (sc->stts_count - index_entry_pos));
5947 if (index_entry_pos < sc->current_sample) {5868 if (index_entry_pos < sc->current_sample) {
5948 sc->current_sample += entries;5869 sc->current_sample += entries;
5949 }5870 }
5950 }5871 }
5951 5872
5952 sti->nb_index_entries += entries;5873 sti->nb_index_entries += entries;
5953 sc->ctts_count = sti->nb_index_entries;5874 sc->tts_count = sti->nb_index_entries;
5954 sc->stts_count = sti->nb_index_entries;5875 sc->stts_count = sti->nb_index_entries;
5876 if (flags & MOV_TRUN_SAMPLE_CTS)
5877 sc->ctts_count = sti->nb_index_entries;
5955 5878
5956 // Record the index_entry position in frag_index of this fragment5879 // Record the index_entry position in frag_index of this fragment
5957 if (frag_stream_info) {5880 if (frag_stream_info) {
@@ -6013,10 +5936,9 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 55 unmodified lines
6013 sti->index_entries[index_entry_pos].min_distance = distance;5936 sti->index_entries[index_entry_pos].min_distance = distance;
6014 sti->index_entries[index_entry_pos].flags = index_entry_flags;5937 sti->index_entries[index_entry_pos].flags = index_entry_flags;
6015 5938
6016 sc->ctts_data[index_entry_pos].count = 1;5939 sc->tts_data[index_entry_pos].count = 1;
6017 sc->ctts_data[index_entry_pos].offset = ctts_duration;5940 sc->tts_data[index_entry_pos].offset = ctts_duration;
6018 sc->stts_data[index_entry_pos].count = 1;5941 sc->tts_data[index_entry_pos].duration = sample_duration;
6019 sc->stts_data[index_entry_pos].duration = sample_duration;
6020 index_entry_pos++;5942 index_entry_pos++;
6021 5943
6022 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "5944 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
@@ -6042,24 +5964,19 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 19 unmodified lines
6042 frag_stream_info->next_trun_dts = dts + sc->time_offset;5964 frag_stream_info->next_trun_dts = dts + sc->time_offset;
6043 if (i < entries) {5965 if (i < entries) {
6044 // EOF found before reading all entries. Fix the hole this would5966 // EOF found before reading all entries. Fix the hole this would
6045 // leave in index_entries and ctts_data5967 // leave in index_entries and tts_data
6046 int gap = entries - i;5968 int gap = entries - i;
6047 memmove(sti->index_entries + index_entry_pos,5969 memmove(sti->index_entries + index_entry_pos,
6048 sti->index_entries + index_entry_pos + gap,5970 sti->index_entries + index_entry_pos + gap,
6049 sizeof(*sti->index_entries) *5971 sizeof(*sti->index_entries) *
6050 (sti->nb_index_entries - (index_entry_pos + gap)));5972 (sti->nb_index_entries - (index_entry_pos + gap)));
6051 memmove(sc->ctts_data + index_entry_pos,5973 memmove(sc->tts_data + index_entry_pos,
6052 sc->ctts_data + index_entry_pos + gap,5974 sc->tts_data + index_entry_pos + gap,
6053 sizeof(*sc->ctts_data) *5975 sizeof(*sc->tts_data) *
6054 (sc->ctts_count - (index_entry_pos + gap)));5976 (sc->tts_count - (index_entry_pos + gap)));
6055 memmove(sc->stts_data + index_entry_pos,
6056 sc->stts_data + index_entry_pos + gap,
6057 sizeof(*sc->stts_data) *
6058 (sc->stts_count - (index_entry_pos + gap)));
6059 5977
6060 sti->nb_index_entries -= gap;5978 sti->nb_index_entries -= gap;
6061 sc->ctts_count -= gap;5979 sc->tts_count -= gap;
6062 sc->stts_count -= gap;
6063 if (index_entry_pos < sc->current_sample) {5980 if (index_entry_pos < sc->current_sample) {
6064 sc->current_sample -= gap;5981 sc->current_sample -= gap;
6065 }5982 }
@@ -9821,7 +9738,7 @@ static void mov_free_stream_context(AVFormatContext *s, AVStream *st) · 3755 unmodified lines
9821 return;9738 return;
9822 }9739 }
9823 9740
9824 av_freep(&sc->ctts_data);9741 av_freep(&sc->tts_data);
9825 for (int i = 0; i < sc->drefs_count; i++) {9742 for (int i = 0; i < sc->drefs_count; i++) {
9826 av_freep(&sc->drefs[i].path);9743 av_freep(&sc->drefs[i].path);
9827 av_freep(&sc->drefs[i].dir);9744 av_freep(&sc->drefs[i].dir);
@@ -9838,6 +9755,7 @@ static void mov_free_stream_context(AVFormatContext *s, AVStream *st) · 10 unmodified lines
9838 av_freep(&sc->stsc_data);9755 av_freep(&sc->stsc_data);
9839 av_freep(&sc->sample_sizes);9756 av_freep(&sc->sample_sizes);
9840 av_freep(&sc->keyframes);9757 av_freep(&sc->keyframes);
9758 av_freep(&sc->ctts_data);
9841 av_freep(&sc->stts_data);9759 av_freep(&sc->stts_data);
9842 av_freep(&sc->sdtp_data);9760 av_freep(&sc->sdtp_data);
9843 av_freep(&sc->stps_data);9761 av_freep(&sc->stps_data);
@@ -10859,27 +10777,10 @@ static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *s · 1015 unmodified lines
10859 if (sample->flags & AVINDEX_DISCARD_FRAME) {10777 if (sample->flags & AVINDEX_DISCARD_FRAME) {
10860 pkt->flags |= AV_PKT_FLAG_DISCARD;10778 pkt->flags |= AV_PKT_FLAG_DISCARD;
10861 }10779 }
10862 if (sc->stts_data && sc->stts_index < sc->stts_count) {10780 if (sc->stts_count && sc->tts_index < sc->tts_count)
10863 pkt->duration = sc->stts_data[sc->stts_index].duration;10781 pkt->duration = sc->tts_data[sc->tts_index].duration;
10864 10782 if (sc->ctts_count && sc->tts_index < sc->tts_count) {
10865 /* update stts context */10783 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset));
10866 sc->stts_sample++;
10867 if (sc->stts_index < sc->stts_count &&
10868 sc->stts_data[sc->stts_index].count == sc->stts_sample) {
10869 sc->stts_index++;
10870 sc->stts_sample = 0;
10871 }
10872 }
10873 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
10874 pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->ctts_data[sc->ctts_index].offset));
10875
10876 /* update ctts context */
10877 sc->ctts_sample++;
10878 if (sc->ctts_index < sc->ctts_count &&
10879 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
10880 sc->ctts_index++;
10881 sc->ctts_sample = 0;
10882 }
10883 } else {10784 } else {
10884 if (pkt->duration == 0) {10785 if (pkt->duration == 0) {
10885 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?10786 int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
@@ -10890,6 +10791,16 @@ static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *s · 4 unmodified lines
10890 pkt->pts = pkt->dts;10791 pkt->pts = pkt->dts;
10891 }10792 }
10892 10793
10794 if (sc->tts_data && sc->tts_index < sc->tts_count) {
10795 /* update tts context */
10796 sc->tts_sample++;
10797 if (sc->tts_index < sc->tts_count &&
10798 sc->tts_data[sc->tts_index].count == sc->tts_sample) {
10799 sc->tts_index++;
10800 sc->tts_sample = 0;
10801 }
10802 }
10803
10893 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {10804 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
10894 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];10805 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
10895 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;10806 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
@@ -10952,7 +10863,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) · 56 unmodified lines
10952 10863
10953 // Clear current sample10864 // Clear current sample
10954 mov_current_sample_set(msc, 0);10865 mov_current_sample_set(msc, 0);
10955 msc->ctts_index = 0;10866 msc->tts_index = 0;
10956 10867
10957 // Discard current index entries10868 // Discard current index entries
10958 avsti = ffstream(avst);10869 avsti = ffstream(avst);
@@ -11185,27 +11096,14 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, · 226 unmodified lines
11185 11096
11186 mov_current_sample_set(sc, sample);11097 mov_current_sample_set(sc, sample);
11187 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);11098 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11188 /* adjust stts index */11099 /* adjust time to sample index */
11189 if (sc->stts_data) {11100 if (sc->tts_data) {
11190 time_sample = 0;
11191 for (i = 0; i < sc->stts_count; i++) {
11192 int next = time_sample + sc->stts_data[i].count;
11193 if (next > sc->current_sample) {
11194 sc->stts_index = i;
11195 sc->stts_sample = sc->current_sample - time_sample;
11196 break;
11197 }
11198 time_sample = next;
11199 }
11200 }
11201 /* adjust ctts index */
11202 if (sc->ctts_data) {
11203 time_sample = 0;11101 time_sample = 0;
11204 for (i = 0; i < sc->ctts_count; i++) {11102 for (i = 0; i < sc->tts_count; i++) {
11205 int next = time_sample + sc->ctts_data[i].count;11103 int next = time_sample + sc->tts_data[i].count;
11206 if (next > sc->current_sample) {11104 if (next > sc->current_sample) {
11207 sc->ctts_index = i;11105 sc->tts_index = i;
11208 sc->ctts_sample = sc->current_sample - time_sample;11106 sc->tts_sample = sc->current_sample - time_sample;
11209 break;11107 break;
11210 }11108 }
11211 time_sample = next;11109 time_sample = next;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t