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.