qt_rtmp_demo/media/AACAudioCoder.cpp

146 lines
4.3 KiB
C++
Raw Normal View History

2023-11-12 16:13:24 +00:00
#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<4C><43>MediaCodecInfo.CodecProfileLevel.AACObjectLC;
int freqIdx = 4; //32K, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>avpriv_mpeg4audio_sample_rates<65><73>32000<30><30>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±꣬<C2B1><EAA3AC><EFBFBD><EFBFBD>ffmpegԴ<67><D4B4>
int chanCfg = channels; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>channel_configuration<6F><6E>Stero˫<6F><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/*int avpriv_mpeg4audio_sample_rates[] = {
96000, 88200, 64000, 48000, 44100, 32000,
24000, 22050, 16000, 12000, 11025, 8000, 7350
};
channel_configuration: <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>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;
}