146 lines
4.3 KiB
C++
146 lines
4.3 KiB
C++
#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_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;
|
||
}
|