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.

164 lines
5.4KB

  1. #include "mov-internal.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <errno.h>
  6. // 8.8.8 Track Fragment Run Box (p72)
  7. int mov_read_trun(struct mov_t* mov, const struct mov_box_t* box)
  8. {
  9. unsigned int version;
  10. uint32_t flags;
  11. uint32_t i, sample_count;
  12. uint64_t data_offset;
  13. uint32_t first_sample_flags;
  14. uint32_t sample_duration, sample_size, sample_flags;
  15. int64_t sample_composition_time_offset;
  16. struct mov_track_t* track;
  17. struct mov_sample_t* sample;
  18. version = mov_buffer_r8(&mov->io); /* version */
  19. flags = mov_buffer_r24(&mov->io); /* flags */
  20. sample_count = mov_buffer_r32(&mov->io); /* sample_count */
  21. track = mov->track;
  22. if (sample_count > 0)
  23. {
  24. void* p = realloc(track->samples, sizeof(struct mov_sample_t) * (track->sample_count + sample_count + 1));
  25. if (NULL == p) return -ENOMEM;
  26. track->samples = (struct mov_sample_t*)p;
  27. memset(track->samples + track->sample_count, 0, sizeof(struct mov_sample_t) * (sample_count + 1));
  28. }
  29. data_offset = track->tfhd.base_data_offset;
  30. if (MOV_TRUN_FLAG_DATA_OFFSET_PRESENT & flags)
  31. data_offset += (int32_t)mov_buffer_r32(&mov->io); /* data_offset */
  32. if (MOV_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT & flags)
  33. first_sample_flags = mov_buffer_r32(&mov->io); /* first_sample_flags */
  34. else
  35. first_sample_flags = track->tfhd.flags;
  36. sample = track->samples + track->sample_count;
  37. for (i = 0; i < sample_count; i++)
  38. {
  39. if (MOV_TRUN_FLAG_SAMPLE_DURATION_PRESENT & flags)
  40. sample_duration = mov_buffer_r32(&mov->io); /* sample_duration*/
  41. else
  42. sample_duration = track->tfhd.default_sample_duration;
  43. if (MOV_TRUN_FLAG_SAMPLE_SIZE_PRESENT & flags)
  44. sample_size = mov_buffer_r32(&mov->io); /* sample_size*/
  45. else
  46. sample_size = track->tfhd.default_sample_size;
  47. if (MOV_TRUN_FLAG_SAMPLE_FLAGS_PRESENT & flags)
  48. sample_flags = mov_buffer_r32(&mov->io); /* sample_flags*/
  49. else
  50. sample_flags = i ? track->tfhd.default_sample_flags : first_sample_flags;
  51. if (MOV_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT & flags)
  52. {
  53. sample_composition_time_offset = mov_buffer_r32(&mov->io); /* sample_composition_time_offset*/
  54. if (1 == version)
  55. sample_composition_time_offset = (int32_t)sample_composition_time_offset;
  56. }
  57. else
  58. sample_composition_time_offset = 0;
  59. sample[i].offset = data_offset;
  60. sample[i].bytes = sample_size;
  61. sample[i].dts = track->tfdt_dts;
  62. sample[i].pts = sample[i].dts + sample_composition_time_offset;
  63. sample[i].flags = (sample_flags & (MOV_TREX_FLAG_SAMPLE_IS_NO_SYNC_SAMPLE | 0x01000000)) ? 0 : MOV_AV_FLAG_KEYFREAME;
  64. sample[i].sample_description_index = track->tfhd.sample_description_index;
  65. data_offset += sample_size;
  66. track->tfdt_dts += sample_duration;
  67. }
  68. track->sample_count += sample_count;
  69. mov->implicit_offset = data_offset;
  70. (void)box;
  71. return mov_buffer_error(&mov->io);
  72. }
  73. size_t mov_write_trun(const struct mov_t* mov, uint32_t from, uint32_t count, uint32_t moof)
  74. {
  75. uint32_t flags;
  76. uint32_t delta;
  77. uint64_t offset;
  78. uint32_t size, i;
  79. const struct mov_sample_t* sample;
  80. const struct mov_track_t* track = mov->track;
  81. if (count < 1) return 0;
  82. assert(from + count <= track->sample_count);
  83. flags = MOV_TRUN_FLAG_DATA_OFFSET_PRESENT;
  84. if (track->samples[from].flags & MOV_AV_FLAG_KEYFREAME)
  85. flags |= MOV_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT;
  86. for (i = from; i < from + count; i++)
  87. {
  88. sample = track->samples + i;
  89. if (sample->bytes != track->tfhd.default_sample_size)
  90. flags |= MOV_TRUN_FLAG_SAMPLE_SIZE_PRESENT;
  91. if ((uint32_t)(i + 1 < track->sample_count ? track->samples[i + 1].dts - track->samples[i].dts : track->turn_last_duration) != track->tfhd.default_sample_duration)
  92. flags |= MOV_TRUN_FLAG_SAMPLE_DURATION_PRESENT;
  93. if (sample->pts != sample->dts)
  94. flags |= MOV_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT;
  95. }
  96. size = 12/* full box */ + 4/* sample count */;
  97. offset = mov_buffer_tell(&mov->io);
  98. mov_buffer_w32(&mov->io, 0); /* size */
  99. mov_buffer_write(&mov->io, "trun", 4);
  100. mov_buffer_w8(&mov->io, 1); /* version */
  101. mov_buffer_w24(&mov->io, flags); /* flags */
  102. mov_buffer_w32(&mov->io, count); /* sample_count */
  103. assert(flags & MOV_TRUN_FLAG_DATA_OFFSET_PRESENT);
  104. if (flags & MOV_TRUN_FLAG_DATA_OFFSET_PRESENT)
  105. {
  106. mov_buffer_w32(&mov->io, moof + (uint32_t)track->samples[from].offset);
  107. size += 4;
  108. }
  109. if (flags & MOV_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT)
  110. {
  111. mov_buffer_w32(&mov->io, MOV_TREX_FLAG_SAMPLE_DEPENDS_ON_I_PICTURE); /* first_sample_flags */
  112. size += 4;
  113. }
  114. assert(from + count <= track->sample_count);
  115. for (i = from; i < from + count; i++)
  116. {
  117. sample = track->samples + i;
  118. if (flags & MOV_TRUN_FLAG_SAMPLE_DURATION_PRESENT)
  119. {
  120. delta = (uint32_t)(i + 1 < track->sample_count ? track->samples[i + 1].dts - track->samples[i].dts : track->turn_last_duration);
  121. mov_buffer_w32(&mov->io, delta); /* sample_duration */
  122. size += 4;
  123. }
  124. if (flags & MOV_TRUN_FLAG_SAMPLE_SIZE_PRESENT)
  125. {
  126. mov_buffer_w32(&mov->io, (uint32_t)sample->bytes); /* sample_size */
  127. size += 4;
  128. }
  129. assert(0 == (flags & MOV_TRUN_FLAG_SAMPLE_FLAGS_PRESENT));
  130. // mov_buffer_w32(&mov->io, 0); /* sample_flags */
  131. if (flags & MOV_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT)
  132. {
  133. mov_buffer_w32(&mov->io, (int32_t)(sample->pts - sample->dts)); /* sample_composition_time_offset */
  134. size += 4;
  135. }
  136. }
  137. mov_write_size(mov, offset, size);
  138. return size;
  139. }