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

138 рядки
3.9KB

  1. #include "mov-writer.h"
  2. #include "mov-format.h"
  3. #include "mov-udta.h"
  4. #include "mpeg4-aac.h"
  5. #include "opus-head.h"
  6. #include "mp3-header.h"
  7. #include "flv-proto.h"
  8. #include "flv-reader.h"
  9. #include "flv-parser.h"
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <assert.h>
  14. extern "C" const struct mov_buffer_t* mov_file_buffer(void);
  15. extern "C" int mov_writer_add_udta(mov_writer_t * mov, const void* data, size_t size);
  16. static uint8_t s_buffer[2 * 1024 * 1024];
  17. static int s_width, s_height;
  18. static int onFLV(void* param, int codec, const void* data, size_t bytes, uint32_t pts, uint32_t dts, int flags)
  19. {
  20. mov_writer_t* mov = (mov_writer_t*)param;
  21. static int s_audio_track = -1;
  22. static int s_video_track = -1;
  23. switch(codec)
  24. {
  25. case FLV_AUDIO_AAC:
  26. return mov_writer_write(mov, s_audio_track, data, bytes, pts, dts, 1==flags ? MOV_AV_FLAG_KEYFREAME : 0);
  27. case FLV_AUDIO_OPUS:
  28. return mov_writer_write(mov, s_audio_track, data, bytes, pts, dts, 1 == flags ? MOV_AV_FLAG_KEYFREAME : 0);
  29. case FLV_AUDIO_MP3:
  30. if (-1 == s_audio_track)
  31. {
  32. struct mp3_header_t mp3;
  33. if (0 == mp3_header_load(&mp3, data, bytes))
  34. return -1;
  35. s_audio_track = mov_writer_add_audio(mov, MOV_OBJECT_MP3, mp3_get_channel(&mp3), 16, mp3_get_frequency(&mp3), NULL, 0);
  36. }
  37. if (-1 == s_audio_track)
  38. return -1;
  39. return mov_writer_write(mov, s_audio_track, data, bytes, pts, dts, 1 == flags ? MOV_AV_FLAG_KEYFREAME : 0);
  40. case FLV_VIDEO_H264:
  41. case FLV_VIDEO_H265:
  42. case FLV_VIDEO_AV1:
  43. return mov_writer_write(mov, s_video_track, data, bytes, pts, dts, flags);
  44. case FLV_VIDEO_AVCC:
  45. if (-1 == s_video_track)
  46. s_video_track = mov_writer_add_video(mov, MOV_OBJECT_H264, s_width, s_height, data, bytes);
  47. break;
  48. case FLV_VIDEO_HVCC:
  49. if (-1 == s_video_track)
  50. s_video_track = mov_writer_add_video(mov, MOV_OBJECT_HEVC, s_width, s_height, data, bytes);
  51. break;
  52. case FLV_VIDEO_AV1C:
  53. if (-1 == s_video_track)
  54. s_video_track = mov_writer_add_video(mov, MOV_OBJECT_AV1, s_width, s_height, data, bytes);
  55. break;
  56. case FLV_AUDIO_ASC:
  57. if (-1 == s_audio_track)
  58. {
  59. struct mpeg4_aac_t aac;
  60. mpeg4_aac_audio_specific_config_load((const uint8_t*)data, bytes, &aac);
  61. int rate = mpeg4_aac_audio_frequency_to((enum mpeg4_aac_frequency)aac.sampling_frequency_index);
  62. s_audio_track = mov_writer_add_audio(mov, MOV_OBJECT_AAC, aac.channel_configuration, 16, rate, data, bytes);
  63. }
  64. break;
  65. case FLV_AUDIO_OPUS_HEAD:
  66. if (-1 == s_audio_track)
  67. {
  68. struct opus_head_t opus;
  69. opus_head_load((const uint8_t*)data, bytes, &opus);
  70. s_audio_track = mov_writer_add_audio(mov, MOV_OBJECT_OPUS, opus.channels, 16, opus.input_sample_rate, data, bytes);
  71. }
  72. break;
  73. default:
  74. // nothing to do
  75. assert(FLV_SCRIPT_METADATA == codec);
  76. }
  77. printf("\n");
  78. return 0;
  79. }
  80. static int mov_writer_add_cover(mov_writer_t* mov, const char* cover)
  81. {
  82. static uint8_t s_cover_data[2 * 1024 * 1024];
  83. static uint8_t s_udta[2 * 1024 * 1024];
  84. FILE* fp = fopen(cover, "rb");
  85. if (!fp)
  86. return -1;
  87. int n = fread(s_cover_data, 1, sizeof(s_cover_data), fp);
  88. fclose(fp);
  89. assert(n < sizeof(s_cover_data)); // assert load all
  90. struct mov_udta_meta_t meta;
  91. memset(&meta, 0, sizeof(meta));
  92. meta.cover = s_cover_data;
  93. meta.cover_size = n;
  94. n = mov_udta_meta_write(&meta, s_udta, sizeof(s_udta));
  95. assert(n < sizeof(s_udta)); // check buffer size
  96. return mov_writer_add_udta(mov, s_udta, n);
  97. }
  98. void mov_writer_test(int w, int h, const char* inflv, const char* outmp4)
  99. {
  100. int r, type;
  101. size_t taglen;
  102. uint32_t timestamp;
  103. FILE* fp = fopen(outmp4, "wb+");
  104. void* flv = flv_reader_create(inflv);
  105. mov_writer_t* mov = mov_writer_create(mov_file_buffer(), fp, MOV_FLAG_FASTSTART);
  106. mov_writer_add_cover(mov, "cover.jpg");
  107. s_width = w;
  108. s_height = h;
  109. while (1 == flv_reader_read(flv, &type, &timestamp, &taglen, s_buffer, sizeof(s_buffer)))
  110. {
  111. r = flv_parser_tag(type, s_buffer, taglen, timestamp, onFLV, mov);
  112. assert(r >= 0);
  113. }
  114. mov_writer_destroy(mov);
  115. flv_reader_destroy(flv);
  116. fclose(fp);
  117. }