C++ 如何使用C+一次解码一个AAC帧+;?
我想连续解码AAC帧流,一次解码一帧 我浏览了ffmpeg示例(正确的答案不一定需要使用ffmpeg),我只找到了使用完整AAC文件和批处理算法的示例。但我想解码一个连续的AAC流。我该怎么做 更新:在评论之后,我能够使用ffmpeg解码到PCM,但是输出非常金属化和嘈杂。当为每个AAC帧调用此方法时,我在这里做错了什么:C++ 如何使用C+一次解码一个AAC帧+;?,c++,audio-streaming,aac,libavcodec,C++,Audio Streaming,Aac,Libavcodec,我想连续解码AAC帧流,一次解码一帧 我浏览了ffmpeg示例(正确的答案不一定需要使用ffmpeg),我只找到了使用完整AAC文件和批处理算法的示例。但我想解码一个连续的AAC流。我该怎么做 更新:在评论之后,我能够使用ffmpeg解码到PCM,但是输出非常金属化和嘈杂。当为每个AAC帧调用此方法时,我在这里做错了什么: ... /*loop that receives frame in buffer*/ while(1){ /*receive frame*/ input = r
...
/*loop that receives frame in buffer*/
while(1){
/*receive frame*/
input = receive_one_buffer();
/*decode frame*/
decodeBuffer(input,strlen(input),Outfile);
}
...
/*decode frame*/
void decodeBuffer(char * input, int numBytes, ofstream& Outfile) {
/*"input" contains one AAC-LC frame*/
//copy bytes from buffer
uint8_t inputBytes[numBytes + FF_INPUT_BUFFER_PADDING_SIZE];
memset(inputBytes, 0, numBytes + FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(inputBytes, input, numBytes);
av_register_all();
AVCodec *codec = avcodec_find_decoder(CODEC_ID_AAC);
AVCodecContext *avCtx = avcodec_alloc_context();
avCtx->channels = 1;
avCtx->sample_rate = 44100;
//the input buffer
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.size = numBytes; //input buffer size
avPacket.data = inputBytes; // the input buffer
int outSize;
int len;
uint8_t *outbuf = static_cast<uint8_t *>(malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE));
while (avPacket.size > 0) {
outSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
len = avcodec_decode_audio3(avCtx, (short *) outbuf, &outSize,
&avPacket);
Outfile.write((char*)outbuf, outSize);
avPacket.size -= len;
avPacket.data += len;
}
av_free_packet(&avPacket);
avcodec_close(avCtx);
//av_free(avCtx);
return;
}
。。。
/*在缓冲区中接收帧的循环*/
而(1){
/*接收帧*/
输入=接收一个缓冲区();
/*解码帧*/
解码缓冲区(输入、strlen(输入)、输出文件);
}
...
/*解码帧*/
无效解码缓冲区(字符*输入,整数字节,流和输出文件){
/*“输入”包含一个AAC-LC帧*/
//从缓冲区复制字节
uint8_t inputBytes[numBytes+FF_INPUT_BUFFER_PADDING_SIZE];
memset(inputBytes,0,numBytes+FF\u INPUT\u BUFFER\u PADDING\u SIZE);
memcpy(inputBytes,input,numBytes);
av_寄存器_all();
AVCodec*codec=AVCodec\u find\u解码器(codec\u ID\u AAC);
AVCodecContext*avCtx=avcodec_alloc_context();
avCtx->通道=1;
avCtx->采样率=44100;
//输入缓冲区
AVPacket-AVPacket;
av_初始_数据包(&av数据包);
avPacket.size=numBytes;//输入缓冲区大小
avPacket.data=inputBytes;//输入缓冲区
int超大;
内伦;
uint8_t*extuf=静态播放(malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE));
而(avPacket.size>0){
超大=AVCODEC\最大\音频\帧\大小;
len=avcodec\U decode\U AUDIO 3(avCtx,(短*)EXBUFF和超大,
&数据包);
Outfile.write((char*)exputf,特大号);
avPacket.size-=len;
avPacket.data+=len;
}
av_免费_数据包(&av数据包);
avcodec_close(avCtx);
//av_免费(avCtx);
返回;
}
您必须在后续解码调用之间保持解码器处于活动状态。
AAC解码器必须对前一个缓冲区进行解码,才能正确地“启动”
详情请参阅:
下面的代码假设“ReceiveBuffer”函数只返回一个
完成AAC访问单元
(顺便说一句:您不能在二进制缓冲区上使用strlen;您将获得到第一个零的距离,而不是缓冲区长度)
#包括
#包括
#包括“libavcodec\avcodec.h”
#包括“libavformat\avformat.h”
#包括“libavdevice\avdevice.h”
#包括“libavfilter\avfilter.h”
AvcodeContext*CreateContext()
{
av_寄存器_all();
AVCodec*codec=AVCodec\u find\u解码器(AV\u codec\u ID\u AAC);
AVCodecContext*avCtx=avcodec\u alloc\u context3(编解码器);
返回avCtx;
}
int32_t解码缓冲区
(
标准::ostream和输出,
uint8_t*pInput,
uint32\u t cbInputSize,
AVCodecContext*pAVContext
)
{
int32_t cbdecode=0;
//输入缓冲区
AVPacket-AVPacket;
av_初始_数据包(&av数据包);
avPacket.size=cbInputSize;//输入缓冲区大小
avPacket.data=pInput;//输入缓冲区
AVFrame*pDecodedFrame=av_frame_alloc();
int nGotFrame=0;
cbDecoded=avcodec\U decode\U audio4,
pDecodedFrame,
&nGotFrame,
&数据包);
int data\u size=av\u samples\u get\u buffer\u size(空,
pAVContext->channels,
pDecodedFrame->nb_样本,
pAVContext->sample_fmt,
1);
output.write((const char*)pDecodedFrame->data[0],data\u size);
无av帧(&pDecodedFrame);
返回CBD编码;
}
uint8*ReceiveBuffer(uint32*cbBufferSize)
{
//待办事项实施
返回NULL;
}
int main
(
int argc,
字符*argv[]
)
{
int nResult=0;
AvcodeContext*pAVContext=CreateContext();
std::of流myOutputFile(“audio.pcm”,std::ios::binary);
而(1)
{
uint32\u t cbBufferSize=0;
uint8_t*pcompressdaudio=接收缓冲区(&cbBufferSize);
if(cbBufferSize和PCompressDaudio)
{
解码缓冲区(myOutputFile,
pCompressedAudio,
CBS的大小,
(上下文);
}
其他的
{
打破
}
}
avcodec_关闭(pAVContext);
av_免费(pAVContext);
返回结果;
}
您必须在后续解码调用之间保持解码器处于活动状态。
AAC解码器必须对前一个缓冲区进行解码,才能正确地“启动”
详情请参阅:
下面的代码假设“ReceiveBuffer”函数只返回一个
完成AAC访问单元
(顺便说一句:您不能在二进制缓冲区上使用strlen;您将获得到第一个零的距离,而不是缓冲区长度)
#包括
#包括
#包括“libavcodec\avcodec.h”
#包括“libavformat\avformat.h”
#包括“libavdevice\avdevice.h”
#包括“libavfilter\avfilter.h”
AvcodeContext*CreateContext()
{
av_寄存器_all();
AVCodec*codec=AVCodec\u find\u解码器(AV\u codec\u ID\u AAC);
AVCodecContext*avCtx=avcodec\u alloc\u context3(编解码器);
返回avCtx;
}
int32_t解码缓冲区
(
标准::ostream和输出,
uint8_t*pInput,
uint32\u t cbInputSize,
AVCodecContext*pAVContext
)
{
int32_t cbdecode=0;
//输入缓冲区
AVPacket-AVPacket;
av_初始_数据包(&av数据包);
avPacket.size=cbInputSize;//输入缓冲区大小
avPacket.data=pInput;//输入缓冲区
AVFrame*pDecodedFrame=av_frame_alloc();
int nGotFrame=0;
cbDecoded=avcodec\U decode\U audio4,
pDecodedFrame,
#include <iostream>
#include <fstream>
#include "libavcodec\avcodec.h"
#include "libavformat\avformat.h"
#include "libavdevice\avdevice.h"
#include "libavfilter\avfilter.h"
AVCodecContext * CreateContext()
{
av_register_all();
AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_AAC);
AVCodecContext *avCtx = avcodec_alloc_context3(codec);
return avCtx;
}
int32_t DecodeBuffer
(
std::ostream & output,
uint8_t * pInput,
uint32_t cbInputSize,
AVCodecContext * pAVContext
)
{
int32_t cbDecoded = 0;
//the input buffer
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.size = cbInputSize; //input buffer size
avPacket.data = pInput; // the input bufferra
AVFrame * pDecodedFrame = av_frame_alloc();
int nGotFrame = 0;
cbDecoded = avcodec_decode_audio4( pAVContext,
pDecodedFrame,
& nGotFrame,
& avPacket);
int data_size = av_samples_get_buffer_size( NULL,
pAVContext->channels,
pDecodedFrame->nb_samples,
pAVContext->sample_fmt,
1);
output.write((const char*)pDecodedFrame->data[0],data_size);
av_frame_free(&pDecodedFrame);
return cbDecoded;
}
uint8_t * ReceiveBuffer( uint32_t * cbBufferSize)
{
// TODO implement
return NULL;
}
int main
(
int argc,
char *argv[]
)
{
int nResult = 0;
AVCodecContext * pAVContext = CreateContext();
std::ofstream myOutputFile("audio.pcm",std::ios::binary);
while(1)
{
uint32_t cbBufferSize = 0;
uint8_t *pCompressedAudio = ReceiveBuffer( &cbBufferSize);
if(cbBufferSize && pCompressedAudio)
{
DecodeBuffer( myOutputFile,
pCompressedAudio,
cbBufferSize,
pAVContext);
}
else
{
break;
}
}
avcodec_close(pAVContext);
av_free(pAVContext);
return nResult;
}