Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

10 місяці тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "mov-reader.h"
  2. #include "mov-format.h"
  3. #include "mpeg4-avc.h"
  4. #include "mpeg4-aac.h"
  5. #include "flv-proto.h"
  6. #include "flv-header.h"
  7. #include "flv-writer.h"
  8. #include "flv-muxer.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <assert.h>
  13. extern "C" const struct mov_buffer_t* mov_file_buffer(void);
  14. static uint8_t s_packet[2 * 1024 * 1024];
  15. static uint8_t s_buffer[4 * 1024 * 1024];
  16. static uint32_t s_aac_track;
  17. static uint32_t s_avc_track;
  18. static uint32_t s_txt_track;
  19. static uint8_t s_video_type;
  20. static struct flv_audio_tag_header_t s_audio_tag;
  21. static struct flv_video_tag_header_t s_video_tag;
  22. static int iskeyframe(const uint8_t* data, size_t bytes)
  23. {
  24. size_t nalu_length = 4;
  25. uint32_t len;
  26. while (bytes >= nalu_length + 1)
  27. {
  28. len = 0;
  29. for (size_t i = 0; i < nalu_length; i++)
  30. len = (len << 8) | data[i];
  31. if (len + nalu_length > bytes)
  32. return 0; // invalid
  33. uint8_t nalu_type = (FLV_VIDEO_H264 == s_video_type) ? (data[nalu_length] & 0x1f) : ((data[nalu_length] >> 1) & 0x3f);
  34. if ((FLV_VIDEO_H264 == s_video_type) ? (5 == nalu_type) : (16 <= nalu_type && nalu_type <= 23))
  35. return 1;
  36. bytes -= nalu_length + len;
  37. data += nalu_length + len;
  38. }
  39. return 0;
  40. }
  41. static void onread(void* flv, uint32_t track, const void* buffer, size_t bytes, int64_t pts, int64_t dts, int flags)
  42. {
  43. if (s_avc_track == track)
  44. {
  45. int keyframe = (FLV_VIDEO_H264 == s_video_type || FLV_VIDEO_H265 == s_video_type) ? iskeyframe((const uint8_t*)buffer, bytes) : flags;
  46. printf("[V] pts: %08lld, dts: %08lld%s\n", pts, dts, keyframe ? " [I]" : "");
  47. s_video_tag.keyframe = (keyframe ? 1 : 2);
  48. s_video_tag.avpacket = FLV_AVPACKET;
  49. s_video_tag.cts = (int32_t)(pts - dts);
  50. flv_video_tag_header_write(&s_video_tag, s_packet, sizeof(s_packet));
  51. memcpy(s_packet + 5, buffer, bytes);
  52. flv_writer_input(flv, FLV_TYPE_VIDEO, s_packet, bytes + 5, (uint32_t)dts);
  53. }
  54. else if (s_aac_track == track)
  55. {
  56. printf("[A] pts: %08lld, dts: %08lld\n", pts, dts);
  57. s_audio_tag.avpacket = FLV_AVPACKET;
  58. int m = flv_audio_tag_header_write(&s_audio_tag, s_packet, sizeof(s_packet));
  59. memcpy(s_packet + m, buffer, bytes); // AAC exclude ADTS
  60. flv_writer_input(flv, FLV_TYPE_AUDIO, s_packet, bytes + m, (uint32_t)dts);
  61. }
  62. else
  63. {
  64. assert(0);
  65. }
  66. }
  67. static void mov_video_info(void* flv, uint32_t track, uint8_t object, int /*width*/, int /*height*/, const void* extra, size_t bytes)
  68. {
  69. s_avc_track = track;
  70. assert(MOV_OBJECT_H264 == object || MOV_OBJECT_HEVC == object || MOV_OBJECT_AV1 == object || MOV_OBJECT_VP9 == object);
  71. s_video_type = MOV_OBJECT_H264 == object ? FLV_VIDEO_H264 : (MOV_OBJECT_HEVC == object ? FLV_VIDEO_H265 : FLV_VIDEO_AV1);
  72. s_video_tag.codecid = s_video_type;
  73. s_video_tag.keyframe = 1;
  74. s_video_tag.avpacket = FLV_SEQUENCE_HEADER;
  75. s_video_tag.cts = 0;
  76. flv_video_tag_header_write(&s_video_tag, s_packet, sizeof(s_packet));
  77. memcpy(s_packet + 5, extra, bytes);
  78. flv_writer_input(flv, FLV_TYPE_VIDEO, s_packet, bytes + 5, 0);
  79. }
  80. static void mov_audio_info(void* flv, uint32_t track, uint8_t object, int channel_count, int /*bit_per_sample*/, int sample_rate, const void* extra, size_t bytes)
  81. {
  82. if (MOV_OBJECT_AAC == object || MOV_OBJECT_OPUS == object)
  83. {
  84. s_aac_track = track;
  85. s_audio_tag.codecid = MOV_OBJECT_AAC == object ? FLV_AUDIO_AAC : FLV_AUDIO_OPUS;
  86. s_audio_tag.rate = 3; // 44k-SoundRate
  87. s_audio_tag.bits = 1; // 16-bit samples
  88. s_audio_tag.channels = 1; // Stereo sound
  89. s_audio_tag.avpacket = FLV_SEQUENCE_HEADER;
  90. int m = flv_audio_tag_header_write(&s_audio_tag, s_packet, sizeof(s_packet));
  91. memcpy(s_packet + m, extra, bytes);
  92. flv_writer_input(flv, FLV_TYPE_AUDIO, s_packet, bytes + m, 0);
  93. }
  94. }
  95. static int mov_meta_info(void* flv, int type, const void* data, size_t bytes, uint32_t timestamp)
  96. {
  97. return flv_writer_input(flv, FLV_TYPE_SCRIPT, data, bytes, 0);
  98. }
  99. void mov_2_flv_test(const char* mp4)
  100. {
  101. snprintf((char*)s_packet, sizeof(s_packet), "%s.flv", mp4);
  102. FILE* fp = fopen(mp4, "rb");
  103. mov_reader_t* mov = mov_reader_create(mov_file_buffer(), fp);
  104. void* flv = flv_writer_create((char*)s_packet);
  105. //flv_muxer_t* muxer = flv_muxer_create(mov_meta_info, flv);
  106. //memset(&metadata, 0, sizeof(metadata));
  107. //metadata.videocodecid = FLV_VIDEO_H264;
  108. //metadata.videodatarate = 2000;
  109. //metadata.framerate = 25.0;
  110. //metadata.width = 1280;
  111. //metadata.height = 720;
  112. //flv_muxer_metadata(muxer, &metadata);
  113. //flv_muxer_destroy(muxer);
  114. struct mov_reader_trackinfo_t info = { mov_video_info, mov_audio_info };
  115. mov_reader_getinfo(mov, &info, flv);
  116. while (mov_reader_read(mov, s_buffer, sizeof(s_buffer), onread, flv) > 0)
  117. {
  118. }
  119. mov_reader_destroy(mov);
  120. flv_writer_destroy(flv);
  121. fclose(fp);
  122. }