c++ffmpegvideo-encodinglibav

C++: Encoding H264 with FFmpeg, unable to set preset


I'm trying to encode H.264 movie with FFmpeg/libAV, when I try to set the codec preset the return code indicates an error:

...

mContext.codec = avcodec_find_encoder(AV_CODEC_ID_H264);

mContext.stream = avformat_new_stream(mContext.format_context, nullptr);
mContext.stream->id = (int)(mContext.format_context->nb_streams - 1);

mContext.codec_context = avcodec_alloc_context3(mContext.codec);

int ret;
ret = av_opt_set(mContext.codec_context->priv_data, "preset", "medium", 0);

// returns -1414549496

...

I ommited error checking for brevity in the example.

I tried setting preset to different values ("medium", "slow", "veryslow" etc.)


Solution

  • The issue is not reproducible.

    In following code sample av_opt_set returns 0:

    #include <stdio.h>
    
    extern "C"
    {
    #include "libavutil/opt.h"
    #include "libavformat/avformat.h"
    }
    
    int main()
    {
        AVOutputFormat* ofmt = av_guess_format("h264", nullptr, nullptr); //H.264
    
        if (ofmt == nullptr)
        {
            return -1;
        }
    
        AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264);
    
        if (codec == nullptr)
        {
            return -1;
        }
    
        AVFormatContext* format_context = avformat_alloc_context();
    
        if (format_context == nullptr)
        {
            return -1;
        }
    
        int ret = avformat_alloc_output_context2(&format_context, ofmt, nullptr, nullptr);
    
        if (ret != 0)
        {
            return ret;
        }
    
        AVStream* stream = avformat_new_stream(format_context, nullptr);
    
        if (stream == nullptr)
        {
            return -1;
        }
    
        stream->id = (int)(format_context->nb_streams - 1);
    
        AVCodecContext* codec_context = avcodec_alloc_context3(codec);
    
        if (codec_context == nullptr)
        {
            return -1;
        }
    
        ret = av_opt_set(codec_context->priv_data, "preset", "medium", 0);
    
        if (ret != 0)
        {
            printf("Error: av_opt_set returned: %d\n", ret);
        }
    
    
        return 0;
    }
    

    The above code checks for errors after each step.

    There are no errors...


    My guess is that your version of FFmpeg does not include libx264 encoder.
    avcodec_find_encoder(AV_CODEC_ID_H264) returns other H.264 encoder (not libx264).
    The other encoder doesn't have the medium preset option.

    Try forcing libx264 encoder by replacing AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264); with:

    AVCodec* codec = avcodec_find_encoder_by_name("libx264");
    

    In case codec == nullptr, your FFmpeg does not include libx264 encoder.


    It's only a guess...

    In case it's not the issue, please post an executable code sample.