如何解码一个AAC帧在一个时间使用c++
How to decode one AAC frame at a time using C++?
我想连续解码AAC帧流,每次解码一帧。
我浏览了ffmpeg示例(正确的答案不一定需要使用ffmpeg),并且我只找到了使用完整AAC文件和批处理算法的示例。但我想解码一个连续的AAC流。我该怎么做呢?
UPDATE:在android上使用ffmpeg解码AAC到PCM之后,我能够使用ffmpeg解码到PCM,但是输出非常金属和嘈杂。当为每个AAC帧调用此方法时,我在这里做错了什么:
...
/*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;
}
您必须在后续解码调用之间保持解码器活动。AAC解码器必须解码前一个缓冲区才能正确地"预充"。
请查看详细信息:
https://developer.apple.com/library/mac/technotes/tn2258/_index.html下面的代码假设"ReceiveBuffer"函数只返回一个完整的AAC存取单元
(顺便说一句:你不能在二进制缓冲区上使用strlen;您将获得到第一个零的距离,而不是缓冲区长度)
#include <iostream>
#include <fstream>
#include "libavcodecavcodec.h"
#include "libavformatavformat.h"
#include "libavdeviceavdevice.h"
#include "libavfilteravfilter.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;
}
相关文章:
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 我可以创建一个包含两个变量的 for 循环,但时间复杂度仍然为 O(n) 吗?
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- ::grpc::ServerReaderWriter 对象在另一个线程中一段时间后无法调用
- 如果你有一个固定大小的数组,你需要遍历它!n次,使用二进制搜索如何改变时间复杂性
- 超过CPU时间限制:当MPI_Sent一个非常大的int*时
- 我们可以在队列前面以 O(1) 时间复杂度排队一个元素吗?
- 给定的两个代码有什么区别.一个在 ideone 上运行时超出时间限制,另一个工作正常
- 将 lambda 函数转换为另一个编译单元中的普通函数会缩短编译时间吗?
- 在模板中,有没有办法为每个时间实例化只编写一个专用化?(纳秒、毫秒、秒等)
- C 中是否有一个无法更改的时间戳?(Internet独立)
- C++将时间从一个环境转换为另一个环境
- 一个足够大的问题大小 C++ 需要 0 个运行时间
- 一个循环,可以打印所有项目(无论链条多长时间) *指针
- 给定一个微秒值,如何准确地得到一个时间值结构体?/*更新获取负值*/
- 我有两个点和一个时间,我如何找出向量
- 制作旋转器的功能,每天每分钟创建一个时间戳
- 正在查找具有tm以外的成员对象的另一个时间结构
- 如何动态分配二维数组一行在一个时间,列是已知的在c/c++
- 如何解码一个AAC帧在一个时间使用c++