qt_rtmp_demo/media/AACDecoder.cpp

139 lines
3.6 KiB
C++

#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;
}