No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

261 líneas
8.0KB

  1. #include "mov-reader.h"
  2. #include "mov-format.h"
  3. #include "mpeg4-hevc.h"
  4. #include "mpeg4-avc.h"
  5. #include "mpeg4-aac.h"
  6. #include "opus-head.h"
  7. #include "webm-vpx.h"
  8. #include "aom-av1.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <assert.h>
  13. #include "mov-file-buffer.h"
  14. #define USE_NEW_MOV_READ_API 1
  15. static uint8_t s_packet[2 * 1024 * 1024];
  16. static uint8_t s_buffer[4 * 1024 * 1024];
  17. static FILE *s_vfp, *s_afp;
  18. static struct mpeg4_hevc_t s_hevc;
  19. static struct mpeg4_avc_t s_avc;
  20. static struct mpeg4_aac_t s_aac;
  21. static struct webm_vpx_t s_vpx;
  22. static struct opus_head_t s_opus;
  23. static struct aom_av1_t s_av1;
  24. static uint32_t s_aac_track = 0xFFFFFFFF;
  25. static uint32_t s_avc_track = 0xFFFFFFFF;
  26. static uint32_t s_av1_track = 0xFFFFFFFF;
  27. static uint32_t s_vpx_track = 0xFFFFFFFF;
  28. static uint32_t s_hevc_track = 0xFFFFFFFF;
  29. static uint32_t s_opus_track = 0xFFFFFFFF;
  30. static uint32_t s_mp3_track = 0xFFFFFFFF;
  31. static uint32_t s_subtitle_track = 0xFFFFFFFF;
  32. #if defined(USE_NEW_MOV_READ_API)
  33. struct mov_packet_test_t
  34. {
  35. int flags;
  36. int64_t pts;
  37. int64_t dts;
  38. uint32_t track;
  39. void* ptr;
  40. size_t bytes;
  41. };
  42. static void* onalloc(void* param, uint32_t track, size_t bytes, int64_t pts, int64_t dts, int flags)
  43. {
  44. // emulate allocation
  45. struct mov_packet_test_t* pkt = (struct mov_packet_test_t*)param;
  46. if (pkt->bytes < bytes)
  47. return NULL;
  48. pkt->flags = flags;
  49. pkt->pts = pts;
  50. pkt->dts = dts;
  51. pkt->track = track;
  52. pkt->bytes = bytes;
  53. return pkt->ptr;
  54. }
  55. #endif
  56. inline const char* ftimestamp(uint32_t t, char* buf)
  57. {
  58. sprintf(buf, "%02u:%02u:%02u.%03u", t / 3600000, (t / 60000) % 60, (t / 1000) % 60, t % 1000);
  59. return buf;
  60. }
  61. static void onread(void* flv, uint32_t track, const void* buffer, size_t bytes, int64_t pts, int64_t dts, int flags)
  62. {
  63. static char s_pts[64], s_dts[64];
  64. static int64_t v_pts, v_dts;
  65. static int64_t a_pts, a_dts;
  66. if (s_avc_track == track)
  67. {
  68. printf("[H264] pts: %s, dts: %s, diff: %03d/%03d, bytes: %u%s\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - v_pts), (int)(dts - v_dts), (unsigned int)bytes, flags ? " [I]" : "");
  69. v_pts = pts;
  70. v_dts = dts;
  71. assert(h264_is_new_access_unit((const uint8_t*)buffer + 4, bytes - 4));
  72. int n = h264_mp4toannexb(&s_avc, buffer, bytes, s_packet, sizeof(s_packet));
  73. fwrite(s_packet, 1, n, s_vfp);
  74. }
  75. else if (s_hevc_track == track)
  76. {
  77. uint8_t nalu_type = (((const uint8_t*)buffer)[4] >> 1) & 0x3F;
  78. uint8_t irap = 16 <= nalu_type && nalu_type <= 23;
  79. printf("[H265] pts: %s, dts: %s, diff: %03d/%03d, bytes: %u%s,%d\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - v_pts), (int)(dts - v_dts), (unsigned int)bytes, flags ? " [I]" : "", (unsigned int)nalu_type);
  80. v_pts = pts;
  81. v_dts = dts;
  82. assert(h265_is_new_access_unit((const uint8_t*)buffer+4, bytes-4));
  83. int n = h265_mp4toannexb(&s_hevc, buffer, bytes, s_packet, sizeof(s_packet));
  84. fwrite(s_packet, 1, n, s_vfp);
  85. }
  86. else if (s_av1_track == track)
  87. {
  88. printf("[AV1] pts: %s, dts: %s, diff: %03d/%03d, bytes: %u%s\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - v_pts), (int)(dts - v_dts), (unsigned int)bytes, flags ? " [I]" : "");
  89. v_pts = pts;
  90. v_dts = dts;
  91. //int n = aom_av1_codec_configuration_record_save(&s_av1, s_packet, sizeof(s_packet));
  92. //fwrite(s_packet, 1, n, s_vfp);
  93. }
  94. else if (s_vpx_track == track)
  95. {
  96. printf("[VP9] pts: %s, dts: %s, diff: %03d/%03d, bytes: %u%s\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - v_pts), (int)(dts - v_dts), (unsigned int)bytes, flags ? " [I]" : "");
  97. v_pts = pts;
  98. v_dts = dts;
  99. //int n = aom_av1_codec_configuration_record_save(&s_av1, s_packet, sizeof(s_packet));
  100. //fwrite(s_packet, 1, n, s_vfp);
  101. }
  102. else if (s_aac_track == track)
  103. {
  104. printf("[AAC] pts: %s, dts: %s, diff: %03d/%03d, bytes: %u\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - a_pts), (int)(dts - a_dts), (unsigned int)bytes);
  105. a_pts = pts;
  106. a_dts = dts;
  107. uint8_t adts[32];
  108. int n = mpeg4_aac_adts_save(&s_aac, bytes, adts, sizeof(adts));
  109. fwrite(adts, 1, n, s_afp);
  110. fwrite(buffer, 1, bytes, s_afp);
  111. }
  112. else if (s_opus_track == track)
  113. {
  114. printf("[OPUS] pts: %s, dts: %s, diff: %03d/%03d, bytes: %u\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - a_pts), (int)(dts - a_dts), (unsigned int)bytes);
  115. a_pts = pts;
  116. a_dts = dts;
  117. }
  118. else if (s_mp3_track == track)
  119. {
  120. printf("[MP3] pts: %s, dts: %s, diff: %03d/%03d, bytes: %u\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - a_pts), (int)(dts - a_dts), (unsigned int)bytes);
  121. a_pts = pts;
  122. a_dts = dts;
  123. fwrite(buffer, 1, bytes, s_afp);
  124. }
  125. else if (s_subtitle_track == track)
  126. {
  127. static int64_t t_pts, t_dts;
  128. printf("[TEXT] pts: %s, dts: %s, diff: %03d/%03d, bytes: %u, text: %.*s\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - t_pts), (int)(dts - t_dts), (unsigned int)bytes, (int)bytes-2, (const char*)buffer+2);
  129. t_pts = pts;
  130. t_dts = dts;
  131. }
  132. else
  133. {
  134. printf("%d\n", track);
  135. //assert(0);
  136. }
  137. }
  138. static void mov_video_info(void* /*param*/, uint32_t track, uint8_t object, int /*width*/, int /*height*/, const void* extra, size_t bytes)
  139. {
  140. if (MOV_OBJECT_H264 == object)
  141. {
  142. s_vfp = fopen("v.h264", "wb");
  143. s_avc_track = track;
  144. mpeg4_avc_decoder_configuration_record_load((const uint8_t*)extra, bytes, &s_avc);
  145. }
  146. else if (MOV_OBJECT_HEVC == object)
  147. {
  148. s_vfp = fopen("v.h265", "wb");
  149. s_hevc_track = track;
  150. mpeg4_hevc_decoder_configuration_record_load((const uint8_t*)extra, bytes, &s_hevc);
  151. }
  152. else if (MOV_OBJECT_AV1 == object)
  153. {
  154. s_vfp = fopen("v.obus", "wb");
  155. s_av1_track = track;
  156. aom_av1_codec_configuration_record_load((const uint8_t*)extra, bytes, &s_av1);
  157. }
  158. else if (MOV_OBJECT_VP9 == object)
  159. {
  160. s_vfp = fopen("v.vp9", "wb");
  161. s_vpx_track = track;
  162. webm_vpx_codec_configuration_record_load((const uint8_t*)extra, bytes, &s_vpx);
  163. }
  164. else
  165. {
  166. assert(0);
  167. }
  168. }
  169. static void mov_audio_info(void* /*param*/, uint32_t track, uint8_t object, int channel_count, int /*bit_per_sample*/, int sample_rate, const void* extra, size_t bytes)
  170. {
  171. if (MOV_OBJECT_AAC == object)
  172. {
  173. s_afp = fopen("a.aac", "wb");
  174. s_aac_track = track;
  175. assert(bytes == mpeg4_aac_audio_specific_config_load((const uint8_t*)extra, bytes, &s_aac));
  176. assert(channel_count == s_aac.channels);
  177. assert(MOV_OBJECT_AAC == object);
  178. s_aac.profile = MPEG4_AAC_LC;
  179. s_aac.channel_configuration = channel_count;
  180. s_aac.sampling_frequency_index = mpeg4_aac_audio_frequency_from(sample_rate);
  181. }
  182. else if (MOV_OBJECT_OPUS == object)
  183. {
  184. s_afp = fopen("a.opus", "wb");
  185. s_opus_track = track;
  186. assert(bytes == opus_head_load((const uint8_t*)extra, bytes, &s_opus));
  187. assert(s_opus.input_sample_rate == 48000);
  188. }
  189. else if (MOV_OBJECT_MP3 == object || MOV_OBJECT_MP1A == object)
  190. {
  191. s_afp = fopen("a.mp3", "wb");
  192. s_mp3_track = track;
  193. }
  194. else
  195. {
  196. s_aac_track = track;
  197. s_aac.channel_configuration = channel_count;
  198. //s_aac.sampling_frequency_index = mpeg4_aac_audio_frequency_from(sample_rate);
  199. }
  200. }
  201. static void mov_subtitle_info(void* /*param*/, uint32_t track, uint8_t object, const void* /*extra*/, size_t /*bytes*/)
  202. {
  203. s_subtitle_track = track;
  204. }
  205. void mov_reader_test(const char* mp4)
  206. {
  207. struct mov_file_cache_t file;
  208. memset(&file, 0, sizeof(file));
  209. file.fp = fopen(mp4, "rb");
  210. mov_reader_t* mov = mov_reader_create(mov_file_cache_buffer(), &file);
  211. uint64_t duration = mov_reader_getduration(mov);
  212. struct mov_reader_trackinfo_t info = { mov_video_info, mov_audio_info, mov_subtitle_info };
  213. mov_reader_getinfo(mov, &info, NULL);
  214. #if !defined(USE_NEW_MOV_READ_API)
  215. while (mov_reader_read(mov, s_buffer, sizeof(s_buffer), onread, NULL) > 0)
  216. {
  217. }
  218. #else
  219. while (1)
  220. {
  221. struct mov_packet_test_t pkt;
  222. pkt.ptr = s_buffer;
  223. pkt.bytes = sizeof(s_buffer);
  224. int r = mov_reader_read2(mov, onalloc, &pkt);
  225. if (r <= 0)
  226. {
  227. // WARNNING: free(pkt.ptr) if alloc new buffer
  228. break;
  229. }
  230. onread(NULL, pkt.track, pkt.ptr, pkt.bytes, pkt.pts, pkt.dts, pkt.flags);
  231. }
  232. #endif
  233. duration /= 2;
  234. mov_reader_seek(mov, (int64_t*)&duration);
  235. mov_reader_destroy(mov);
  236. if(s_vfp) fclose(s_vfp);
  237. if(s_afp) fclose(s_afp);
  238. fclose(file.fp);
  239. }