2013-10-10 4 views
0

Я разрабатываю андроид приложение с libav и я пытаюсь расшифровать 3gp с кодом ниже:FFmpeg ошибка декодирования

#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 

спасибо большое!


EDITED

Я прочитал на 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, чтобы андроид я создал подобный метод под названием 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]); 

Я получаю позицию последовательности правильно памяти, но ошибка не изменилась.

Кусок outpout:

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 

ответ

1

Вы пытаетесь расшифровать без демультиплексирования.

+0

Я не понял, пример декодирования из документов ffmpeg не имеет демультиплексирования, демультиплекс используется в другом примере. Почему мне нужно демультиплексирование? – ademar111190

Смежные вопросы