You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.5KB

  1. #include "mov-internal.h"
  2. #include <errno.h>
  3. #include <stdlib.h>
  4. #include <assert.h>
  5. // 8.6.6 Edit List Box (p53)
  6. int mov_read_elst(struct mov_t* mov, const struct mov_box_t* box)
  7. {
  8. uint32_t i, entry_count;
  9. uint32_t version;
  10. struct mov_track_t* track = mov->track;
  11. version = mov_buffer_r8(&mov->io); /* version */
  12. mov_buffer_r24(&mov->io); /* flags */
  13. entry_count = mov_buffer_r32(&mov->io);
  14. assert(0 == track->elst_count && NULL == track->elst);
  15. if (track->elst_count < entry_count)
  16. {
  17. void* p = realloc(track->elst, sizeof(struct mov_elst_t) * entry_count);
  18. if (NULL == p) return -ENOMEM;
  19. track->elst = (struct mov_elst_t*)p;
  20. }
  21. track->elst_count = entry_count;
  22. for (i = 0; i < entry_count; i++)
  23. {
  24. if (1 == version)
  25. {
  26. track->elst[i].segment_duration = mov_buffer_r64(&mov->io);
  27. track->elst[i].media_time = (int64_t)mov_buffer_r64(&mov->io);
  28. }
  29. else
  30. {
  31. assert(0 == version);
  32. track->elst[i].segment_duration = mov_buffer_r32(&mov->io);
  33. track->elst[i].media_time = (int32_t)mov_buffer_r32(&mov->io);
  34. }
  35. track->elst[i].media_rate_integer = (int16_t)mov_buffer_r16(&mov->io);
  36. track->elst[i].media_rate_fraction = (int16_t)mov_buffer_r16(&mov->io);
  37. }
  38. (void)box;
  39. return mov_buffer_error(&mov->io);
  40. }
  41. size_t mov_write_elst(const struct mov_t* mov)
  42. {
  43. uint32_t size;
  44. int64_t time;
  45. int64_t delay;
  46. uint8_t version;
  47. const struct mov_track_t* track = mov->track;
  48. assert(track->start_dts == track->samples[0].dts);
  49. version = track->tkhd.duration > UINT32_MAX ? 1 : 0;
  50. // in media time scale units, in composition time
  51. time = track->samples[0].pts - track->samples[0].dts;
  52. // in units of the timescale in the Movie Header Box
  53. delay = track->samples[0].pts * mov->mvhd.timescale / track->mdhd.timescale;
  54. if (delay > UINT32_MAX)
  55. version = 1;
  56. time = time < 0 ? 0 : time;
  57. size = 12/* full box */ + 4/* entry count */ + (delay > 0 ? 2 : 1) * (version ? 20 : 12);
  58. mov_buffer_w32(&mov->io, size); /* size */
  59. mov_buffer_write(&mov->io, "elst", 4);
  60. mov_buffer_w8(&mov->io, version); /* version */
  61. mov_buffer_w24(&mov->io, 0); /* flags */
  62. mov_buffer_w32(&mov->io, delay > 0 ? 2 : 1); /* entry count */
  63. if (delay > 0)
  64. {
  65. if (1 == version)
  66. {
  67. mov_buffer_w64(&mov->io, (uint64_t)delay); /* segment_duration */
  68. mov_buffer_w64(&mov->io, (uint64_t)-1); /* media_time */
  69. }
  70. else
  71. {
  72. mov_buffer_w32(&mov->io, (uint32_t)delay);
  73. mov_buffer_w32(&mov->io, (uint32_t)-1);
  74. }
  75. mov_buffer_w16(&mov->io, 1); /* media_rate_integer */
  76. mov_buffer_w16(&mov->io, 0); /* media_rate_fraction */
  77. }
  78. /* duration */
  79. if (version == 1)
  80. {
  81. mov_buffer_w64(&mov->io, track->tkhd.duration);
  82. mov_buffer_w64(&mov->io, time);
  83. }
  84. else
  85. {
  86. mov_buffer_w32(&mov->io, (uint32_t)track->tkhd.duration);
  87. mov_buffer_w32(&mov->io, (uint32_t)time);
  88. }
  89. mov_buffer_w16(&mov->io, 1); /* media_rate_integer */
  90. mov_buffer_w16(&mov->io, 0); /* media_rate_fraction */
  91. return size;
  92. }
  93. void mov_apply_elst(struct mov_track_t *track)
  94. {
  95. size_t i;
  96. // edit list
  97. track->samples[0].dts = 0;
  98. track->samples[0].pts = 0;
  99. for (i = 0; i < track->elst_count; i++)
  100. {
  101. if (-1 == track->elst[i].media_time)
  102. {
  103. track->samples[0].dts = track->elst[i].segment_duration;
  104. track->samples[0].pts = track->samples[0].dts;
  105. }
  106. }
  107. }
  108. void mov_apply_elst_tfdt(struct mov_track_t *track)
  109. {
  110. size_t i;
  111. for (i = 0; i < track->elst_count; i++)
  112. {
  113. if (-1 == track->elst[i].media_time)
  114. {
  115. track->tfdt_dts += track->elst[i].segment_duration;
  116. }
  117. }
  118. }