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.

113 satır
2.6KB

  1. #include "mkv-writer.h"
  2. #include "mkv-format.h"
  3. #include "mpeg4-aac.h"
  4. #include "riff-acm.h"
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <assert.h>
  9. static uint8_t* file_read(const char* file, long* size)
  10. {
  11. FILE* fp = fopen(file, "rb");
  12. if (fp)
  13. {
  14. fseek(fp, 0, SEEK_END);
  15. *size = ftell(fp);
  16. fseek(fp, 0, SEEK_SET);
  17. uint8_t* ptr = (uint8_t*)malloc(*size);
  18. fread(ptr, 1, *size, fp);
  19. fclose(fp);
  20. return ptr;
  21. }
  22. return NULL;
  23. }
  24. static void g711_read_frame(mkv_writer_t* mkv, const uint8_t* ptr, const uint8_t* end)
  25. {
  26. int track = -1;
  27. int64_t pts = 0;
  28. while (ptr < end)
  29. {
  30. if (-1 == track)
  31. {
  32. struct wave_format_t wav;
  33. memset(&wav, 0, sizeof(wav));
  34. wav.wFormatTag = WAVE_FORMAT_ALAW;
  35. wav.nChannels = 1;
  36. wav.nSamplesPerSec = 8000;
  37. wav.nAvgBytesPerSec = 8000;
  38. wav.nBlockAlign = 1;
  39. wav.wBitsPerSample = 8;
  40. uint8_t data[18];
  41. int n = wave_format_save(&wav, data, sizeof(data));
  42. track = mkv_writer_add_audio(mkv, MKV_CODEC_AUDIO_ACM, 1, 16, 8000, data, n);
  43. if (-1 == track) continue;
  44. }
  45. int n = ptr + 320 < end ? 320 : end - ptr;
  46. mkv_writer_write(mkv, track, ptr, n, pts, pts, 0);
  47. pts += n / 8; // 8000Hz/8-bits/1-channel
  48. ptr += n;
  49. }
  50. }
  51. static void aac_read_frame(mkv_writer_t* mkv, const uint8_t* ptr, const uint8_t* end)
  52. {
  53. int rate = 1;
  54. int track = -1;
  55. int64_t pts = 0;
  56. uint64_t samples = 1024; // aac frame
  57. struct mpeg4_aac_t aac;
  58. uint8_t extra_data[64 * 1024];
  59. while (ptr + 7 < end)
  60. {
  61. mpeg4_aac_adts_load(ptr, end - ptr, &aac);
  62. if (-1 == track)
  63. {
  64. int extra_data_size = mpeg4_aac_audio_specific_config_save(&aac, extra_data, sizeof(extra_data));
  65. rate = mpeg4_aac_audio_frequency_to((enum mpeg4_aac_frequency)aac.sampling_frequency_index);
  66. track = mkv_writer_add_audio(mkv, MKV_CODEC_AUDIO_AAC, aac.channel_configuration, 16, rate, extra_data, extra_data_size);
  67. if (-1 == track) continue;
  68. assert(rate != 0);
  69. }
  70. int framelen = mpeg4_aac_adts_frame_length(ptr, end - ptr);
  71. mkv_writer_write(mkv, track, ptr + 7, framelen - 7, pts, pts, 0);
  72. pts += samples * 1000 / rate;
  73. ptr += framelen;
  74. }
  75. }
  76. void mkv_writer_audio(const char* audio, int type, const char* out)
  77. {
  78. long bytes = 0;
  79. uint8_t* ptr = file_read(audio, &bytes);
  80. if (NULL == ptr) return;
  81. struct mkv_file_cache_t wfile;
  82. memset(&wfile, 0, sizeof(wfile));
  83. wfile.fp = fopen(out, "wb+");
  84. mkv_writer_t* mkv = mkv_writer_create(mkv_file_cache_buffer(), &wfile, 0);
  85. switch (type)
  86. {
  87. case 1:
  88. aac_read_frame(mkv, ptr, ptr + bytes);
  89. break;
  90. case 2:
  91. g711_read_frame(mkv, ptr, ptr + bytes);
  92. break;
  93. default:
  94. assert(0);
  95. }
  96. mkv_writer_destroy(mkv);
  97. fclose(wfile.fp);
  98. free(ptr);
  99. }