encoder_aac.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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. ret = avcodec_open2(_encoder_ctx, _encoder, &options);
  74. av_dict_free(&options);
  75. if (ret < 0) {
  76. err = AE_FFMPEG_OPEN_CODEC_FAILED;
  77. break;
  78. }
  79. // 调试信息:输出编码器配置
  80. al_debug("AAC encoder initialized: frame_size=%d, extradata_size=%d, profile=%d",
  81. _encoder_ctx->frame_size, _encoder_ctx->extradata_size, _encoder_ctx->profile);
  82. // 初始化BSF将raw AAC转换为ADTS格式
  83. // 注意:我们需要手动添加ADTS头部,因为没有直接的BSF可以将raw AAC转换为ADTS
  84. // 暂时跳过BSF初始化,使用手动ADTS头部添加
  85. _bsf_ctx = NULL;
  86. al_debug("Skipping BSF initialization, will add ADTS headers manually");
  87. /*
  88. const AVBitStreamFilter *bsf = av_bsf_get_by_name("aac_adtstoasc");
  89. if (!bsf) {
  90. al_error("Failed to find aac_adtstoasc BSF");
  91. err = AE_FFMPEG_FIND_BSF_FAILED;
  92. break;
  93. }
  94. ret = av_bsf_alloc(bsf, &_bsf_ctx);
  95. if (ret < 0) {
  96. al_error("Failed to allocate BSF context: %d", ret);
  97. err = AE_FFMPEG_ALLOC_BSF_FAILED;
  98. break;
  99. }
  100. // 复制编码器参数到BSF
  101. ret = avcodec_parameters_from_context(_bsf_ctx->par_in, _encoder_ctx);
  102. if (ret < 0) {
  103. al_error("Failed to copy parameters to BSF: %d", ret);
  104. err = AE_FFMPEG_BSF_PARAMS_FAILED;
  105. break;
  106. }
  107. ret = av_bsf_init(_bsf_ctx);
  108. if (ret < 0) {
  109. al_error("Failed to initialize BSF: %d", ret);
  110. err = AE_FFMPEG_BSF_INIT_FAILED;
  111. break;
  112. }
  113. al_debug("BSF initialized successfully for ADTS conversion");
  114. */
  115. // 确保frame_size有效
  116. if (_encoder_ctx->frame_size <= 0) {
  117. al_warn("AAC encoder frame_size is invalid: %d, setting to 1024", _encoder_ctx->frame_size);
  118. _encoder_ctx->frame_size = 1024;
  119. }
  120. _buff_size = av_samples_get_buffer_size(NULL, nb_channels, _encoder_ctx->frame_size, fmt, 1);
  121. _buff = (uint8_t *) av_malloc(_buff_size);
  122. _frame = av_frame_alloc();
  123. if (!_frame) {
  124. err = AE_FFMPEG_ALLOC_FRAME_FAILED;
  125. break;
  126. }
  127. ffmpeg_set_frame_channels(_frame, nb_channels);
  128. _frame->nb_samples = _encoder_ctx->frame_size;
  129. ffmpeg_set_frame_channel_layout(_frame, ffmpeg_get_default_channel_layout(nb_channels));
  130. _frame->format = fmt;
  131. _frame->sample_rate = sample_rate;
  132. ret = avcodec_fill_audio_frame(_frame, nb_channels, fmt, _buff, _buff_size, 0);
  133. #ifdef SAVE_AAC
  134. ret = avio_open(&_aac_io_ctx, "save.aac", AVIO_FLAG_READ_WRITE);
  135. if (ret < 0) {
  136. err = AE_FFMPEG_OPEN_IO_FAILED;
  137. break;
  138. }
  139. _aac_fmt_ctx = avformat_alloc_context();
  140. if (!_aac_fmt_ctx) {
  141. err = AE_FFMPEG_ALLOC_CONTEXT_FAILED;
  142. break;
  143. }
  144. _aac_fmt_ctx->pb = _aac_io_ctx;
  145. _aac_fmt_ctx->oformat = av_guess_format(NULL, "save.aac", NULL);
  146. _aac_fmt_ctx->url = av_strdup("save.aac");
  147. _aac_stream = avformat_new_stream(_aac_fmt_ctx, NULL);
  148. if (!_aac_stream) {
  149. err = AE_FFMPEG_CREATE_STREAM_FAILED;
  150. break;
  151. }
  152. ret = avcodec_parameters_from_context(_aac_stream->codecpar, _encoder_ctx);
  153. if (ret < 0) {
  154. err = AE_FFMPEG_COPY_PARAMS_FAILED;
  155. break;
  156. }
  157. if (_aac_fmt_ctx->oformat->flags | AV_CODEC_FLAG_GLOBAL_HEADER) {
  158. _aac_stream->codec->extradata_size
  159. = _encoder_ctx->extradata_size; // +AV_INPUT_BUFFER_PADDING_SIZE;
  160. _aac_stream->codec->extradata = (uint8_t *) av_memdup(_encoder_ctx->extradata,
  161. _encoder_ctx->extradata_size);
  162. }
  163. #endif
  164. _inited = true;
  165. } while (0);
  166. if (err != AE_NO) {
  167. al_debug("%s,error:%d", err2str(err), ret);
  168. cleanup();
  169. }
  170. return err;
  171. }
  172. int encoder_aac::get_extradata_size()
  173. {
  174. return _encoder_ctx->extradata_size;
  175. }
  176. const uint8_t *encoder_aac::get_extradata()
  177. {
  178. return (const uint8_t *) _encoder_ctx->extradata;
  179. }
  180. int encoder_aac::get_nb_samples()
  181. {
  182. return _encoder_ctx->frame_size;
  183. }
  184. int encoder_aac::start()
  185. {
  186. int error = AE_NO;
  187. if (_running == true) {
  188. return error;
  189. }
  190. if (_inited == false) {
  191. return AE_NEED_INIT;
  192. }
  193. _running = true;
  194. _thread = std::thread(std::bind(&encoder_aac::encode_loop, this));
  195. return error;
  196. }
  197. void encoder_aac::stop()
  198. {
  199. _running = false;
  200. _cond_notify = true;
  201. _cond_var.notify_all();
  202. if (_thread.joinable())
  203. _thread.join();
  204. }
  205. int encoder_aac::put(const uint8_t *data, int data_len, AVFrame *frame)
  206. {
  207. std::unique_lock<std::mutex> lock(_mutex);
  208. AVFrame frame_cp;
  209. memcpy(&frame_cp, frame, sizeof(AVFrame));
  210. _ring_buffer->put(data, data_len, frame_cp);
  211. _cond_notify = true;
  212. _cond_var.notify_all();
  213. return 0;
  214. }
  215. const AVRational &encoder_aac::get_time_base()
  216. {
  217. return _encoder_ctx->time_base;
  218. }
  219. AVCodecID encoder_aac::get_codec_id()
  220. {
  221. if (_inited == false)
  222. return AV_CODEC_ID_NONE;
  223. return _encoder->id;
  224. }
  225. int encoder_aac::encode(AVFrame *frame, AVPacket *packet)
  226. {
  227. // 添加输入帧验证
  228. if (frame) {
  229. al_debug("Input frame: samples=%d, channels=%d, format=%d, pts=%lld",
  230. frame->nb_samples, ffmpeg_get_frame_channels(frame), frame->format, frame->pts);
  231. }
  232. int ret = avcodec_send_frame(_encoder_ctx, frame);
  233. al_debug("avcodec_send_frame returned: %d", ret);
  234. if (ret < 0) {
  235. al_error("avcodec_send_frame failed: %d", ret);
  236. return AE_FFMPEG_ENCODE_FRAME_FAILED;
  237. }
  238. bool packetReceived = false;
  239. while (ret == 0) {
  240. av_init_packet(packet);
  241. ret = avcodec_receive_packet(_encoder_ctx, packet);
  242. al_debug("avcodec_receive_packet returned: %d", ret);
  243. if (ret == AVERROR(EAGAIN)) {
  244. al_debug("Encoder needs more input: %d (this is normal)", ret);
  245. break; // 需要更多输入,这是正常情况
  246. }
  247. if (ret == AVERROR_EOF) {
  248. al_debug("Encoder EOF: %d", ret);
  249. break; // 编码器已结束
  250. }
  251. if (ret < 0) {
  252. al_error("avcodec_receive_packet failed: %d", ret);
  253. return AE_FFMPEG_READ_PACKET_FAILED;
  254. }
  255. if (ret == 0) {
  256. packetReceived = true;
  257. // 如果输入帧有有效的时间戳,将其传递给输出包
  258. if (frame && frame->pts != AV_NOPTS_VALUE) {
  259. packet->pts = frame->pts;
  260. packet->dts = frame->pts; // 对于音频,通常dts等于pts
  261. al_debug("Timestamp inherited from frame: pts=%lld, dts=%lld", packet->pts, packet->dts);
  262. } else {
  263. al_warn("Input frame has invalid timestamp (AV_NOPTS_VALUE), packet will have invalid timestamp");
  264. }
  265. // 立即检查编码器输出的原始包大小
  266. al_debug("Raw encoder output: size=%d, data=%p", packet->size, packet->data);
  267. // 验证AAC数据包的有效性
  268. if (packet->data == nullptr) {
  269. al_warn("AAC packet data is null, skipping");
  270. av_packet_unref(packet);
  271. continue;
  272. }
  273. // 验证音频包大小,确保符合RTMP要求
  274. // AAC数据包至少需要包含ADTS头部(7字节)+ 音频数据
  275. if (packet->size < 7) {
  276. al_warn("AAC packet size too small: %d bytes (minimum 7 required), skipping", packet->size);
  277. av_packet_unref(packet);
  278. continue;
  279. }
  280. // 检查ADTS头部的同步字(0xFFF)
  281. if (packet->size >= 2 && (packet->data[0] != 0xFF || (packet->data[1] & 0xF0) != 0xF0)) {
  282. al_debug("Raw AAC data detected, adding ADTS header");
  283. // 为raw AAC数据添加ADTS头部
  284. int adts_ret = add_adts_header(packet);
  285. if (adts_ret != AE_NO) {
  286. al_error("Failed to add ADTS header: %d", adts_ret);
  287. av_packet_unref(packet);
  288. continue;
  289. }
  290. } else {
  291. al_debug("ADTS header already present");
  292. }
  293. al_debug("AAC packet: size=%d, pts=%lld, dts=%lld, header=0x%02X%02X",
  294. packet->size, packet->pts, packet->dts,
  295. packet->size >= 2 ? packet->data[0] : 0,
  296. packet->size >= 2 ? packet->data[1] : 0);
  297. if (_on_data)
  298. _on_data(packet);
  299. }
  300. #ifdef SAVE_AAC
  301. av_packet_rescale_ts(packet, _encoder_ctx->time_base, _aac_stream->time_base);
  302. packet->stream_index = _aac_stream->index;
  303. av_write_frame(_aac_fmt_ctx, packet);
  304. #endif
  305. av_packet_unref(packet);
  306. }
  307. // 如果没有收到数据包且不是EAGAIN错误,可能有问题
  308. if (!packetReceived && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
  309. al_warn("No packet received and unexpected return code: %d", ret);
  310. }
  311. return AE_NO;
  312. }
  313. void encoder_aac::encode_loop()
  314. {
  315. int len = 0;
  316. int error = AE_NO;
  317. AVPacket *packet = av_packet_alloc();
  318. AVFrame pcm_frame;
  319. #ifdef SAVE_AAC
  320. avformat_write_header(_aac_fmt_ctx, NULL);
  321. #endif
  322. while (_running) {
  323. std::unique_lock<std::mutex> lock(_mutex);
  324. while (!_cond_notify && _running)
  325. _cond_var.wait_for(lock, std::chrono::milliseconds(300));
  326. while ((len = _ring_buffer->get(_buff, _buff_size, pcm_frame))) {
  327. // 验证获取的音频数据
  328. if (len <= 0) {
  329. al_warn("Invalid audio data length: %d", len);
  330. continue;
  331. }
  332. // 确保音频数据正确填充到frame中
  333. if (len != _buff_size) {
  334. al_warn("Audio data size mismatch: expected=%d, actual=%d", _buff_size, len);
  335. }
  336. // 添加详细的调试信息
  337. static int frameCounter = 0;
  338. if (++frameCounter % 100 == 0) { // 每100帧打印一次
  339. al_debug("Ring buffer data: len=%d, buff_size=%d, frame_size=%d, channels=%d, format=%d",
  340. len, _buff_size, _encoder_ctx->frame_size,
  341. ffmpeg_get_frame_channels(_frame), _frame->format);
  342. }
  343. _frame->pts = pcm_frame.pts;
  344. #if FFMPEG_VERSION_MAJOR >= 7
  345. // In FFmpeg 7+, pkt_pts is removed, use pts instead
  346. // _frame->pts is already set above
  347. #else
  348. _frame->pkt_pts = pcm_frame.pkt_pts;
  349. #endif
  350. _frame->pkt_dts = pcm_frame.pkt_dts;
  351. // 验证编码器帧的配置
  352. if (_frame->nb_samples != _encoder_ctx->frame_size) {
  353. al_warn("Frame samples mismatch: frame->nb_samples=%d, encoder->frame_size=%d",
  354. _frame->nb_samples, _encoder_ctx->frame_size);
  355. }
  356. // 重新填充音频frame数据,确保数据正确
  357. int ret = avcodec_fill_audio_frame(_frame,
  358. ffmpeg_get_frame_channels(_frame),
  359. (AVSampleFormat)_frame->format,
  360. _buff,
  361. len,
  362. 0);
  363. if (ret < 0) {
  364. al_warn("Failed to fill audio frame: %d", ret);
  365. continue;
  366. }
  367. // 验证填充后的帧数据
  368. if (!_frame->data[0]) {
  369. al_warn("Frame data is null after filling");
  370. continue;
  371. }
  372. // 计算期望的数据大小并验证
  373. int expectedSize = _frame->nb_samples * ffmpeg_get_frame_channels(_frame) *
  374. av_get_bytes_per_sample((AVSampleFormat)_frame->format);
  375. if (len != expectedSize) {
  376. al_warn("Data size validation failed: actual=%d, expected=%d", len, expectedSize);
  377. }
  378. if ((error = encode(_frame, packet)) != AE_NO) {
  379. al_error("AAC encoding failed: error=%d, frame_pts=%lld, frame_size=%d",
  380. error, _frame->pts, _frame->nb_samples);
  381. // 尝试恢复:跳过当前帧,继续处理下一帧
  382. if (error == AE_FFMPEG_ENCODE_FRAME_FAILED || error == AE_FFMPEG_READ_PACKET_FAILED) {
  383. al_warn("Attempting to recover from encoding error, skipping current frame");
  384. continue;
  385. }
  386. // 严重错误,通知上层并退出
  387. if (_on_error)
  388. _on_error(error);
  389. al_fatal("Critical AAC encoding error:%d, stopping encoder", error);
  390. break;
  391. }
  392. }
  393. _cond_notify = false;
  394. }
  395. //flush pcm data in encoder
  396. al_debug("Flushing remaining AAC data from encoder");
  397. int flush_error = encode(NULL, packet);
  398. if (flush_error != AE_NO) {
  399. al_warn("Error during AAC encoder flush: %d", flush_error);
  400. }
  401. av_packet_free(&packet);
  402. // 输出编码统计信息
  403. al_info("AAC encoder stopped. Encoding session completed.");
  404. #ifdef SAVE_AAC
  405. av_write_trailer(_aac_fmt_ctx);
  406. #endif
  407. }
  408. void encoder_aac::cleanup()
  409. {
  410. if (_encoder) {
  411. avcodec_close(_encoder_ctx);
  412. }
  413. _encoder = NULL;
  414. if (_encoder_ctx) {
  415. avcodec_free_context(&_encoder_ctx);
  416. }
  417. if (_frame)
  418. av_free(_frame);
  419. _frame = NULL;
  420. if (_buff)
  421. av_free(_buff);
  422. _buff = NULL;
  423. if (_bsf_ctx) {
  424. av_bsf_free(&_bsf_ctx);
  425. _bsf_ctx = NULL;
  426. }
  427. _encoder_ctx = NULL;
  428. #ifdef SAVE_AAC
  429. if (_aac_fmt_ctx) {
  430. avio_closep(&_aac_fmt_ctx->pb);
  431. avformat_free_context(_aac_fmt_ctx);
  432. }
  433. #endif
  434. }
  435. int encoder_aac::add_adts_header(AVPacket *packet)
  436. {
  437. if (!packet || !packet->data || packet->size <= 0) {
  438. al_error("Invalid packet for ADTS header addition");
  439. return AE_INVALID_CONTEXT;
  440. }
  441. // ADTS头部长度为7字节
  442. const int adts_header_size = 7;
  443. int new_size = packet->size + adts_header_size;
  444. // 创建新的缓冲区
  445. uint8_t *new_data = (uint8_t*)av_malloc(new_size);
  446. if (!new_data) {
  447. al_error("Failed to allocate memory for ADTS header");
  448. return AE_FFMPEG_ALLOC_FRAME_FAILED;
  449. }
  450. // 生成ADTS头部
  451. uint8_t adts_header[7];
  452. // 获取编码器参数
  453. int sample_rate = _encoder_ctx->sample_rate;
  454. int channels = ffmpeg_get_codec_context_channels(_encoder_ctx);
  455. int profile = _encoder_ctx->profile; // AAC-LC = 1
  456. // 采样率索引映射
  457. int freq_idx = 4; // 默认44100Hz
  458. switch (sample_rate) {
  459. case 96000: freq_idx = 0; break;
  460. case 88200: freq_idx = 1; break;
  461. case 64000: freq_idx = 2; break;
  462. case 48000: freq_idx = 3; break;
  463. case 44100: freq_idx = 4; break;
  464. case 32000: freq_idx = 5; break;
  465. case 24000: freq_idx = 6; break;
  466. case 22050: freq_idx = 7; break;
  467. case 16000: freq_idx = 8; break;
  468. case 12000: freq_idx = 9; break;
  469. case 11025: freq_idx = 10; break;
  470. case 8000: freq_idx = 11; break;
  471. default: freq_idx = 4; break;
  472. }
  473. // 声道配置
  474. int channel_config = channels;
  475. if (channels > 6) channel_config = 0; // 自定义配置
  476. // 构建ADTS头部
  477. adts_header[0] = 0xFF; // syncword (12 bits) - 高8位
  478. adts_header[1] = 0xF0 | (0 << 3) | (0 << 2) | 1; // syncword低4位 + MPEG版本 + Layer + protection_absent
  479. adts_header[2] = ((profile - 1) << 6) | (freq_idx << 2) | (0 << 1) | ((channel_config >> 2) & 1);
  480. adts_header[3] = ((channel_config & 3) << 6) | (0 << 5) | (0 << 4) | (0 << 3) | ((new_size >> 11) & 3);
  481. adts_header[4] = (new_size >> 3) & 0xFF;
  482. adts_header[5] = ((new_size & 7) << 5) | 0x1F;
  483. adts_header[6] = 0xFC; // number_of_raw_data_blocks_in_frame (2 bits) + 6位填充
  484. // 复制ADTS头部和原始数据
  485. memcpy(new_data, adts_header, adts_header_size);
  486. memcpy(new_data + adts_header_size, packet->data, packet->size);
  487. // 释放原始数据并更新packet
  488. av_packet_unref(packet);
  489. packet->data = new_data;
  490. packet->size = new_size;
  491. al_debug("ADTS header added: total_size=%d, profile=%d, freq_idx=%d, channels=%d",
  492. new_size, profile, freq_idx, channels);
  493. return AE_NO;
  494. }
  495. } // namespace am