#include "AACDecoder.h" #include "Debuger.h" void AACDecoder::OnRtmpFrame(void * dat, uint32_t size) { this->Decode((uint8_t *)dat, size); } AACDecoder::AACDecoder() :mObserver(nullptr) { mStatus = RUNNING; this->mObserverType = Observer_Audio; mCodec = avcodec_find_decoder(AV_CODEC_ID_AAC); if (mCodec == NULL) { Debuger::Debug(L"find codec fail\r\n"); mStatus = FAIL; } mCodecCtx = avcodec_alloc_context3(mCodec); if (nullptr == mCodecCtx) { Debuger::Debug(L"find codec ctx fail\r\n"); mStatus = FAIL; } mCodecCtx->codec = mCodec; mCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO; mCodecCtx->sample_rate = 44100; mCodecCtx->channels = 2; mCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO; mCodecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP; mCodecCtx->frame_size = 2048; #if LIBSWRESAMPLE_VERSION_MINOR >= 17 // 根据版本不同,选用适当函数 mSwrCtx = swr_alloc(); av_opt_set_int(mSwrCtx, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(mSwrCtx, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(mSwrCtx, "in_sample_rate", 44100, 0); av_opt_set_int(mSwrCtx, "out_sample_rate", 44100, 0); av_opt_set_sample_fmt(mSwrCtx, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0); av_opt_set_sample_fmt(mSwrCtx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); swr_init(mSwrCtx); #else mSwrCtx = swr_alloc(); mSwrCtx = swr_alloc_set_opts(mSwrCtx, AV_CH_LAYOUT_STEREO, //output AV_SAMPLE_FMT_S16, 44100, AV_CH_LAYOUT_STEREO, // input AV_SAMPLE_FMT_FLTP, 44100, 0, NULL); swr_init(mSwrCtx); #endif if (avcodec_open2(mCodecCtx, mCodec, NULL) < 0) { Debuger::Debug(L"can't open codec\r\n"); mStatus = FAIL; } mSampleRate = 44100; mChannel = 2; mChannelLayout = AV_CH_LAYOUT_STEREO; mSampleFmt = AV_SAMPLE_FMT_FLTP; mStatus = RUNNING; mU16Data = (uint8_t *)av_malloc(192000); } #define MAX_AUDIO_FRAME_SIZE 192000 AACDecoder::AACDecoder(AVStream * p):mObserver(nullptr) { mStatus = RUNNING; this->mObserverType = Observer_Audio; if (nullptr == p) { Debuger::Debug(L"find codec fail\r\n"); mStatus = FAIL; } mCodecCtx = p->codec; mCodec = avcodec_find_decoder(mCodecCtx->codec_id); if (mCodec == NULL) { Debuger::Debug(L"find codec fail\r\n"); mStatus = FAIL; } if (avcodec_open2(mCodecCtx, mCodec, NULL) < 0) { Debuger::Debug(L"can't open codec\r\n"); mStatus = FAIL; } mSampleRate = mCodecCtx->sample_rate; mChannel = mCodecCtx->channels; mChannelLayout = mCodecCtx->channel_layout; mSampleFmt = mCodecCtx->sample_fmt; } int AACDecoder::Decode(uint8_t * dat, uint16_t size) { AVPacket pkt; int got_pcm = 0; int len = 0; if (mStatus == RUNNING) { mPcmDat = av_frame_alloc(); av_init_packet(&pkt); char* data = (char*)dat; pkt.data = (uint8_t *)data; pkt.size = size; len = avcodec_decode_audio4(this->mCodecCtx, mPcmDat, &got_pcm, &pkt); if (len < 0) { printf("Error while decoding a frame.\n"); return -1; } if (got_pcm == 0) { return 0; } int buffer_size = av_samples_get_buffer_size(NULL, AV_CH_LAYOUT_STEREO, mPcmDat->nb_samples, AV_SAMPLE_FMT_S16, 1); swr_convert(mSwrCtx, &mU16Data, buffer_size, (const uint8_t **)mPcmDat->data, mPcmDat->nb_samples); //Debuger::Debug(L"get %d audio samples\r\n", mPcmDat->nb_samples); if (nullptr != this->mObserver) { int out_buffer_size = av_samples_get_buffer_size(NULL, 2, mPcmDat->nb_samples, AV_SAMPLE_FMT_FLTP, 1); this->mObserver->OnAudioDecode(mU16Data, buffer_size); } //(const uint8_t **)mPcmDat->data, mPcmDat->nb_samples; av_frame_free(&mPcmDat); return 0; } } int AACDecoder::SetObserver(AACDecoderObserver *p) { if(nullptr != p) this->mObserver = p; return 0; }