gpt4 book ai didi

c - 使用 avcodec_decode_audio4() 解码 AAC 时出错

转载 作者:行者123 更新时间:2023-12-02 01:34:53 27 4
gpt4 key购买 nike

我正在尝试使用 FFmpeg native 解码器解码 AAC 并遇到错误

SSR is not implemeted. Update your FFmpeg version to newest from Git. If the      problem still occurs, it mean that your file has a feature which has not implemented.

函数 avcodec_decode_audio4() 返回 -1163346256。这是因为FFmpeg版本吗?我从 here 下载了共享和开发版本.这是最新的吗?

这是源代码:
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"

extern "C"
{
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include <libavcodec\avcodec.h>
#include <libavformat/avformat.h>
}

// compatibility with newer API
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
#define av_frame_alloc avcodec_alloc_frame
#define av_frame_free avcodec_free_frame
#endif

#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096


static void audio_decode_example(const char *outfilename, const char *filename);


int main(int argc, char *argv[]) {
audio_decode_example("D:\\sample.pcm","D:\\sample.m4a");
getch();
return 0;
}


/*
* Audio decoding.
*/
static void audio_decode_example(const char *outfilename, const char *filename)
{
AVCodec *codec;
AVFormatContext *pFormatCtx = NULL;
AVCodecContext *pCodecCtxOrig = NULL;
AVCodecContext * pCodecCtx= NULL;
int len;
FILE *f, *outfile;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
AVFrame *decoded_frame = NULL;


av_register_all();

av_init_packet(&avpkt);

printf("Decode audio file %s to %s\n", filename, outfilename);

// Open file to get format context
if(avformat_open_input(&pFormatCtx, filename, NULL, NULL)!=0){
printf("Couldn't open file");
return; // Couldn't open file
}

// Retrieve stream information
if(avformat_find_stream_info(pFormatCtx, NULL)<0){
printf("Couldn't find stream information");
return; // Couldn't find stream information
}

// Dump information about file onto standard error
av_dump_format(pFormatCtx, 0, filename, 0);

// Find the first audio stream
int audioStream = -1;
int i =0;
for(i=0; i<pFormatCtx->nb_streams; i++) {
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
audioStream=i;
break;
}
}

if(audioStream==-1) {
printf("Didn't find a audio stream");
return; // Didn't find a audio stream
}

// Get a pointer to the codec context for the audio stream
pCodecCtxOrig=pFormatCtx->streams[audioStream]->codec;

// Find the decoder for the audio stream
codec=avcodec_find_decoder(pCodecCtxOrig->codec_id);
if(codec==NULL) {
fprintf(stderr, "Codec not found\n");
return; // Codec not found
}

pCodecCtx = avcodec_alloc_context3(codec);
if (!pCodecCtx) {
fprintf(stderr, "Could not allocate audio codec context\n");
return;
}

if(avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) {
fprintf(stderr, "Couldn't copy codec context");
return; // Error copying codec context
}


/* open it */
if (avcodec_open2(pCodecCtx, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
return;
}

f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
return;
}
outfile = fopen(outfilename, "wb");
if (!outfile) {
av_free(pCodecCtx);
return;
}

/* decode until eof */
avpkt.data = inbuf;
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);

while (avpkt.size > 0) {
int i, ch;
int got_frame = 0;

if (!decoded_frame) {
if (!(decoded_frame = av_frame_alloc())) {
fprintf(stderr, "Could not allocate audio frame\n");
return;
}
}

len = avcodec_decode_audio4(pCodecCtx, decoded_frame, &got_frame, &avpkt);
if (len < 0) {
fprintf(stderr, "Error while decoding. len = %d \n",len);
return;
}
if (got_frame) {
/* if a frame has been decoded, output it */
int data_size = av_get_bytes_per_sample(pCodecCtx->sample_fmt);
if (data_size < 0) {
/* This should not occur, checking just for paranoia */
fprintf(stderr, "Failed to calculate data size\n");
return;
}
for (i=0; i < decoded_frame->nb_samples; i++)
for (ch=0; ch < pCodecCtx->channels; ch++)
fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile);
}
avpkt.size -= len;
avpkt.data += len;
avpkt.dts =
avpkt.pts = AV_NOPTS_VALUE;
if (avpkt.size < AUDIO_REFILL_THRESH) {
/* Refill the input buffer, to avoid trying to decode
* incomplete frames. Instead of this, one could also use
* a parser, or use a proper container format through
* libavformat. */
memmove(inbuf, avpkt.data, avpkt.size);
avpkt.data = inbuf;
len = fread(avpkt.data + avpkt.size, 1,
AUDIO_INBUF_SIZE - avpkt.size, f);
if (len > 0)
avpkt.size += len;
}
}

fclose(outfile);
fclose(f);

avcodec_close(pCodecCtx);
av_free(pCodecCtx);
av_frame_free(&decoded_frame);
}

我也读过这个问题: How to decode AAC using avcodec_decode_audio4?但没有提供解决方案。

最佳答案

f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
return;
}
outfile = fopen(outfilename, "wb");
if (!outfile) {
av_free(pCodecCtx);
return;
}

/* decode until eof */
avpkt.data = inbuf;
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);

while (avpkt.size > 0) {
int i, ch;
int got_frame = 0;


是的,那是行不通的。您不能将某些随机复用格式(可能是 mp4)的原始字节转储到解码器中并期望它能够正常工作。使用 av_read_frame () 从复用格式中读取单个音频数据包,并使用 avcodec_decode_audio4() 将生成的 AVPacket 输入解码器。参见例如 dranger api tutorial .我知道 api-example.c 使用上面的代码,但不幸的是,这只适用于非常有限的案例子集。另请参阅 API docs 中的详细说明。 .

关于c - 使用 avcodec_decode_audio4() 解码 AAC 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31831725/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com