gpt4 book ai didi

android - ffmpeg 解码时出错

转载 作者:行者123 更新时间:2023-11-30 15:44:53 27 4
gpt4 key购买 nike

我正在使用 libav 开发一个 Android 应用程序,并尝试使用以下代码解码 3gp:

#define simbiLog(...) __android_log_print(ANDROID_LOG_DEBUG, "simbiose", __VA_ARGS__)

...

AVCodec *codec;
AVCodecContext *c = NULL;
int len;
FILE *infile, *outfile;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
AVFrame *decoded_frame = NULL;

simbiLog("inbuf size: %d", sizeof(inbuf) / sizeof(inbuf[0]));

av_register_all();
av_init_packet(&avpkt);

codec = avcodec_find_decoder(AV_CODEC_ID_AMR_NB);
if (!codec) {
simbiLog("codec not found");
return ERROR;
}

c = avcodec_alloc_context3(codec);
if (!c) {
simbiLog("Could not allocate audio codec context");
return ERROR;
}

int open = avcodec_open2(c, codec, NULL);
if (open < 0) {
simbiLog("could not open codec %d", open);
return ERROR;
}

infile = fopen(inputPath, "rb");
if (!infile) {
simbiLog("could not open %s", inputPath);
return ERROR;
}

outfile = fopen(outputPath, "wb");
if (!outfile) {
simbiLog("could not open %s", outputPath);
return ERROR;
}

avpkt.data = inbuf;
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, infile);
int iterations = 0;

while (avpkt.size > 0) {
simbiLog("iteration %d", (++iterations));
simbiLog("avpkt.size %d avpkt.data %X", avpkt.size, avpkt.data);
int got_frame = 0;

if (!decoded_frame) {
if (!(decoded_frame = avcodec_alloc_frame())) {
simbiLog("out of memory");
return ERROR;
}
} else {
avcodec_get_frame_defaults(decoded_frame);
}

//below the error, but it isn't occur on first time, only in 4th loop interation
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
if (len < 0) {
simbiLog("Error while decoding error %d frame %d duration %d", len, got_frame, avpkt.duration);
return ERROR;
} else {
simbiLog("Decoding length %d frame %d duration %d", len, got_frame, avpkt.duration);
}

if (got_frame) {
int data_size = av_samples_get_buffer_size(NULL, c->channels, decoded_frame->nb_samples, c->sample_fmt, 1);
size_t* fwrite_size = fwrite(decoded_frame->data[0], 1, data_size, outfile);
simbiLog("fwrite returned %d", fwrite_size);
}
avpkt.size -= len;
avpkt.data += len;
if (avpkt.size < AUDIO_REFILL_THRESH) {
memmove(inbuf, avpkt.data, avpkt.size);
avpkt.data = inbuf;
len = fread(avpkt.data + avpkt.size, 1, AUDIO_INBUF_SIZE - avpkt.size, infile);
if (len > 0)
avpkt.size += len;
simbiLog("fread returned %d", len);
}
}

fclose(outfile);
fclose(infile);

avcodec_close(c);
av_free(c);
av_free(decoded_frame);

但我收到以下日志和错误:

inbuf size: 20488
iteration 1
avpkt.size 3305 avpkt.data BEEED40C
Decoding length 13 frame 1 duration 0
fwrite returned 640
fread returned 0
iteration 2
avpkt.size 3292 avpkt.data BEEED40C
Decoding length 13 frame 1 duration 0
fwrite returned 640
fread returned 0
iteration 3
avpkt.size 3279 avpkt.data BEEED40C
Decoding length 14 frame 1 duration 0
fwrite returned 640
fread returned 0
iteration 4
avpkt.size 3265 avpkt.data BEEED40C
Error while decoding error -1052488119 frame 0 duration 0

我正在尝试解码的音频文件:

$ avprobe blue.3gp 
avprobe version 0.8.6-6:0.8.6-1ubuntu2, Copyright (c) 2007-2013 the Libav developers
built on Mar 30 2013 22:23:21 with gcc 4.7.2
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'blue.3gp':
Metadata:
major_brand : 3gp4
minor_version : 0
compatible_brands: isom3gp4
creation_time : 2013-09-19 18:53:38
Duration: 00:00:01.52, start: 0.000000, bitrate: 17 kb/s
Stream #0.0(eng): Audio: amrnb, 8000 Hz, 1 channels, flt, 12 kb/s
Metadata:
creation_time : 2013-09-19 18:53:38

非常感谢!

<小时/>

已编辑

我在 ffmper 文档中阅读了有关方法 avcodec_decode_audio4 的内容:

@warning The input buffer, avpkt->data must be FF_INPUT_BUFFER_PADDING_SIZE larger than the actual read bytes because some optimized bitstream readers read 32 or 64 bits at once and could read over the end.
@note You might have to align the input buffer. The alignment requirements depend on the CPU and the decoder.

我看到here使用posix_memalign的解决方案,对于android我创建了一个类似的方法称为memalign,所以我做了改变:

删除:

uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];

插入:

int inbufSize = sizeof(uint8_t) * (AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
uint8_t *inbuf = memalign(FF_INPUT_BUFFER_PADDING_SIZE, inbufSize);
simbiLog("inbuf size: %d", inbufSize);
for (; inbufSize >= 0; inbufSize--)
simbiLog("inbuf position: %d index: %p", inbufSize, &inbuf[inbufSize]);

我得到了正确的内存序列位置,但错误没有改变。

一段输出:

inbuf position: 37 index: 0x4e43d745
inbuf position: 36 index: 0x4e43d744
inbuf position: 35 index: 0x4e43d743
inbuf position: 34 index: 0x4e43d742
inbuf position: 33 index: 0x4e43d741
inbuf position: 32 index: 0x4e43d740
inbuf position: 31 index: 0x4e43d73f
inbuf position: 30 index: 0x4e43d73e
inbuf position: 29 index: 0x4e43d73d
inbuf position: 28 index: 0x4e43d73c
inbuf position: 27 index: 0x4e43d73b
inbuf position: 26 index: 0x4e43d73a
inbuf position: 25 index: 0x4e43d739
inbuf position: 24 index: 0x4e43d738
inbuf position: 23 index: 0x4e43d737
inbuf position: 22 index: 0x4e43d736
inbuf position: 21 index: 0x4e43d735
inbuf position: 20 index: 0x4e43d734
inbuf position: 19 index: 0x4e43d733

最佳答案

您正在尝试在不进行解复用的情况下进行解码。

关于android - ffmpeg 解码时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19292431/

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