encoder_aac.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. #include "encoder_aac.h"
  2. #include "headers_ffmpeg.h"
  3. #include "ring_buffer.h"
  4. #include "error_define.h"
  5. #include "log_helper.h"
  6. namespace am {
  7. encoder_aac::encoder_aac()
  8. {
  9. ffmpeg_register_all();
  10. _ring_buffer = new ring_buffer<AVFrame>(1024 * 1024 * 10);
  11. _inited = false;
  12. _running = false;
  13. _encoder = NULL;
  14. _encoder_ctx = NULL;
  15. _frame = NULL;
  16. _buff = NULL;
  17. _buff_size = 0;
  18. _bsf_ctx = NULL;
  19. _cond_notify = false;
  20. #ifdef SAVE_AAC
  21. _aac_io_ctx = NULL;
  22. _aac_stream = NULL;
  23. _aac_fmt_ctx = NULL;
  24. #endif
  25. }
  26. encoder_aac::~encoder_aac()
  27. {
  28. stop();
  29. cleanup();
  30. delete _ring_buffer;
  31. }
  32. int encoder_aac::init(int nb_channels, int sample_rate, AVSampleFormat fmt, int bit_rate)
  33. {
  34. int err = AE_NO;
  35. int ret = 0;
  36. if (_inited == true)
  37. return err;
  38. do {
  39. _encoder = (AVCodec*)avcodec_find_encoder(AV_CODEC_ID_AAC);
  40. if (!_encoder) {
  41. err = AE_FFMPEG_FIND_ENCODER_FAILED;
  42. break;
  43. }
  44. _encoder_ctx = avcodec_alloc_context3(_encoder);
  45. if (!_encoder_ctx) {
  46. err = AE_FFMPEG_ALLOC_CONTEXT_FAILED;
  47. break;
  48. }
  49. ffmpeg_set_channels(_encoder_ctx, nb_channels);
  50. ffmpeg_set_channel_layout(_encoder_ctx, ffmpeg_get_default_channel_layout(nb_channels));
  51. _encoder_ctx->sample_rate = sample_rate;
  52. _encoder_ctx->sample_fmt = fmt;
  53. _encoder_ctx->bit_rate = bit_rate;
  54. // 设置AAC profile为LC,确保RTMP兼容性
  55. _encoder_ctx->profile = FF_PROFILE_AAC_LOW;
  56. _encoder_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
  57. _encoder_ctx->time_base.den = sample_rate;
  58. _encoder_ctx->time_base.num = 1;
  59. // 设置编码器选项,确保生成高质量AAC数据
  60. AVDictionary *options = NULL;
  61. av_dict_set(&options, "aac_coder", "twoloop", 0);
  62. av_dict_set(&options, "aac_pns", "1", 0);
  63. av_dict_set(&options, "aac_is", "1", 0);
  64. av_dict_set(&options, "aac_ms", "1", 0);
  65. av_dict_set(&options, "aac_ltp", "0", 0);
  66. av_dict_set(&options, "aac_pred", "0", 0);
  67. // 强制启用ADTS头部格式,确保RTMP兼容性
  68. // 注意:"f"选项对编码器无效,需要在muxer层面处理ADTS格式
  69. // av_dict_set(&options, "f", "adts", 0);
  70. // 对于RTMP推流,确保生成ADTS头部
  71. // 不设置GLOBAL_HEADER,让每个包都包含ADTS头
  72. // _encoder_ctx->flags &= ~AV_CODEC_FLAG_GLOBAL_HEADER;
  73. // 由容器/复用层决定是否需要全局头,编码器保持默认行为(输出原始AAC帧)
  74. /* no manual change to GLOBAL_HEADER here */
  75. ret = avcodec_open2(_encoder_ctx, _encoder, &options);
  76. av_dict_free(&options);
  77. if (ret < 0) {
  78. err = AE_FFMPEG_OPEN_CODEC_FAILED;
  79. break;
  80. }
  81. // 调试信息:输出编码器配置
  82. al_debug("AAC encoder initialized: frame_size=%d, extradata_size=%d, profile=%d",
  83. _encoder_ctx->frame_size, _encoder_ctx->extradata_size, _encoder_ctx->profile);
  84. // 初始化BSF以适配必要的比特流转换
  85. // 目前不使用AAC相关BSF,编码器输出原始AAC帧,由复用器/容器处理(如写入ASC/ADTS等)
  86. _bsf_ctx = NULL;
  87. al_debug("No AAC BSF used; raw AAC frames will be passed to muxer for container-specific framing");
  88. /*
  89. const AVBitStreamFilter *bsf = av_bsf_get_by_name("aac_adtstoasc");
  90. if (!bsf) {
  91. al_error("Failed to find aac_adtstoasc BSF");
  92. err = AE_FFMPEG_FIND_BSF_FAILED;
  93. break;
  94. }
  95. ret = av_bsf_alloc(bsf, &_bsf_ctx);
  96. if (ret < 0) {
  97. al_error("Failed to allocate BSF context: %d", ret);
  98. err = AE_FFMPEG_ALLOC_BSF_FAILED;
  99. break;
  100. }
  101. // 复制编码器参数到BSF
  102. ret = avcodec_parameters_from_context(_bsf_ctx->par_in, _encoder_ctx);
  103. if (ret < 0) {
  104. al_error("Failed to copy parameters to BSF: %d", ret);
  105. err = AE_FFMPEG_BSF_PARAMS_FAILED;
  106. break;
  107. }
  108. ret = av_bsf_init(_bsf_ctx);
  109. if (ret < 0) {
  110. al_error("Failed to initialize BSF: %d", ret);
  111. err = AE_FFMPEG_BSF_INIT_FAILED;
  112. break;
  113. }
  114. al_debug("BSF initialized successfully for ADTS conversion");
  115. */
  116. // 确保frame_size有效
  117. if (_encoder_ctx->frame_size <= 0) {
  118. al_warn("AAC encoder frame_size is invalid: %d, setting to 1024", _encoder_ctx->frame_size);
  119. _encoder_ctx->frame_size = 1024;
  120. }
  121. _buff_size = av_samples_get_buffer_size(NULL, nb_channels, _encoder_ctx->frame_size, fmt, 1);
  122. _buff = (uint8_t *) av_malloc(_buff_size);
  123. _frame = av_frame_alloc();
  124. if (!_frame) {
  125. err = AE_FFMPEG_ALLOC_FRAME_FAILED;
  126. break;
  127. }
  128. ffmpeg_set_frame_channels(_frame, nb_channels);
  129. _frame->nb_samples = _encoder_ctx->frame_size;
  130. ffmpeg_set_frame_channel_layout(_frame, ffmpeg_get_default_channel_layout(nb_channels));
  131. _frame->format = fmt;
  132. _frame->sample_rate = sample_rate;
  133. ret = avcodec_fill_audio_frame(_frame, nb_channels, fmt, _buff, _buff_size, 0);
  134. #ifdef SAVE_AAC
  135. ret = avio_open(&_aac_io_ctx, "save.aac", AVIO_FLAG_READ_WRITE);
  136. if (ret < 0) {
  137. err = AE_FFMPEG_OPEN_IO_FAILED;
  138. break;
  139. }
  140. _aac_fmt_ctx = avformat_alloc_context();
  141. if (!_aac_fmt_ctx) {
  142. err = AE_FFMPEG_ALLOC_CONTEXT_FAILED;
  143. break;
  144. }
  145. _aac_fmt_ctx->pb = _aac_io_ctx;
  146. _aac_fmt_ctx->oformat = av_guess_format(NULL, "save.aac", NULL);
  147. _aac_fmt_ctx->url = av_strdup("save.aac");
  148. _aac_stream = avformat_new_stream(_aac_fmt_ctx, NULL);
  149. if (!_aac_stream) {
  150. err = AE_FFMPEG_CREATE_STREAM_FAILED;
  151. break;
  152. }
  153. ret = avcodec_parameters_from_context(_aac_stream->codecpar, _encoder_ctx);
  154. if (ret < 0) {
  155. err = AE_FFMPEG_COPY_PARAMS_FAILED;
  156. break;
  157. }
  158. if (_aac_fmt_ctx->oformat->flags | AV_CODEC_FLAG_GLOBAL_HEADER) {
  159. _aac_stream->codec->extradata_size
  160. = _encoder_ctx->extradata_size; // +AV_INPUT_BUFFER_PADDING_SIZE;
  161. _aac_stream->codec->extradata = (uint8_t *) av_memdup(_encoder_ctx->extradata,
  162. _encoder_ctx->extradata_size);
  163. }
  164. #endif
  165. _inited = true;
  166. } while (0);
  167. if (err != AE_NO) {
  168. al_debug("%s,error:%d", err2str(err), ret);
  169. cleanup();
  170. }
  171. return err;
  172. }
  173. int encoder_aac::get_extradata_size()
  174. {
  175. return _encoder_ctx->extradata_size;
  176. }
  177. const uint8_t *encoder_aac::get_extradata()
  178. {
  179. return (const uint8_t *) _encoder_ctx->extradata;
  180. }
  181. int encoder_aac::get_nb_samples()
  182. {
  183. return _encoder_ctx->frame_size;
  184. }
  185. int encoder_aac::start()
  186. {
  187. int error = AE_NO;
  188. if (_running == true) {
  189. return error;
  190. }
  191. if (_inited == false) {
  192. return AE_NEED_INIT;
  193. }
  194. _running = true;
  195. _thread = std::thread(std::bind(&encoder_aac::encode_loop, this));
  196. return error;
  197. }
  198. void encoder_aac::stop()
  199. {
  200. _running = false;
  201. _cond_notify = true;
  202. _cond_var.notify_all();
  203. if (_thread.joinable())
  204. _thread.join();
  205. }
  206. int encoder_aac::put(const uint8_t *data, int data_len, AVFrame *frame)
  207. {
  208. std::unique_lock<std::mutex> lock(_mutex);
  209. AVFrame frame_cp;
  210. memcpy(&frame_cp, frame, sizeof(AVFrame));
  211. _ring_buffer->put(data, data_len, frame_cp);
  212. _cond_notify = true;
  213. _cond_var.notify_all();
  214. return 0;
  215. }
  216. const AVRational &encoder_aac::get_time_base()
  217. {
  218. return _encoder_ctx->time_base;
  219. }
  220. AVCodecID encoder_aac::get_codec_id()
  221. {
  222. if (_inited == false)
  223. return AV_CODEC_ID_NONE;
  224. return _encoder->id;
  225. }
  226. int encoder_aac::encode(AVFrame *frame, AVPacket *packet)
  227. {
  228. // 添加输入帧验证
  229. if (frame) {
  230. al_debug("Input frame: samples=%d, channels=%d, format=%d, pts=%lld",
  231. frame->nb_samples, ffmpeg_get_frame_channels(frame), frame->format, frame->pts);
  232. }
  233. int ret = avcodec_send_frame(_encoder_ctx, frame);
  234. al_debug("avcodec_send_frame returned: %d", ret);
  235. if (ret < 0) {
  236. al_error("avcodec_send_frame failed: %d", ret);
  237. return AE_FFMPEG_ENCODE_FRAME_FAILED;
  238. }
  239. bool packetReceived = false;
  240. while (ret == 0) {
  241. av_init_packet(packet);
  242. ret = avcodec_receive_packet(_encoder_ctx, packet);
  243. al_debug("avcodec_receive_packet returned: %d", ret);
  244. if (ret == AVERROR(EAGAIN)) {
  245. al_debug("Encoder needs more input: %d (this is normal)", ret);
  246. break; // 需要更多输入,这是正常情况
  247. }
  248. if (ret == AVERROR_EOF) {
  249. al_debug("Encoder EOF: %d", ret);
  250. break; // 编码器已结束
  251. }
  252. if (ret < 0) {
  253. al_error("avcodec_receive_packet failed: %d", ret);
  254. return AE_FFMPEG_READ_PACKET_FAILED;
  255. }
  256. if (ret == 0) {
  257. packetReceived = true;
  258. // 如果输入帧有有效的时间戳,将其传递给输出包
  259. if (frame && frame->pts != AV_NOPTS_VALUE) {
  260. packet->pts = frame->pts;
  261. packet->dts = frame->pts; // 对于音频,通常dts等于pts
  262. al_debug("Timestamp inherited from frame: pts=%lld, dts=%lld", packet->pts, packet->dts);
  263. } else {
  264. al_warn("Input frame has invalid timestamp (AV_NOPTS_VALUE), packet will have invalid timestamp");
  265. }
  266. // 验证编码器输出的包有效性
  267. if (packet->data == nullptr || packet->size <= 0) {
  268. al_warn("AAC packet is empty, skipping");
  269. av_packet_unref(packet);
  270. continue;
  271. }
  272. // 不再手动添加ADTS头部,完全由复用器/容器处理需要的打包格式
  273. al_debug("AAC packet ready: size=%d, pts=%lld, dts=%lld",
  274. packet->size, packet->pts, packet->dts);
  275. if (_on_data)
  276. _on_data(packet);
  277. }
  278. #ifdef SAVE_AAC
  279. av_packet_rescale_ts(packet, _encoder_ctx->time_base, _aac_stream->time_base);
  280. packet->stream_index = _aac_stream->index;
  281. av_write_frame(_aac_fmt_ctx, packet);
  282. #endif
  283. av_packet_unref(packet);
  284. }
  285. // 如果没有收到数据包且不是EAGAIN错误,可能有问题
  286. if (!packetReceived && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
  287. al_warn("No packet received and unexpected return code: %d", ret);
  288. }
  289. return AE_NO;
  290. }
  291. void encoder_aac::encode_loop()
  292. {
  293. int len = 0;
  294. int error = AE_NO;
  295. AVPacket *packet = av_packet_alloc();
  296. AVFrame pcm_frame;
  297. #ifdef SAVE_AAC
  298. avformat_write_header(_aac_fmt_ctx, NULL);
  299. #endif
  300. while (_running) {
  301. std::unique_lock<std::mutex> lock(_mutex);
  302. // 改为基于条件的等待,避免固定50ms超时带来的延迟抖动
  303. _cond_var.wait(lock, [this] { return _cond_notify || !_running; });
  304. if (!_running)
  305. break;
  306. while ((len = _ring_buffer->get(_buff, _buff_size, pcm_frame))) {
  307. // 验证获取的音频数据
  308. if (len <= 0) {
  309. al_warn("Invalid audio data length: %d", len);
  310. continue;
  311. }
  312. // 确保音频数据正确填充到frame中
  313. if (len != _buff_size) {
  314. al_warn("Audio data size mismatch: expected=%d, actual=%d", _buff_size, len);
  315. }
  316. // 添加详细的调试信息
  317. static int frameCounter = 0;
  318. if (++frameCounter % 100 == 0) { // 每100帧打印一次
  319. al_debug("Ring buffer data: len=%d, buff_size=%d, frame_size=%d, channels=%d, format=%d",
  320. len, _buff_size, _encoder_ctx->frame_size,
  321. ffmpeg_get_frame_channels(_frame), _frame->format);
  322. }
  323. _frame->pts = pcm_frame.pts;
  324. #if FFMPEG_VERSION_MAJOR >= 7
  325. // In FFmpeg 7+, pkt_pts is removed, use pts instead
  326. // _frame->pts is already set above
  327. #else
  328. _frame->pkt_pts = pcm_frame.pkt_pts;
  329. #endif
  330. _frame->pkt_dts = pcm_frame.pkt_dts;
  331. // 验证编码器帧的配置
  332. if (_frame->nb_samples != _encoder_ctx->frame_size) {
  333. al_warn("Frame samples mismatch: frame->nb_samples=%d, encoder->frame_size=%d",
  334. _frame->nb_samples, _encoder_ctx->frame_size);
  335. }
  336. int error = encode(_frame, packet);
  337. if (error != AE_NO) {
  338. if (_on_error)
  339. _on_error(error);
  340. al_fatal("encode aac packet failed:%d", error);
  341. break;
  342. }
  343. }
  344. _cond_notify = false;
  345. }
  346. //flush pcm data in encoder
  347. al_debug("Flushing remaining AAC data from encoder");
  348. int flush_error = encode(NULL, packet);
  349. if (flush_error != AE_NO) {
  350. al_warn("Error during AAC encoder flush: %d", flush_error);
  351. }
  352. av_packet_free(&packet);
  353. // 输出编码统计信息
  354. al_info("AAC encoder stopped. Encoding session completed.");
  355. #ifdef SAVE_AAC
  356. av_write_trailer(_aac_fmt_ctx);
  357. #endif
  358. }
  359. void encoder_aac::cleanup()
  360. {
  361. if (_encoder) {
  362. avcodec_close(_encoder_ctx);
  363. }
  364. _encoder = NULL;
  365. if (_encoder_ctx) {
  366. avcodec_free_context(&_encoder_ctx);
  367. }
  368. if (_frame)
  369. av_free(_frame);
  370. _frame = NULL;
  371. if (_buff)
  372. av_free(_buff);
  373. _buff = NULL;
  374. if (_bsf_ctx) {
  375. av_bsf_free(&_bsf_ctx);
  376. _bsf_ctx = NULL;
  377. }
  378. _encoder_ctx = NULL;
  379. #ifdef SAVE_AAC
  380. if (_aac_fmt_ctx) {
  381. avio_closep(&_aac_fmt_ctx->pb);
  382. avformat_free_context(_aac_fmt_ctx);
  383. }
  384. #endif
  385. }
  386. int encoder_aac::add_adts_header(AVPacket *packet)
  387. {
  388. if (!packet || !packet->data || packet->size <= 0) {
  389. al_error("Invalid packet for ADTS header addition");
  390. return AE_INVALID_CONTEXT;
  391. }
  392. // ADTS头部长度为7字节
  393. const int adts_header_size = 7;
  394. const int new_size = packet->size + adts_header_size;
  395. // 生成ADTS头部
  396. uint8_t adts_header[adts_header_size];
  397. // 获取编码器参数
  398. int sample_rate = _encoder_ctx->sample_rate;
  399. int channels = ffmpeg_get_codec_context_channels(_encoder_ctx);
  400. int profile = _encoder_ctx->profile; // AAC-LC = 1
  401. // 采样率索引映射
  402. int freq_idx = 4; // 默认44100Hz
  403. switch (sample_rate) {
  404. case 96000: freq_idx = 0; break;
  405. case 88200: freq_idx = 1; break;
  406. case 64000: freq_idx = 2; break;
  407. case 48000: freq_idx = 3; break;
  408. case 44100: freq_idx = 4; break;
  409. case 32000: freq_idx = 5; break;
  410. case 24000: freq_idx = 6; break;
  411. case 22050: freq_idx = 7; break;
  412. case 16000: freq_idx = 8; break;
  413. case 12000: freq_idx = 9; break;
  414. case 11025: freq_idx = 10; break;
  415. case 8000: freq_idx = 11; break;
  416. default: freq_idx = 4; break;
  417. }
  418. // 声道配置
  419. int channel_config = channels;
  420. if (channels > 6) channel_config = 0; // 自定义配置
  421. // 构建ADTS头部
  422. adts_header[0] = 0xFF; // syncword (12 bits) - 高8位
  423. adts_header[1] = 0xF0 | (0 << 3) | (0 << 2) | 1; // syncword低4位 + MPEG版本 + Layer + protection_absent
  424. adts_header[2] = ((profile - 1) << 6) | (freq_idx << 2) | (0 << 1) | ((channel_config >> 2) & 1);
  425. adts_header[3] = ((channel_config & 3) << 6) | (0 << 5) | (0 << 4) | (0 << 3) | ((new_size >> 11) & 3);
  426. adts_header[4] = (new_size >> 3) & 0xFF;
  427. adts_header[5] = ((new_size & 7) << 5) | 0x1F;
  428. adts_header[6] = 0xFC; // number_of_raw_data_blocks_in_frame (2 bits) + 6位填充
  429. // 备份原始包的时间戳与元数据
  430. int64_t old_pts = packet->pts;
  431. int64_t old_dts = packet->dts;
  432. int64_t old_duration = packet->duration;
  433. int old_flags = packet->flags;
  434. int old_stream_index = packet->stream_index;
  435. int64_t old_pos = packet->pos;
  436. // 创建新包并拷贝数据(头部+原数据),以避免清空原包导致PTS/DTS丢失
  437. AVPacket *new_pkt = av_packet_alloc();
  438. if (!new_pkt) {
  439. al_error("Failed to allocate AVPacket for ADTS header");
  440. return AE_FFMPEG_ALLOC_FRAME_FAILED;
  441. }
  442. if (av_new_packet(new_pkt, new_size) < 0) {
  443. av_packet_free(&new_pkt);
  444. al_error("Failed to allocate packet buffer for ADTS header");
  445. return AE_FFMPEG_ALLOC_FRAME_FAILED;
  446. }
  447. // 拷贝ADTS头部和原始数据
  448. memcpy(new_pkt->data, adts_header, adts_header_size);
  449. memcpy(new_pkt->data + adts_header_size, packet->data, packet->size);
  450. // 恢复时间戳与元数据
  451. new_pkt->pts = old_pts;
  452. new_pkt->dts = old_dts;
  453. new_pkt->duration = old_duration;
  454. new_pkt->flags = old_flags;
  455. new_pkt->stream_index = old_stream_index;
  456. new_pkt->pos = old_pos;
  457. // 用新包替换旧包
  458. av_packet_unref(packet);
  459. av_packet_move_ref(packet, new_pkt);
  460. av_packet_free(&new_pkt);
  461. al_debug("ADTS header added: total_size=%d, profile=%d, freq_idx=%d, channels=%d (pts=%lld, dts=%lld)",
  462. new_size, profile, freq_idx, channels, packet->pts, packet->dts);
  463. return AE_NO;
  464. }
  465. } // namespace am