Error while decoding AAC with avcodec_decode_audio4 ()

I am trying to decode AAC with the native FFmpeg decoder and encountered an error

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 () function return -1163346256. Is it because of the FFmpeg version? I downloaded the generic and dev version from here . Is it relevant?

Here's the source code:

#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);
}

      

I also read this question: How to decode AAC using avcodec_decode_audio4? but no solution is provided.

+3


source to share


1 answer


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;

      



Yes, it won't work. You cannot dump raw bytes from some random mux format (potentially mp4) into a decoder and expect it to work. Use av_read_frame () to read individual audio packets from the mux format and feed the resulting AVPacket to the decoder using avcodec_decode_audio4 (). See instructor apanger . I know that api-example.c uses the above code, but unfortunately only works in a very limited subset of cases. Also see API docs for detailed description .

+2


source







All Articles