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.

121 lines
3.2KB

  1. #include "mkv-writer.h"
  2. #include "mkv-format.h"
  3. #include "mpeg4-aac.h"
  4. #include "opus-head.h"
  5. #include "mp3-header.h"
  6. #include "flv-proto.h"
  7. #include "flv-reader.h"
  8. #include "flv-parser.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <assert.h>
  13. extern "C" const struct mkv_buffer_t* mkv_file_buffer(void);
  14. static uint8_t s_buffer[2 * 1024 * 1024];
  15. static int s_width, s_height;
  16. static int onFLV(void* param, int codec, const void* data, size_t bytes, uint32_t pts, uint32_t dts, int flags)
  17. {
  18. mkv_writer_t* mkv = (mkv_writer_t*)param;
  19. static int s_audio_track = -1;
  20. static int s_video_track = -1;
  21. switch(codec)
  22. {
  23. case FLV_AUDIO_AAC:
  24. return mkv_writer_write(mkv, s_audio_track, data, bytes, pts, dts, 0);
  25. case FLV_AUDIO_OPUS:
  26. return mkv_writer_write(mkv, s_audio_track, data, bytes, pts, dts, 0);
  27. case FLV_AUDIO_MP3:
  28. if (-1 == s_audio_track)
  29. {
  30. struct mp3_header_t mp3;
  31. if (0 == mp3_header_load(&mp3, data, bytes))
  32. return -1;
  33. s_audio_track = mkv_writer_add_audio(mkv, MKV_CODEC_AUDIO_MP3, mp3_get_channel(&mp3), 16, mp3_get_frequency(&mp3), NULL, 0);
  34. }
  35. if (-1 == s_audio_track)
  36. return -1;
  37. return mkv_writer_write(mkv, s_audio_track, data, bytes, pts, dts, 0);
  38. case FLV_VIDEO_H264:
  39. case FLV_VIDEO_H265:
  40. case FLV_VIDEO_AV1:
  41. return mkv_writer_write(mkv, s_video_track, data, bytes, pts, dts, 1 == flags ? MKV_FLAGS_KEYFRAME : 0);
  42. case FLV_VIDEO_AVCC:
  43. if (-1 == s_video_track)
  44. s_video_track = mkv_writer_add_video(mkv, MKV_CODEC_VIDEO_H264, s_width, s_height, data, bytes);
  45. break;
  46. case FLV_VIDEO_HVCC:
  47. if (-1 == s_video_track)
  48. s_video_track = mkv_writer_add_video(mkv, MKV_CODEC_VIDEO_H265, s_width, s_height, data, bytes);
  49. break;
  50. case FLV_VIDEO_AV1C:
  51. if (-1 == s_video_track)
  52. s_video_track = mkv_writer_add_video(mkv, MKV_CODEC_VIDEO_AV1, s_width, s_height, data, bytes);
  53. break;
  54. case FLV_AUDIO_ASC:
  55. if (-1 == s_audio_track)
  56. {
  57. struct mpeg4_aac_t aac;
  58. mpeg4_aac_audio_specific_config_load((const uint8_t*)data, bytes, &aac);
  59. int rate = mpeg4_aac_audio_frequency_to((enum mpeg4_aac_frequency)aac.sampling_frequency_index);
  60. s_audio_track = mkv_writer_add_audio(mkv, MKV_CODEC_AUDIO_AAC, aac.channel_configuration, 16, rate, data, bytes);
  61. }
  62. break;
  63. case FLV_AUDIO_OPUS_HEAD:
  64. if (-1 == s_audio_track)
  65. {
  66. struct opus_head_t opus;
  67. opus_head_load((const uint8_t*)data, bytes, &opus);
  68. s_audio_track = mkv_writer_add_audio(mkv, MKV_CODEC_AUDIO_OPUS, opus.channels, 16, opus.input_sample_rate, data, bytes);
  69. }
  70. break;
  71. case 0: // script
  72. break;
  73. default:
  74. // nothing to do
  75. assert(0);
  76. }
  77. printf("\n");
  78. return 0;
  79. }
  80. void mkv_writer_test(int w, int h, const char* inflv, const char* outmkv)
  81. {
  82. int r, type;
  83. size_t taglen;
  84. uint32_t timestamp;
  85. struct mkv_file_cache_t wfile;
  86. memset(&wfile, 0, sizeof(wfile));
  87. wfile.fp = fopen(outmkv, "wb+");
  88. void* flv = flv_reader_create(inflv);
  89. mkv_writer_t* mkv = mkv_writer_create(mkv_file_cache_buffer(), &wfile, 0);
  90. s_width = w;
  91. s_height = h;
  92. while (1 == flv_reader_read(flv, &type, &timestamp, &taglen, s_buffer, sizeof(s_buffer)))
  93. {
  94. r = flv_parser_tag(type, s_buffer, taglen, timestamp, onFLV, mkv);
  95. assert(r >= 0);
  96. }
  97. mkv_writer_destroy(mkv);
  98. flv_reader_destroy(flv);
  99. fclose(wfile.fp);
  100. }