qt_rtmp_demo/media/AACAudioCoder.cpp

146 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "AACAudioCoder.h"
//#include "Debuger.h"
using namespace AAC_CODER;
AACAudioCoder::~AACAudioCoder() {
}
void AACAudioCoder::OnAudioData(const void *frameaddress, uint32_t framelen)
{
this->Encode((unsigned char *)frameaddress, framelen * 4);
}
AACAudioCoder::AACAudioCoder(unsigned int smprate, unsigned int channel) {
AVCodecID codec_id = AV_CODEC_ID_AAC;
pCodec = (AVCodec *)avcodec_find_encoder_by_name("libfdk_aac");
if (!pCodec) {
printf("Codec not found\n");
this->mStatus = FAIL;
}
mCodecCtx = avcodec_alloc_context3(pCodec);
if (!mCodecCtx) {
printf("Could not allocate video codec context\n");
this->mStatus = FAIL;
}
mCodecCtx->codec_id = pCodec->id;
mCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
mCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16; ///< float
mCodecCtx->sample_rate = 44100;
mCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO;
mCodecCtx->channels = 2;
mCodecCtx->bit_rate = 640000;
mCodecCtx->time_base.den = 1;
mCodecCtx->time_base.num = 23;
mCodecCtx->frame_size = 1024;
this->mObserver = nullptr;
if (avcodec_open2(mCodecCtx, pCodec, NULL) < 0) {
this->mStatus = FAIL;
}
mFrame = av_frame_alloc();
mFrame->nb_samples = mCodecCtx->frame_size;
mFrame->format = mCodecCtx->sample_fmt;
int size = av_samples_get_buffer_size(NULL, mCodecCtx->channels, mCodecCtx->frame_size, mCodecCtx->sample_fmt, 1);
mFrameBuf = (uint8_t *)av_malloc(size);
avcodec_fill_audio_frame(mFrame, mCodecCtx->channels, mCodecCtx->sample_fmt, (const uint8_t*)mFrameBuf, size, 1);
mPts = 0;
}
int adts_sample_rates[]={96000,882000,64000,48000,441000,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};
int FindAdstSRIndex(int samplerate)
{
int i;
for (i = 0; i < 16; i++)
{
if (samplerate == adts_sample_rates[i])
return i;
}
return 16 - 1;
}
#define ADTS_HEAD_LEN 7
void MakeAdtsHeader(unsigned char *data, int samplerate, int channels, int iFrameLen)
{
int profile = 2; //AAC LC£¬MediaCodecInfo.CodecProfileLevel.AACObjectLC;
int freqIdx = 4; //32K, ¼ûºóÃæ×¢ÊÍavpriv_mpeg4audio_sample_ratesÖÐ32000¶ÔÓ¦µÄÊý×éϱ꣬À´×ÔffmpegÔ´Âë
int chanCfg = channels; //¼ûºóÃæ×¢ÊÍchannel_configuration£¬SteroË«ÉùµÀÁ¢ÌåÉù
/*int avpriv_mpeg4audio_sample_rates[] = {
96000, 88200, 64000, 48000, 44100, 32000,
24000, 22050, 16000, 12000, 11025, 8000, 7350
};
channel_configuration: ±íʾÉùµÀÊýchanCfg
0: Defined in AOT Specifc Config
1: 1 channel: front-center
2: 2 channels: front-left, front-right
3: 3 channels: front-center, front-left, front-right
4: 4 channels: front-center, front-left, front-right, back-center
5: 5 channels: front-center, front-left, front-right, back-left, back-right
6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
8-15: Reserved
*/
// fill in ADTS data
data[0] = (uint8_t)0xFF;
data[1] = (uint8_t)0xF9;
data[2] = (uint8_t)(((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));
data[3] = (uint8_t)(((chanCfg & 3) << 6) + (iFrameLen >> 11));
data[4] = (uint8_t)((iFrameLen & 0x7FF) >> 3);
data[5] = (uint8_t)(((iFrameLen & 7) << 5) + 0x1F);
data[6] = (uint8_t)0xFC;
}
FILE *ptest = nullptr;
int once = 1;
int AACAudioCoder::Encode( unsigned char *input, unsigned int num) {
mFrame->nb_samples = mCodecCtx->frame_size;
mFrame->format = mCodecCtx->sample_fmt;
avcodec_fill_audio_frame(mFrame, mCodecCtx->channels,
mCodecCtx->sample_fmt, input,
num, 1);
int aac_out_len = 0;
unsigned char*aac_buf;
if (nullptr == input) {
return -1;
}
if (nullptr == ptest) {
ptest = fopen("dst.aac", "wb");
}
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
int got_output = 0;
mFrame->pts = mPts += 23;
int ret = avcodec_encode_audio2(mCodecCtx, &pkt, mFrame, &got_output);
if (ret < 0) {
printf("Error encoding frame\n");
return -1;
}
if (got_output) {
if (nullptr != mObserver) {
mObserver->OnAudioEncode(pkt.data, pkt.size, mFrame->pts);
}
fwrite(pkt.data, 1, pkt.size, ptest);
av_free_packet(&pkt);
}
return 0;
}
int AAC_CODER::AACAudioCoder::SetObserver(EncodeAudioObserver *p)
{
if (nullptr == this->mObserver) {
this->mObserver = p;
}
return 0;
}