本文共 2455 字,大约阅读时间需要 8 分钟。
AAC是一种常见的音频格式,今天尝试使用ffmpeg把pcm压缩成AAC编码。
第一步:初始化编码相关变量
寻找AAC的编码器
codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
初始化编码器上下文,主要通道数,采样率,采样格式
c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate audio codec context\n"); return false; } c->channels = m_PcmChannel; c->channel_layout = av_get_default_channel_layout(m_PcmChannel); c->sample_rate = m_PcmSampleRate; c->sample_fmt = AV_SAMPLE_FMT_FLTP;//AV_SAMPLE_FMT_FLTP; c->bit_rate = 64000; /* Allow the use of the experimental AAC encoder. */ c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
打开编码器
if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); return false; }
设置格式转换,主要是AAC需要的采样格式位AV_SAMPLE_FMT_FLTP,而PCM格式位AV_SAMPLE_FMT_S16,所以需要进行格式的转换。
resample_context = swr_alloc_set_opts(NULL, c->channel_layout, c->sample_fmt, c->sample_rate, c->channel_layout, m_PcmFormat, c->sample_rate, 0, NULL);if (swr_init(resample_context) < 0) { fprintf(stderr, "Could not open resample context\n"); return false; }
第二步:初始化相关工作做完之后,可以进行转码工作,首先丢进。
对PCM进行重新采样,转换成AAC需要的PCM格式
if (swr_convert(resample_context, frame->extended_data, frame->nb_samples, (const uint8_t**)m_PcmPointer, 1024)<0) { fprintf(stderr, "Could not convert input samples (error )\n"); if (NULL != frame) { av_frame_free(&frame); } return ; }
放进编码器
ret = avcodec_send_frame(c, frame);
第三步:从编码器取出编码完的数据
int ret = avcodec_receive_packet(c, packet);
第四步:由于编码后的AAC文件没有头,导致写成文件无法识别,所以需要手动写入AAC头
// fill in ADTS data m_pOutData[0] = 0xFF; m_pOutData[1] = 0xF1; m_pOutData[2] = ((profile) << 6) + (freqIdx << 2) + (chanCfg >> 2); m_pOutData[3] = (((chanCfg & 3) << 6) + (packetLen >> 11)); m_pOutData[4] = ((packetLen & 0x7FF) >> 3); m_pOutData[5] = (((packetLen & 7) << 5) + 0x1F); m_pOutData[6] = 0xFC;
至此,PCM转成AAC的格式流程结束。
这里对AVSampleFormat格式进行一下介绍,
如果是以下格式:
AV_SAMPLE_FMT_U8, ///< unsigned 8 bits
AV_SAMPLE_FMT_S16, ///< signed 16 bits AV_SAMPLE_FMT_S32, ///< signed 32 bits AV_SAMPLE_FMT_FLT, ///< float AV_SAMPLE_FMT_DBL, ///< double只能保存再AVFrame的uint8_t *data[0];
音频保持格式如下:
LRLRLR。。。。
如果是以下格式
AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar
AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar AV_SAMPLE_FMT_FLTP, ///< float, planar AV_SAMPLE_FMT_DBLP, ///< double, planarplane 0: LLLLLLLLLLLLLLLLLLLLLLLLLL...
plane 1: RRRRRRRRRRRRRRRRRRRR....plane 0对于uint8_t *data[0];
plane 1对于uint8_t *data[1];
为了便于大家学习和研究, 工程采用VS2017开发,地址如下:
转载地址:http://jmvad.baihongyu.com/