25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

244 satır
6.9KB

  1. #include "mov-internal.h"
  2. #include <errno.h>
  3. #include <stdlib.h>
  4. #include <assert.h>
  5. // 8.6.1.2 Decoding Time to Sample Box (p47)
  6. int mov_read_stts(struct mov_t* mov, const struct mov_box_t* box)
  7. {
  8. uint32_t i, entry_count;
  9. struct mov_stbl_t* stbl = &mov->track->stbl;
  10. mov_buffer_r8(&mov->io); /* version */
  11. mov_buffer_r24(&mov->io); /* flags */
  12. entry_count = mov_buffer_r32(&mov->io);
  13. assert(0 == stbl->stts_count && NULL == stbl->stts); // duplicated STTS atom
  14. if (stbl->stts_count < entry_count)
  15. {
  16. void* p = realloc(stbl->stts, sizeof(struct mov_stts_t) * entry_count);
  17. if (NULL == p) return -ENOMEM;
  18. stbl->stts = (struct mov_stts_t*)p;
  19. }
  20. stbl->stts_count = entry_count;
  21. for (i = 0; i < entry_count; i++)
  22. {
  23. stbl->stts[i].sample_count = mov_buffer_r32(&mov->io);
  24. stbl->stts[i].sample_delta = mov_buffer_r32(&mov->io);
  25. }
  26. (void)box;
  27. return mov_buffer_error(&mov->io);
  28. }
  29. // 8.6.1.3 Composition Time to Sample Box (p47)
  30. int mov_read_ctts(struct mov_t* mov, const struct mov_box_t* box)
  31. {
  32. uint32_t i, entry_count;
  33. struct mov_stbl_t* stbl = &mov->track->stbl;
  34. mov_buffer_r8(&mov->io); /* version */
  35. mov_buffer_r24(&mov->io); /* flags */
  36. entry_count = mov_buffer_r32(&mov->io);
  37. assert(0 == stbl->ctts_count && NULL == stbl->ctts); // duplicated CTTS atom
  38. if (stbl->ctts_count < entry_count)
  39. {
  40. void* p = realloc(stbl->ctts, sizeof(struct mov_stts_t) * entry_count);
  41. if (NULL == p) return -ENOMEM;
  42. stbl->ctts = (struct mov_stts_t*)p;
  43. }
  44. stbl->ctts_count = entry_count;
  45. for (i = 0; i < entry_count; i++)
  46. {
  47. stbl->ctts[i].sample_count = mov_buffer_r32(&mov->io);
  48. stbl->ctts[i].sample_delta = mov_buffer_r32(&mov->io); // parse at int32_t
  49. }
  50. (void)box;
  51. return mov_buffer_error(&mov->io);
  52. }
  53. // 8.6.1.4 Composition to Decode Box (p53)
  54. int mov_read_cslg(struct mov_t* mov, const struct mov_box_t* box)
  55. {
  56. uint8_t version;
  57. // struct mov_stbl_t* stbl = &mov->track->stbl;
  58. version = (uint8_t)mov_buffer_r8(&mov->io); /* version */
  59. mov_buffer_r24(&mov->io); /* flags */
  60. if (0 == version)
  61. {
  62. mov_buffer_r32(&mov->io); /* compositionToDTSShift */
  63. mov_buffer_r32(&mov->io); /* leastDecodeToDisplayDelta */
  64. mov_buffer_r32(&mov->io); /* greatestDecodeToDisplayDelta */
  65. mov_buffer_r32(&mov->io); /* compositionStartTime */
  66. mov_buffer_r32(&mov->io); /* compositionEndTime */
  67. }
  68. else
  69. {
  70. mov_buffer_r64(&mov->io);
  71. mov_buffer_r64(&mov->io);
  72. mov_buffer_r64(&mov->io);
  73. mov_buffer_r64(&mov->io);
  74. mov_buffer_r64(&mov->io);
  75. }
  76. (void)box;
  77. return mov_buffer_error(&mov->io);
  78. }
  79. size_t mov_write_stts(const struct mov_t* mov, uint32_t count)
  80. {
  81. uint32_t size, i;
  82. const struct mov_sample_t* sample;
  83. const struct mov_track_t* track = mov->track;
  84. size = 12/* full box */ + 4/* entry count */ + count * 8/* entry */;
  85. mov_buffer_w32(&mov->io, size); /* size */
  86. mov_buffer_write(&mov->io, "stts", 4);
  87. mov_buffer_w32(&mov->io, 0); /* version & flags */
  88. mov_buffer_w32(&mov->io, count); /* entry count */
  89. for (i = 0; i < track->sample_count; i++)
  90. {
  91. sample = &track->samples[i];
  92. if(0 == sample->first_chunk)
  93. continue;
  94. mov_buffer_w32(&mov->io, sample->first_chunk); // count
  95. mov_buffer_w32(&mov->io, sample->samples_per_chunk); // delta * timescale / 1000
  96. }
  97. return size;
  98. }
  99. size_t mov_write_ctts(const struct mov_t* mov, uint32_t count)
  100. {
  101. uint32_t size, i;
  102. const struct mov_sample_t* sample;
  103. const struct mov_track_t* track = mov->track;
  104. size = 12/* full box */ + 4/* entry count */ + count * 8/* entry */;
  105. mov_buffer_w32(&mov->io, size); /* size */
  106. mov_buffer_write(&mov->io, "ctts", 4);
  107. mov_buffer_w8(&mov->io, (track->flags & MOV_TRACK_FLAG_CTTS_V1) ? 1 : 0); /* version */
  108. mov_buffer_w24(&mov->io, 0); /* flags */
  109. mov_buffer_w32(&mov->io, count); /* entry count */
  110. for (i = 0; i < track->sample_count; i++)
  111. {
  112. sample = &track->samples[i];
  113. if(0 == sample->first_chunk)
  114. continue;
  115. mov_buffer_w32(&mov->io, sample->first_chunk); // count
  116. mov_buffer_w32(&mov->io, sample->samples_per_chunk); // offset * timescale / 1000
  117. }
  118. return size;
  119. }
  120. uint32_t mov_build_stts(struct mov_track_t* track)
  121. {
  122. size_t i;
  123. uint32_t delta, count = 0;
  124. struct mov_sample_t* sample = NULL;
  125. for (i = 0; i < track->sample_count; i++)
  126. {
  127. assert(track->samples[i + 1].dts >= track->samples[i].dts || i + 1 == track->sample_count);
  128. delta = (uint32_t)(i + 1 < track->sample_count && track->samples[i + 1].dts > track->samples[i].dts ? track->samples[i + 1].dts - track->samples[i].dts : 1);
  129. if (NULL != sample && delta == sample->samples_per_chunk)
  130. {
  131. track->samples[i].first_chunk = 0;
  132. assert(sample->first_chunk > 0);
  133. ++sample->first_chunk; // compress
  134. }
  135. else
  136. {
  137. sample = &track->samples[i];
  138. sample->first_chunk = 1;
  139. sample->samples_per_chunk = delta;
  140. ++count;
  141. }
  142. }
  143. return count;
  144. }
  145. uint32_t mov_build_ctts(struct mov_track_t* track)
  146. {
  147. size_t i;
  148. uint32_t delta;
  149. uint32_t count = 0;
  150. struct mov_sample_t* sample = NULL;
  151. for (i = 0; i < track->sample_count; i++)
  152. {
  153. delta = (uint32_t)(track->samples[i].pts - track->samples[i].dts);
  154. if (i > 0 && delta == sample->samples_per_chunk)
  155. {
  156. track->samples[i].first_chunk = 0;
  157. assert(sample->first_chunk > 0);
  158. ++sample->first_chunk; // compress
  159. }
  160. else
  161. {
  162. sample = &track->samples[i];
  163. sample->first_chunk = 1;
  164. sample->samples_per_chunk = delta;
  165. ++count;
  166. // fixed: firefox version 51 don't support version 1
  167. if (track->samples[i].pts < track->samples[i].dts)
  168. track->flags |= MOV_TRACK_FLAG_CTTS_V1;
  169. }
  170. }
  171. return count;
  172. }
  173. void mov_apply_stts(struct mov_track_t* track)
  174. {
  175. size_t i, j, n;
  176. struct mov_stbl_t* stbl = &track->stbl;
  177. for (i = 0, n = 1; i < stbl->stts_count; i++)
  178. {
  179. for (j = 0; j < stbl->stts[i].sample_count; j++, n++)
  180. {
  181. track->samples[n].dts = track->samples[n - 1].dts + stbl->stts[i].sample_delta;
  182. track->samples[n].pts = track->samples[n].dts;
  183. }
  184. }
  185. assert(n - 1 == track->sample_count); // see more mov_read_stsz
  186. }
  187. void mov_apply_ctts(struct mov_track_t* track)
  188. {
  189. size_t i, j, n;
  190. int32_t delta, dts_shift;
  191. struct mov_stbl_t* stbl = &track->stbl;
  192. // make sure pts >= dts
  193. dts_shift = 0;
  194. for (i = 0; i < stbl->ctts_count; i++)
  195. {
  196. delta = (int32_t)stbl->ctts[i].sample_delta;
  197. if (delta < 0 && dts_shift > delta && delta != -1 /* see more cslg box*/)
  198. dts_shift = delta;
  199. }
  200. assert(dts_shift <= 0);
  201. // sample cts/pts
  202. for (i = 0, n = 0; i < stbl->ctts_count; i++)
  203. {
  204. for (j = 0; j < stbl->ctts[i].sample_count; j++, n++)
  205. track->samples[n].pts += (int64_t)((int32_t)stbl->ctts[i].sample_delta - dts_shift); // always as int, fixed mp4box delta version error
  206. }
  207. assert(0 == stbl->ctts_count || n == track->sample_count);
  208. }