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.

mov-writer-audio.cpp 2.3KB

10 maanden geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "mov-writer.h"
  2. #include "mov-format.h"
  3. #include "mpeg4-aac.h"
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <assert.h>
  7. extern "C" const struct mov_buffer_t* mov_file_buffer(void);
  8. static uint8_t* file_read(const char* file, long* size)
  9. {
  10. FILE* fp = fopen(file, "rb");
  11. if (fp)
  12. {
  13. fseek(fp, 0, SEEK_END);
  14. *size = ftell(fp);
  15. fseek(fp, 0, SEEK_SET);
  16. uint8_t* ptr = (uint8_t*)malloc(*size);
  17. fread(ptr, 1, *size, fp);
  18. fclose(fp);
  19. return ptr;
  20. }
  21. return NULL;
  22. }
  23. static void g711_read_frame(mov_writer_t* mov, const uint8_t* ptr, const uint8_t* end)
  24. {
  25. int track = -1;
  26. int64_t pts = 0;
  27. while (ptr < end)
  28. {
  29. if (-1 == track)
  30. {
  31. track = mov_writer_add_audio(mov, MOV_OBJECT_G711a, 1, 16, 8000, NULL, 0);
  32. if(-1 == track) continue;
  33. }
  34. int n = ptr + 320 < end ? 320 : end - ptr;
  35. mov_writer_write(mov, track, ptr, n, pts, pts, 0);
  36. pts += n / 8; // 8000Hz/8-bits/1-channel
  37. ptr += n;
  38. }
  39. }
  40. static void aac_read_frame(mov_writer_t* mov, const uint8_t* ptr, const uint8_t* end)
  41. {
  42. int rate = 1;
  43. int track = -1;
  44. int64_t pts = 0;
  45. uint64_t samples = 1024; // aac frame
  46. struct mpeg4_aac_t aac;
  47. uint8_t extra_data[64 * 1024];
  48. while (ptr + 7 < end)
  49. {
  50. mpeg4_aac_adts_load(ptr, end - ptr, &aac);
  51. if (-1 == track)
  52. {
  53. int extra_data_size = mpeg4_aac_audio_specific_config_save(&aac, extra_data, sizeof(extra_data));
  54. rate = mpeg4_aac_audio_frequency_to((enum mpeg4_aac_frequency)aac.sampling_frequency_index);
  55. track = mov_writer_add_audio(mov, MOV_OBJECT_AAC, aac.channel_configuration, 16, rate, extra_data, extra_data_size);
  56. if (-1 == track) continue;
  57. assert(rate != 0);
  58. }
  59. int framelen = mpeg4_aac_adts_frame_length(ptr, end - ptr);
  60. mov_writer_write(mov, track, ptr + 7, framelen - 7, pts, pts, 0);
  61. samples += 1024;
  62. pts = samples * 1000 / rate;
  63. ptr += framelen;
  64. }
  65. }
  66. void mov_writer_audio(const char* audio, int type, const char* mp4)
  67. {
  68. long bytes = 0;
  69. uint8_t* ptr = file_read(audio, &bytes);
  70. if (NULL == ptr) return;
  71. FILE* fp = fopen(mp4, "wb+");
  72. mov_writer_t* mov = mov_writer_create(mov_file_buffer(), fp, MOV_FLAG_FASTSTART);
  73. switch (type)
  74. {
  75. case 1:
  76. aac_read_frame(mov, ptr, ptr + bytes);
  77. break;
  78. case 2:
  79. g711_read_frame(mov, ptr, ptr + bytes);
  80. break;
  81. default:
  82. assert(0);
  83. }
  84. mov_writer_destroy(mov);
  85. fclose(fp);
  86. free(ptr);
  87. }