Should reduce memory usage as well as remove code duplication.
Unified · Split
| @@ -54,6 +54,12 @@ struct AVAESCTR; · 53 unmodified lines | ||
| 54 | 54 | * Here we just use what is needed to read the chunks |
| 55 | 55 | */ |
| 56 | 56 | |
| 57 | +typedef struct MOVTimeToSample { | |
| 58 | + unsigned int count; | |
| 59 | + unsigned int duration; | |
| 60 | + int offset; | |
| 61 | +} MOVTimeToSample; | |
| 62 | + | |
| 57 | 63 | typedef struct MOVStts { |
| 58 | 64 | unsigned int count; |
| 59 | 65 | unsigned int duration; |
| @@ -173,6 +179,9 @@ typedef struct MOVStreamContext { · 113 unmodified lines | ||
| 173 | 179 | int next_chunk; |
| 174 | 180 | unsigned int chunk_count; |
| 175 | 181 | int64_t *chunk_offsets; |
| 182 | + unsigned int tts_count; | |
| 183 | + unsigned int tts_allocated_size; | |
| 184 | + MOVTimeToSample *tts_data; | |
| 176 | 185 | unsigned int stts_count; |
| 177 | 186 | unsigned int stts_allocated_size; |
| 178 | 187 | MOVStts *stts_data; |
| @@ -189,10 +198,8 @@ typedef struct MOVStreamContext { · 10 unmodified lines | ||
| 189 | 198 | unsigned *stps_data; ///< partial sync sample for mpeg-2 open gop |
| 190 | 199 | MOVElst *elst_data; |
| 191 | 200 | unsigned int elst_count; |
| 192 | − int stts_index; | |
| 193 | − int stts_sample; | |
| 194 | − int ctts_index; | |
| 195 | − int ctts_sample; | |
| 201 | + int tts_index; | |
| 202 | + int tts_sample; | |
| 196 | 203 | unsigned int sample_size; ///< may contain value calculated from stsd or value from stsz atom |
| 197 | 204 | unsigned int stsz_sample_size; ///< always contains sample size from stsz atom |
| 198 | 205 | unsigned int sample_count; |
| @@ -87,8 +87,6 @@ typedef struct MOVParseTableEntry { · 86 unmodified lines | ||
| 87 | 87 | static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom); |
| 88 | 88 | static int mov_read_mfra(MOVContext *c, AVIOContext *f); |
| 89 | 89 | static void mov_free_stream_context(AVFormatContext *s, AVStream *st); |
| 90 | −static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size, | |
| 91 | − int count, int duration); | |
| 92 | 90 | |
| 93 | 91 | static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, |
| 94 | 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 | 3664 | return AVERROR(ENOMEM); |
| 3667 | 3665 | |
| 3668 | 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 | 3673 | int count = avio_rb32(pb); |
| 3670 | 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 | 3680 | continue; |
| 3677 | 3681 | } |
| 3678 | 3682 | |
| 3679 | − add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size, | |
| 3680 | − count, duration); | |
| 3683 | + if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1) | |
| 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 | 3697 | av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n", |
| 3683 | 3698 | count, duration); |
| @@ -3871,24 +3886,19 @@ static int get_edit_list_entry(MOVContext *mov, · 187 unmodified lines | ||
| 3871 | 3886 | static int find_prev_closest_index(AVStream *st, |
| 3872 | 3887 | AVIndexEntry *e_old, |
| 3873 | 3888 | int nb_old, |
| 3874 | − MOVStts* stts_data, | |
| 3875 | − int64_t stts_count, | |
| 3876 | − MOVCtts* ctts_data, | |
| 3877 | − int64_t ctts_count, | |
| 3889 | + MOVTimeToSample *tts_data, | |
| 3890 | + int64_t tts_count, | |
| 3878 | 3891 | int64_t timestamp_pts, |
| 3879 | 3892 | int flag, |
| 3880 | 3893 | int64_t* index, |
| 3881 | − int64_t* stts_index, | |
| 3882 | − int64_t* stts_sample, | |
| 3883 | − int64_t* ctts_index, | |
| 3884 | − int64_t* ctts_sample) | |
| 3894 | + int64_t* tts_index, | |
| 3895 | + int64_t* tts_sample) | |
| 3885 | 3896 | { |
| 3886 | 3897 | MOVStreamContext *msc = st->priv_data; |
| 3887 | 3898 | FFStream *const sti = ffstream(st); |
| 3888 | 3899 | AVIndexEntry *e_keep = sti->index_entries; |
| 3889 | 3900 | int nb_keep = sti->nb_index_entries; |
| 3890 | 3901 | int64_t i = 0; |
| 3891 | − int64_t index_ctts_count; | |
| 3892 | 3902 | |
| 3893 | 3903 | av_assert0(index); |
| 3894 | 3904 | |
| @@ -3916,64 +3926,38 @@ static int find_prev_closest_index(AVStream *st, · 21 unmodified lines | ||
| 3916 | 3926 | |
| 3917 | 3927 | // If we have CTTS then refine the search, by searching backwards over PTS |
| 3918 | 3928 | // computed by adding corresponding CTTS durations to index timestamps. |
| 3919 | − if (ctts_data && *index >= 0) { | |
| 3920 | − av_assert0(ctts_index); | |
| 3921 | − av_assert0(ctts_sample); | |
| 3929 | + if (msc->ctts_count && *index >= 0) { | |
| 3930 | + av_assert0(tts_index); | |
| 3931 | + av_assert0(tts_sample); | |
| 3922 | 3932 | // Find out the ctts_index for the found frame. |
| 3923 | − *ctts_index = 0; | |
| 3924 | − *ctts_sample = 0; | |
| 3925 | − | |
| 3926 | − if (stts_data) { | |
| 3927 | − av_assert0(stts_index); | |
| 3928 | − av_assert0(stts_sample); | |
| 3929 | − | |
| 3930 | − *stts_index = 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; | |
| 3933 | + *tts_index = 0; | |
| 3934 | + *tts_sample = 0; | |
| 3935 | + for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) { | |
| 3936 | + if (*tts_index < tts_count) { | |
| 3937 | + (*tts_sample)++; | |
| 3938 | + if (tts_data[*tts_index].count == *tts_sample) { | |
| 3939 | + (*tts_index)++; | |
| 3940 | + *tts_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 | 3946 | // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly). |
| 3953 | 3947 | // No need to add dts_shift to the timestamp here becase timestamp_pts has already been |
| 3954 | 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 | 3950 | (e_old[*index].flags & AVINDEX_KEYFRAME)) { |
| 3957 | 3951 | break; |
| 3958 | 3952 | } |
| 3959 | 3953 | |
| 3960 | 3954 | (*index)--; |
| 3961 | − if (*ctts_sample == 0) { | |
| 3962 | − (*ctts_index)--; | |
| 3963 | − if (*ctts_index >= 0) | |
| 3964 | − *ctts_sample = ctts_data[*ctts_index].count - 1; | |
| 3955 | + if (*tts_sample == 0) { | |
| 3956 | + (*tts_index)--; | |
| 3957 | + if (*tts_index >= 0) | |
| 3958 | + *tts_sample = tts_data[*tts_index].count - 1; | |
| 3965 | 3959 | } else { |
| 3966 | − (*ctts_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 | − } | |
| 3960 | + (*tts_sample)--; | |
| 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 | |
| 4051 | −static int64_t add_stts_entry(MOVStts** stts_data, unsigned int* stts_count, unsigned int* allocated_size, | |
| 4052 | − int count, 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 | − */ | |
| 4082 | −static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size, | |
| 4083 | − int count, int offset) | |
| 4035 | +static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, | |
| 4036 | + int count, int offset, unsigned int duration) | |
| 4084 | 4037 | { |
| 4085 | − MOVCtts *ctts_buf_new; | |
| 4086 | − const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts); | |
| 4038 | + MOVTimeToSample *tts_buf_new; | |
| 4039 | + const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample); | |
| 4087 | 4040 | const size_t requested_size = |
| 4088 | 4041 | min_size_needed > *allocated_size ? |
| 4089 | 4042 | FFMAX(min_size_needed, 2 * (*allocated_size)) : |
| 4090 | 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 | 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 | 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; | |
| 4103 | − ctts_buf_new[*ctts_count].offset = offset; | |
| 4055 | + tts_buf_new[*tts_count].count = count; | |
| 4056 | + tts_buf_new[*tts_count].offset = offset; | |
| 4057 | + tts_buf_new[*tts_count].duration = duration; | |
| 4104 | 4058 | |
| 4105 | − *ctts_count = (*ctts_count) + 1; | |
| 4106 | − return *ctts_count; | |
| 4059 | + *tts_count = (*tts_count) + 1; | |
| 4060 | + return 0; | |
| 4107 | 4061 | } |
| 4108 | 4062 | |
| 4109 | 4063 | #define MAX_REORDER_DELAY 16 |
| @@ -4120,17 +4074,17 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st) · 10 unmodified lines | ||
| 4120 | 4074 | for (j = 0; j < MAX_REORDER_DELAY + 1; j++) |
| 4121 | 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 | 4078 | st->codecpar->codec_id == AV_CODEC_ID_H264) { |
| 4125 | 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 | 4081 | // Point j to the last elem of the buffer and insert the current pts there. |
| 4128 | 4082 | j = buf_start; |
| 4129 | 4083 | buf_start = (buf_start + 1); |
| 4130 | 4084 | if (buf_start == MAX_REORDER_DELAY + 1) |
| 4131 | 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 | 4089 | // The timestamps that are already in the sorted buffer, and are greater than the |
| 4136 | 4090 | // 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 | 4107 | st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps); |
| 4154 | 4108 | |
| 4155 | 4109 | ctts_sample++; |
| 4156 | − if (ctts_sample == msc->ctts_data[ctts_ind].count) { | |
| 4110 | + if (ctts_sample == msc->tts_data[ctts_ind].count) { | |
| 4157 | 4111 | ctts_ind++; |
| 4158 | 4112 | ctts_sample = 0; |
| 4159 | 4113 | } |
| @@ -4223,21 +4177,16 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 63 unmodified lines | ||
| 4223 | 4177 | int nb_old = sti->nb_index_entries; |
| 4224 | 4178 | const AVIndexEntry *e_old_end = e_old + nb_old; |
| 4225 | 4179 | const AVIndexEntry *current = NULL; |
| 4226 | − MOVStts *stts_data_old = msc->stts_data; | |
| 4227 | − int64_t stts_index_old = 0; | |
| 4228 | − int64_t stts_sample_old = 0; | |
| 4229 | − int64_t stts_count_old = msc->stts_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; | |
| 4180 | + MOVTimeToSample *tts_data_old = msc->tts_data; | |
| 4181 | + int64_t tts_index_old = 0; | |
| 4182 | + int64_t tts_sample_old = 0; | |
| 4183 | + int64_t tts_count_old = msc->tts_count; | |
| 4234 | 4184 | int64_t edit_list_media_time = 0; |
| 4235 | 4185 | int64_t edit_list_duration = 0; |
| 4236 | 4186 | int64_t frame_duration = 0; |
| 4237 | 4187 | int64_t edit_list_dts_counter = 0; |
| 4238 | 4188 | int64_t edit_list_dts_entry_end = 0; |
| 4239 | − int64_t edit_list_start_stts_sample = 0; | |
| 4240 | − int64_t edit_list_start_ctts_sample = 0; | |
| 4189 | + int64_t edit_list_start_tts_sample = 0; | |
| 4241 | 4190 | int64_t curr_cts; |
| 4242 | 4191 | int64_t curr_ctts = 0; |
| 4243 | 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 | 4223 | sti->nb_index_entries = 0; |
| 4275 | 4224 | |
| 4276 | 4225 | // Clean time to sample fields of MOVStreamContext |
| 4277 | − msc->stts_data = NULL; | |
| 4278 | − msc->stts_count = 0; | |
| 4279 | − msc->stts_index = 0; | |
| 4280 | − msc->stts_sample = 0; | |
| 4281 | − msc->stts_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; | |
| 4226 | + msc->tts_data = NULL; | |
| 4227 | + msc->tts_count = 0; | |
| 4228 | + msc->tts_index = 0; | |
| 4229 | + msc->tts_sample = 0; | |
| 4230 | + msc->tts_allocated_size = 0; | |
| 4287 | 4231 | |
| 4288 | 4232 | // Reinitialize min_corrected_pts so that it can be computed again. |
| 4289 | 4233 | msc->min_corrected_pts = -1; |
| @@ -4336,26 +4280,23 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 46 unmodified lines | ||
| 4336 | 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, | |
| 4340 | − &index, &stts_index_old, &stts_sample_old, &ctts_index_old, &ctts_sample_old) < 0) { | |
| 4283 | + if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0, | |
| 4284 | + &index, &tts_index_old, &tts_sample_old) < 0) { | |
| 4341 | 4285 | av_log(mov->fc, AV_LOG_WARNING, |
| 4342 | 4286 | "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n", |
| 4343 | 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, | |
| 4345 | − &index, &stts_index_old, &stts_sample_old, &ctts_index_old, &ctts_sample_old) < 0) { | |
| 4288 | + if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY, | |
| 4289 | + &index, &tts_index_old, &tts_sample_old) < 0) { | |
| 4346 | 4290 | av_log(mov->fc, AV_LOG_WARNING, |
| 4347 | 4291 | "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n", |
| 4348 | 4292 | st->index, edit_list_index, search_timestamp); |
| 4349 | 4293 | index = 0; |
| 4350 | − stts_index_old = 0; | |
| 4351 | − stts_sample_old = 0; | |
| 4352 | − ctts_index_old = 0; | |
| 4353 | − ctts_sample_old = 0; | |
| 4294 | + tts_index_old = 0; | |
| 4295 | + tts_sample_old = 0; | |
| 4354 | 4296 | } |
| 4355 | 4297 | } |
| 4356 | 4298 | current = e_old + index; |
| 4357 | − edit_list_start_ctts_sample = ctts_sample_old; | |
| 4358 | − edit_list_start_stts_sample = stts_sample_old; | |
| 4299 | + edit_list_start_tts_sample = tts_sample_old; | |
| 4359 | 4300 | |
| 4360 | 4301 | // Iterate over index and arrange it according to edit list |
| 4361 | 4302 | edit_list_start_encountered = 0; |
| @@ -4371,44 +4312,26 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 9 unmodified lines | ||
| 4371 | 4312 | curr_cts = current->timestamp + msc->dts_shift; |
| 4372 | 4313 | curr_ctts = 0; |
| 4373 | 4314 | |
| 4374 | − if (stts_data_old && stts_index_old < stts_count_old) { | |
| 4375 | − stts_sample_old++; | |
| 4376 | − if (stts_sample_old == stts_data_old[stts_index_old].count) { | |
| 4377 | − if (add_stts_entry(&msc->stts_data, &msc->stts_count, | |
| 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); | |
| 4315 | + if (tts_data_old && tts_index_old < tts_count_old) { | |
| 4316 | + curr_ctts = tts_data_old[tts_index_old].offset; | |
| 4317 | + av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n", | |
| 4318 | + curr_cts, curr_ctts, tts_index_old, tts_count_old); | |
| 4396 | 4319 | curr_cts += curr_ctts; |
| 4397 | − ctts_sample_old++; | |
| 4398 | − if (ctts_sample_old == ctts_data_old[ctts_index_old].count) { | |
| 4399 | − if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count, | |
| 4400 | − &msc->ctts_allocated_size, | |
| 4401 | − ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample, | |
| 4402 | − ctts_data_old[ctts_index_old].offset) == -1) { | |
| 4403 | − av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n", | |
| 4404 | − ctts_index_old, | |
| 4405 | − ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample, | |
| 4406 | − ctts_data_old[ctts_index_old].offset); | |
| 4320 | + tts_sample_old++; | |
| 4321 | + if (tts_sample_old == tts_data_old[tts_index_old].count) { | |
| 4322 | + if (add_tts_entry(&msc->tts_data, &msc->tts_count, | |
| 4323 | + &msc->tts_allocated_size, | |
| 4324 | + tts_data_old[tts_index_old].count - edit_list_start_tts_sample, | |
| 4325 | + tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) { | |
| 4326 | + av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n", | |
| 4327 | + tts_index_old, | |
| 4328 | + tts_data_old[tts_index_old].count - edit_list_start_tts_sample, | |
| 4329 | + tts_data_old[tts_index_old].offset); | |
| 4407 | 4330 | break; |
| 4408 | 4331 | } |
| 4409 | − ctts_index_old++; | |
| 4410 | − ctts_sample_old = 0; | |
| 4411 | − edit_list_start_ctts_sample = 0; | |
| 4332 | + tts_index_old++; | |
| 4333 | + tts_sample_old = 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 | 4417 | // Break when found first key frame after edit entry completion |
| 4495 | 4418 | if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) && |
| 4496 | 4419 | ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) { |
| 4497 | − if (ctts_data_old) { | |
| 4420 | + if (msc->ctts_count) { | |
| 4498 | 4421 | // If we have CTTS and this is the first keyframe after edit elist, |
| 4499 | 4422 | // wait for one more, because there might be trailing B-frames after this I-frame |
| 4500 | 4423 | // that do belong to the edit. |
| @@ -4502,24 +4425,14 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) · 1 unmodified line | ||
| 4502 | 4425 | found_keyframe_after_edit = 1; |
| 4503 | 4426 | continue; |
| 4504 | 4427 | } |
| 4505 | − if (ctts_sample_old != 0) { | |
| 4506 | − if (stts_data_old && | |
| 4507 | − add_stts_entry(&msc->stts_data, &msc->stts_count, | |
| 4508 | − &msc->stts_allocated_size, | |
| 4509 | − stts_sample_old - edit_list_start_stts_sample, | |
| 4510 | − stts_data_old[stts_index_old].duration) == -1) { | |
| 4511 | − av_log(mov->fc, AV_LOG_ERROR, "Cannot add STTS entry %"PRId64" - {%"PRId64", %d}\n", | |
| 4512 | − stts_index_old, stts_sample_old - edit_list_start_stts_sample, | |
| 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); | |
| 4428 | + if (tts_sample_old != 0) { | |
| 4429 | + if (add_tts_entry(&msc->tts_data, &msc->tts_count, | |
| 4430 | + &msc->tts_allocated_size, | |
| 4431 | + tts_sample_old - edit_list_start_tts_sample, | |
| 4432 | + tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) { | |
| 4433 | + av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n", | |
| 4434 | + tts_index_old, tts_sample_old - edit_list_start_tts_sample, | |
| 4435 | + tts_data_old[tts_index_old].offset); | |
| 4523 | 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 | 4464 | // Free the old index and the old CTTS structures |
| 4552 | 4465 | av_free(e_old); |
| 4553 | − av_free(stts_data_old); | |
| 4554 | − av_free(ctts_data_old); | |
| 4466 | + av_free(tts_data_old); | |
| 4555 | 4467 | av_freep(&frame_duration_buffer); |
| 4556 | 4468 | |
| 4557 | 4469 | // Null terminate the index ranges array |
| @@ -4633,6 +4545,76 @@ static int build_open_gop_key_points(AVStream *st) · 75 unmodified lines | ||
| 4633 | 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 | + */ | |
| 4555 | +static 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 | + | |
| 4636 | 4618 | static void mov_build_index(MOVContext *mov, AVStream *st) |
| 4637 | 4619 | { |
| 4638 | 4620 | MOVStreamContext *sc = st->priv_data; |
| @@ -4645,10 +4627,6 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 6 unmodified lines | ||
| 4645 | 4627 | unsigned int stps_index = 0; |
| 4646 | 4628 | unsigned int i, j; |
| 4647 | 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 | 4631 | int ret = build_open_gop_key_points(st); |
| 4654 | 4632 | if (ret < 0) |
| @@ -4728,54 +4706,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 73 unmodified lines | ||
| 4728 | 4706 | } |
| 4729 | 4707 | sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries); |
| 4730 | 4708 | |
| 4731 | − if (ctts_data_old) { | |
| 4732 | − // Expand ctts entries such that we have a 1-1 mapping with samples | |
| 4733 | − if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data)) | |
| 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 | − } | |
| 4709 | + ret = mov_merge_tts_data(mov, st, MOV_MERGE_CTTS | MOV_MERGE_STTS); | |
| 4710 | + if (ret < 0) | |
| 4711 | + return; | |
| 4779 | 4712 | |
| 4780 | 4713 | for (i = 0; i < sc->chunk_count; i++) { |
| 4781 | 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 | 4789 | current_offset += sample_size; |
| 4857 | 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 | 4794 | distance++; |
| 4862 | 4795 | stts_sample++; |
| 4863 | 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 | 4798 | stts_sample = 0; |
| 4866 | 4799 | stts_index++; |
| 4867 | 4800 | } |
| @@ -4872,6 +4805,10 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 4 unmodified lines | ||
| 4872 | 4805 | } else { |
| 4873 | 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 | 4812 | if (!sc->chunk_count) |
| 4876 | 4813 | return; |
| 4877 | 4814 | |
| @@ -4979,8 +4916,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st) · 101 unmodified lines | ||
| 4979 | 4916 | // Update start time of the stream. |
| 4980 | 4917 | if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries > 0) { |
| 4981 | 4918 | st->start_time = sti->index_entries[0].timestamp + sc->dts_shift; |
| 4982 | − if (sc->ctts_data) { | |
| 4983 | − st->start_time += sc->ctts_data[0].offset; | |
| 4919 | + if (sc->tts_data) { | |
| 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 | 5193 | #if FF_API_R_FRAME_RATE |
| 5257 | − for (int i = 1; sc->stts_count && i < sc->stts_count - 1; i++) { | |
| 5258 | − if (sc->stts_data[i].duration == sc->stts_data[0].duration) | |
| 5194 | + for (int i = 1; sc->stts_count && i < sc->tts_count - 1; i++) { | |
| 5195 | + if (sc->tts_data[i].duration == sc->tts_data[0].duration) | |
| 5259 | 5196 | continue; |
| 5260 | 5197 | stts_constant = 0; |
| 5261 | 5198 | } |
| 5262 | 5199 | if (stts_constant) |
| 5263 | 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 | 5202 | #endif |
| 5266 | 5203 | } |
| 5267 | 5204 | |
| @@ -5292,8 +5229,8 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 24 unmodified lines | ||
| 5292 | 5229 | if (st->codecpar->codec_id == AV_CODEC_ID_MP3 |
| 5293 | 5230 | && sc->time_scale == st->codecpar->sample_rate) { |
| 5294 | 5231 | int stts_constant = 1; |
| 5295 | − for (int i = 1; i < sc->stts_count; i++) { | |
| 5296 | − if (sc->stts_data[i].duration == sc->stts_data[0].duration) | |
| 5232 | + for (int i = 1; sc->stts_count && i < sc->tts_count; i++) { | |
| 5233 | + if (sc->tts_data[i].duration == sc->tts_data[0].duration) | |
| 5297 | 5234 | continue; |
| 5298 | 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 | 5713 | AVStream *st = NULL; |
| 5777 | 5714 | FFStream *sti = NULL; |
| 5778 | 5715 | MOVStreamContext *sc; |
| 5779 | − MOVStts *stts_data; | |
| 5780 | − MOVCtts *ctts_data; | |
| 5716 | + MOVTimeToSample *tts_data; | |
| 5781 | 5717 | uint64_t offset; |
| 5782 | 5718 | int64_t dts, pts = AV_NOPTS_VALUE; |
| 5783 | 5719 | int data_offset = 0; |
| @@ -5833,7 +5769,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 49 unmodified lines | ||
| 5833 | 5769 | entries = avio_rb32(pb); |
| 5834 | 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 | 5773 | return AVERROR_INVALIDDATA; |
| 5838 | 5774 | if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb); |
| 5839 | 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 | 5842 | return AVERROR(ENOMEM); |
| 5907 | 5843 | sti->index_entries= new_entries; |
| 5908 | 5844 | |
| 5909 | − requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data); | |
| 5910 | − old_allocated_size = sc->ctts_allocated_size; | |
| 5911 | − ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, | |
| 5845 | + requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data); | |
| 5846 | + old_allocated_size = sc->tts_allocated_size; | |
| 5847 | + tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size, | |
| 5912 | 5848 | requested_size); |
| 5913 | − if (!ctts_data) | |
| 5849 | + if (!tts_data) | |
| 5914 | 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 get | |
| 5853 | + // In case there were samples without time to sample entries, ensure they get | |
| 5918 | 5854 | // zero valued entries. This ensures clips which mix boxes with and |
| 5919 | − // without ctts entries don't pickup uninitialized data. | |
| 5920 | − memset((uint8_t*)(sc->ctts_data) + old_allocated_size, 0, | |
| 5921 | − sc->ctts_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); | |
| 5855 | + // without time to sample entries don't pickup uninitialized data. | |
| 5856 | + memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0, | |
| 5857 | + sc->tts_allocated_size - old_allocated_size); | |
| 5934 | 5858 | |
| 5935 | 5859 | if (index_entry_pos < sti->nb_index_entries) { |
| 5936 | − // Make hole in index_entries and ctts_data for new samples | |
| 5860 | + // Make hole in index_entries and tts_data for new samples | |
| 5937 | 5861 | memmove(sti->index_entries + index_entry_pos + entries, |
| 5938 | 5862 | sti->index_entries + index_entry_pos, |
| 5939 | 5863 | sizeof(*sti->index_entries) * |
| 5940 | 5864 | (sti->nb_index_entries - index_entry_pos)); |
| 5941 | − memmove(sc->ctts_data + index_entry_pos + entries, | |
| 5942 | − sc->ctts_data + index_entry_pos, | |
| 5943 | − sizeof(*sc->ctts_data) * (sc->ctts_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)); | |
| 5865 | + memmove(sc->tts_data + index_entry_pos + entries, | |
| 5866 | + sc->tts_data + index_entry_pos, | |
| 5867 | + sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos)); | |
| 5947 | 5868 | if (index_entry_pos < sc->current_sample) { |
| 5948 | 5869 | sc->current_sample += entries; |
| 5949 | 5870 | } |
| 5950 | 5871 | } |
| 5951 | 5872 | |
| 5952 | 5873 | sti->nb_index_entries += entries; |
| 5953 | − sc->ctts_count = sti->nb_index_entries; | |
| 5874 | + sc->tts_count = sti->nb_index_entries; | |
| 5954 | 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 | 5879 | // Record the index_entry position in frag_index of this fragment |
| 5957 | 5880 | if (frag_stream_info) { |
| @@ -6013,10 +5936,9 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 55 unmodified lines | ||
| 6013 | 5936 | sti->index_entries[index_entry_pos].min_distance = distance; |
| 6014 | 5937 | sti->index_entries[index_entry_pos].flags = index_entry_flags; |
| 6015 | 5938 | |
| 6016 | − sc->ctts_data[index_entry_pos].count = 1; | |
| 6017 | − sc->ctts_data[index_entry_pos].offset = ctts_duration; | |
| 6018 | − sc->stts_data[index_entry_pos].count = 1; | |
| 6019 | − sc->stts_data[index_entry_pos].duration = sample_duration; | |
| 5939 | + sc->tts_data[index_entry_pos].count = 1; | |
| 5940 | + sc->tts_data[index_entry_pos].offset = ctts_duration; | |
| 5941 | + sc->tts_data[index_entry_pos].duration = sample_duration; | |
| 6020 | 5942 | index_entry_pos++; |
| 6021 | 5943 | |
| 6022 | 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 | 5964 | frag_stream_info->next_trun_dts = dts + sc->time_offset; |
| 6043 | 5965 | if (i < entries) { |
| 6044 | 5966 | // EOF found before reading all entries. Fix the hole this would |
| 6045 | − // leave in index_entries and ctts_data | |
| 5967 | + // leave in index_entries and tts_data | |
| 6046 | 5968 | int gap = entries - i; |
| 6047 | 5969 | memmove(sti->index_entries + index_entry_pos, |
| 6048 | 5970 | sti->index_entries + index_entry_pos + gap, |
| 6049 | 5971 | sizeof(*sti->index_entries) * |
| 6050 | 5972 | (sti->nb_index_entries - (index_entry_pos + gap))); |
| 6051 | − memmove(sc->ctts_data + index_entry_pos, | |
| 6052 | − sc->ctts_data + index_entry_pos + gap, | |
| 6053 | − sizeof(*sc->ctts_data) * | |
| 6054 | − (sc->ctts_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))); | |
| 5973 | + memmove(sc->tts_data + index_entry_pos, | |
| 5974 | + sc->tts_data + index_entry_pos + gap, | |
| 5975 | + sizeof(*sc->tts_data) * | |
| 5976 | + (sc->tts_count - (index_entry_pos + gap))); | |
| 6059 | 5977 | |
| 6060 | 5978 | sti->nb_index_entries -= gap; |
| 6061 | − sc->ctts_count -= gap; | |
| 6062 | − sc->stts_count -= gap; | |
| 5979 | + sc->tts_count -= gap; | |
| 6063 | 5980 | if (index_entry_pos < sc->current_sample) { |
| 6064 | 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 | 9738 | return; |
| 9822 | 9739 | } |
| 9823 | 9740 | |
| 9824 | − av_freep(&sc->ctts_data); | |
| 9741 | + av_freep(&sc->tts_data); | |
| 9825 | 9742 | for (int i = 0; i < sc->drefs_count; i++) { |
| 9826 | 9743 | av_freep(&sc->drefs[i].path); |
| 9827 | 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 | 9755 | av_freep(&sc->stsc_data); |
| 9839 | 9756 | av_freep(&sc->sample_sizes); |
| 9840 | 9757 | av_freep(&sc->keyframes); |
| 9758 | + av_freep(&sc->ctts_data); | |
| 9841 | 9759 | av_freep(&sc->stts_data); |
| 9842 | 9760 | av_freep(&sc->sdtp_data); |
| 9843 | 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 | 10777 | if (sample->flags & AVINDEX_DISCARD_FRAME) { |
| 10860 | 10778 | pkt->flags |= AV_PKT_FLAG_DISCARD; |
| 10861 | 10779 | } |
| 10862 | − if (sc->stts_data && sc->stts_index < sc->stts_count) { | |
| 10863 | − pkt->duration = sc->stts_data[sc->stts_index].duration; | |
| 10864 | − | |
| 10865 | − /* update stts context */ | |
| 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 | − } | |
| 10780 | + if (sc->stts_count && sc->tts_index < sc->tts_count) | |
| 10781 | + pkt->duration = sc->tts_data[sc->tts_index].duration; | |
| 10782 | + if (sc->ctts_count && sc->tts_index < sc->tts_count) { | |
| 10783 | + pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->tts_data[sc->tts_index].offset)); | |
| 10883 | 10784 | } else { |
| 10884 | 10785 | if (pkt->duration == 0) { |
| 10885 | 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 | 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 | 10804 | if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) { |
| 10894 | 10805 | uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1]; |
| 10895 | 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 | 10864 | // Clear current sample |
| 10954 | 10865 | mov_current_sample_set(msc, 0); |
| 10955 | − msc->ctts_index = 0; | |
| 10866 | + msc->tts_index = 0; | |
| 10956 | 10867 | |
| 10957 | 10868 | // Discard current index entries |
| 10958 | 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 | 11097 | mov_current_sample_set(sc, sample); |
| 11187 | 11098 | av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample); |
| 11188 | − /* adjust stts index */ | |
| 11189 | − if (sc->stts_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) { | |
| 11099 | + /* adjust time to sample index */ | |
| 11100 | + if (sc->tts_data) { | |
| 11203 | 11101 | time_sample = 0; |
| 11204 | − for (i = 0; i < sc->ctts_count; i++) { | |
| 11205 | − int next = time_sample + sc->ctts_data[i].count; | |
| 11102 | + for (i = 0; i < sc->tts_count; i++) { | |
| 11103 | + int next = time_sample + sc->tts_data[i].count; | |
| 11206 | 11104 | if (next > sc->current_sample) { |
| 11207 | − sc->ctts_index = i; | |
| 11208 | − sc->ctts_sample = sc->current_sample - time_sample; | |
| 11105 | + sc->tts_index = i; | |
| 11106 | + sc->tts_sample = sc->current_sample - time_sample; | |
| 11209 | 11107 | break; |
| 11210 | 11108 | } |
| 11211 | 11109 | time_sample = next; |