|
- #include "mov-internal.h"
- #include <errno.h>
- #include <stdlib.h>
- #include <assert.h>
-
- // 8.6.6 Edit List Box (p53)
- int mov_read_elst(struct mov_t* mov, const struct mov_box_t* box)
- {
- uint32_t i, entry_count;
- uint32_t version;
- struct mov_track_t* track = mov->track;
-
- version = mov_buffer_r8(&mov->io); /* version */
- mov_buffer_r24(&mov->io); /* flags */
- entry_count = mov_buffer_r32(&mov->io);
-
- assert(0 == track->elst_count && NULL == track->elst);
- if (track->elst_count < entry_count)
- {
- void* p = realloc(track->elst, sizeof(struct mov_elst_t) * entry_count);
- if (NULL == p) return -ENOMEM;
- track->elst = (struct mov_elst_t*)p;
- }
- track->elst_count = entry_count;
-
- for (i = 0; i < entry_count; i++)
- {
- if (1 == version)
- {
- track->elst[i].segment_duration = mov_buffer_r64(&mov->io);
- track->elst[i].media_time = (int64_t)mov_buffer_r64(&mov->io);
- }
- else
- {
- assert(0 == version);
- track->elst[i].segment_duration = mov_buffer_r32(&mov->io);
- track->elst[i].media_time = (int32_t)mov_buffer_r32(&mov->io);
- }
- track->elst[i].media_rate_integer = (int16_t)mov_buffer_r16(&mov->io);
- track->elst[i].media_rate_fraction = (int16_t)mov_buffer_r16(&mov->io);
- }
-
- (void)box;
- return mov_buffer_error(&mov->io);
- }
-
- size_t mov_write_elst(const struct mov_t* mov)
- {
- uint32_t size;
- int64_t time;
- int64_t delay;
- uint8_t version;
- const struct mov_track_t* track = mov->track;
-
- assert(track->start_dts == track->samples[0].dts);
- version = track->tkhd.duration > UINT32_MAX ? 1 : 0;
-
- // in media time scale units, in composition time
- time = track->samples[0].pts - track->samples[0].dts;
- // in units of the timescale in the Movie Header Box
- delay = track->samples[0].pts * mov->mvhd.timescale / track->mdhd.timescale;
- if (delay > UINT32_MAX)
- version = 1;
-
- time = time < 0 ? 0 : time;
- size = 12/* full box */ + 4/* entry count */ + (delay > 0 ? 2 : 1) * (version ? 20 : 12);
-
- mov_buffer_w32(&mov->io, size); /* size */
- mov_buffer_write(&mov->io, "elst", 4);
- mov_buffer_w8(&mov->io, version); /* version */
- mov_buffer_w24(&mov->io, 0); /* flags */
- mov_buffer_w32(&mov->io, delay > 0 ? 2 : 1); /* entry count */
-
- if (delay > 0)
- {
- if (1 == version)
- {
- mov_buffer_w64(&mov->io, (uint64_t)delay); /* segment_duration */
- mov_buffer_w64(&mov->io, (uint64_t)-1); /* media_time */
- }
- else
- {
- mov_buffer_w32(&mov->io, (uint32_t)delay);
- mov_buffer_w32(&mov->io, (uint32_t)-1);
- }
-
- mov_buffer_w16(&mov->io, 1); /* media_rate_integer */
- mov_buffer_w16(&mov->io, 0); /* media_rate_fraction */
- }
-
- /* duration */
- if (version == 1)
- {
- mov_buffer_w64(&mov->io, track->tkhd.duration);
- mov_buffer_w64(&mov->io, time);
- }
- else
- {
- mov_buffer_w32(&mov->io, (uint32_t)track->tkhd.duration);
- mov_buffer_w32(&mov->io, (uint32_t)time);
- }
- mov_buffer_w16(&mov->io, 1); /* media_rate_integer */
- mov_buffer_w16(&mov->io, 0); /* media_rate_fraction */
-
- return size;
- }
-
- void mov_apply_elst(struct mov_track_t *track)
- {
- size_t i;
-
- // edit list
- track->samples[0].dts = 0;
- track->samples[0].pts = 0;
- for (i = 0; i < track->elst_count; i++)
- {
- if (-1 == track->elst[i].media_time)
- {
- track->samples[0].dts = track->elst[i].segment_duration;
- track->samples[0].pts = track->samples[0].dts;
- }
- }
- }
-
- void mov_apply_elst_tfdt(struct mov_track_t *track)
- {
- size_t i;
-
- for (i = 0; i < track->elst_count; i++)
- {
- if (-1 == track->elst[i].media_time)
- {
- track->tfdt_dts += track->elst[i].segment_duration;
- }
- }
- }
|