Home > other >  C : Encoding H264 with FFmpeg, unable to set preset
C : Encoding H264 with FFmpeg, unable to set preset

Time:01-04

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.)

CodePudding user response:

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

// returns -1414549496

I don't think you're allowed to touch priv_data. Why don't you call av_opt_set() on the codec_context directly? See e.g. here.

CodePudding user response:

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.

  • Related