Opened 4 years ago

Closed 4 years ago

#4722 closed defect (needs_more_info)

avcodec_alloc_context3 returns NULL - without error

Reported by: TheSHEEEP Owned by:
Priority: normal Component: avcodec
Version: 2.7 Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:

I am trying to decode an .ogg file containing vorbis audio.
However, I cannot even avcodec_open2(), as avcodec_alloc_context3 returns NULL without logging any errors, so I have no idea what is wrong.
Naturally, the following avcodec_open2 fails.

It does not make a difference if I call avcodec_alloc_context3 with an AVCodec* or with NULL, it always returns a null-pointer.

Please, do not return NULL pointer in this function.
I have attached the file I used to test, but I doubt the file is the problem here, it can played fine with any player.

Here is the code I use:

    av_register_all();
    avcodec_register_all();
    av_log_set_callback(log_callback);
    av_log_set_level(AV_LOG_TRACE);

    int result = avformat_open_input(&_formatContext, fileName, NULL, NULL);
    if (result < 0) 
    {
        char errorBuf[1024];
        av_make_error_string(errorBuf, 1024, result);
        LOG_DECODING << "ERROR: Could not open input: " << (_path + _fileName) << "\n"
                << errorBuf;
        return;
    }
    
    // Read stream information
    if (avformat_find_stream_info(_formatContext, NULL) < 0) 
    {
        LOG_DECODING << "ERROR: Could not find stream information: " << (_path + _fileName);
        return;
    }

    AVStream* stream;
    AVCodec* decodeCodec = NULL;
    
    // Find the stream
    int streamIndex = av_find_best_stream(_formatContext, p_type, -1, -1, NULL, 0);
    if (streamIndex < 0) 
    {
        LOG_DECODING << "ERROR: Could not find stream of type: " << av_get_media_type_string(p_type);
        return false;
    } 
    else 
    {
        stream = _formatContext->streams[streamIndex];
        
        // Find decoder codec
        decodeCodec = avcodec_find_decoder(stream->codec->codec_id);
        if (!decodeCodec) 
        {
            LOG_DECODING << "Failed to find codec: " << av_get_media_type_string(p_type);
            return false;
        }
        
        // Allocate the context
        // THIS returns NULL 
        decodeCodecContext = avcodec_alloc_context3(decodeCodec);
        
        // Open decode codec & context
        // With decodeCodecContext == NULL, this naturally fails
        int result = avcodec_open2(decodeCodecContext, decodeCodec, NULL);
        if (result < 0) 
        {
            char errorBuf[1024];
            av_make_error_string(errorBuf, 1024, result);
            LOG_DECODING << "Failed to open codec: " << av_get_media_type_string(p_type) << "\n    " << errorBuf;
            return false;
        }
    }

Attachments (1)

saxophone.ogg (221.4 KB) - added by TheSHEEEP 4 years ago.
The .ogg file used when the problem appears (actually the problem appears with all testes ogg files)

Download all attachments as: .zip

Change History (11)

comment:1 follow-up: Changed 4 years ago by TheSHEEEP

I wanted to attach the .ogg file that I use, but I get an error:
IndexError?: pop from empty list

comment:2 Changed 4 years ago by TheSHEEEP

With "Please, do not return NULL pointer in this function." I mean not to do so without at least sending an error to the callback.

comment:3 Changed 4 years ago by cehoyos

  • Priority changed from important to normal

Is the problem you see reproducible with current FFmpeg git head?

comment:4 follow-ups: Changed 4 years ago by gjdfgh

This function fails only if memory allocation fails, and it allocates only little memory. codec=NULL should work too, and also only fails if a small memory allocation fails.

Is the problem you see reproducible with current FFmpeg git head?

This question makes no sense.

comment:5 in reply to: ↑ 4 Changed 4 years ago by TheSHEEEP

Replying to gjdfgh:

This function fails only if memory allocation fails, and it allocates only little memory. codec=NULL should work too, and also only fails if a small memory allocation fails.

That's what I would guess, but memory allocation is not a problem, the program allocates lots of it before, after and likely even at the same time in other threads. No worries, though, FFmpeg usage is limited to one thread only.

I found out a workaround, though I have to say I do not understand it.
If I do not use

 decodeCodecContext = avcodec_alloc_context3(decodeCodec);

and instead do the following

 decodeCodecContext = stream->codec;

Everything works correctly.

Maybe avcodec_find_decoder does something that forbids the allocation of a new codec context?
If so, it should clearly be stated.

comment:6 Changed 4 years ago by gjdfgh

decodeCodecContext = stream->codec;

No, this is deprecated and/or not recommended. Normally you should create your own AVCodecContext for decoding, copy all needed codec parameters, and then open it. You can use avcodec_copy_context() for copying the parameters.

comment:7 Changed 4 years ago by TheSHEEEP

Well, I'd love to, but the problem remains ;)
I'd rather use something deprecated that works than a suggested way than doesn't.

Version 0, edited 4 years ago by TheSHEEEP (next)

comment:8 in reply to: ↑ 4 Changed 4 years ago by cehoyos

Replying to gjdfgh:

Is the problem you see reproducible with current FFmpeg git head?

This question makes no sense.

I don't understand: Could you elaborate?

comment:9 in reply to: ↑ 1 Changed 4 years ago by beastd

Replying to TheSHEEEP:

I wanted to attach the .ogg file that I use, but I get an error:
IndexError?: pop from empty list

This problem should not occur anymore.

Sorry for the inconvenience.

Changed 4 years ago by TheSHEEEP

The .ogg file used when the problem appears (actually the problem appears with all testes ogg files)

comment:10 Changed 4 years ago by cehoyos

  • Resolution set to needs_more_info
  • Status changed from new to closed

The code you posted does not compile.
Please feel free to reopen this ticket if the issue is reproducible with current FFmpeg git head and if you can explain how to reproduce.

Note: See TracTickets for help on using tickets.