I want to multiplex audio and video together using the ffmpeg encoding library with xvid264rgb codec. I can open the codec when I create the context specifying that codec, but not if I use NULL for the argument with allocate context. My understanding is I need to use NULL so I can open the audio codec as well.
In the example, the first open works with codec indicated in the allocate context. The second doesn’t.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#define WIDTH 400
#define HEIGHT 300
const AVCodec *videocodec;
bool init_video_encoder(AVCodecContext *c, int width, int height) {
int ret;
const AVRational tb_rat = {1, 30};
const AVRational fr_rat = {30, 1};
fprintf(stderr, "init video encodern");
// video
//fprintf(stderr, "speed= %d n", videocodec->speed);
c->bit_rate = 400000;
c->width = width;
c->height = height;
c->time_base = tb_rat;
c->framerate = fr_rat;
c->gop_size = 10;
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_RGB24;
if( videocodec->id == AV_CODEC_ID_H264 )
av_opt_set(c->priv_data, "preset", "slow", 0);
ret = avcodec_open2(c, videocodec, NULL);
if( ret < 0 ) {
fprintf(stderr, "failure to open codec: %sn", av_err2str(ret));
return false;
}
//avcodec_free_context(&c);
return true;
}
int main(int argc, char **argv) {
AVCodecContext *context = NULL;
videocodec = avcodec_find_encoder_by_name("libx264rgb");
if( videocodec == NULL ) {
fprintf(stderr, "video encoder 'libx264rgb' not found");
exit;
}
context = avcodec_alloc_context3(videocodec);
if( context == NULL ) {
fprintf(stderr, "could not allocate context with codec");
return false;
}
if( init_video_encoder( context, WIDTH, HEIGHT ) )
fprintf(stderr, " success initializing video encoder case onen");
else
fprintf(stderr, " failure to initialize video encoder case onen");
avcodec_close( context );
context = avcodec_alloc_context3(NULL);
if( context == NULL ) {
fprintf(stderr, "could not allocate context without codec");
return false;
}
if( init_video_encoder( context, WIDTH, HEIGHT ) )
fprintf(stderr, " success initializing video encoder case twon");
else
fprintf(stderr, " failure to initialize video encoder case twon");
avcodec_close( context );
}
Here is the error message:
broken ffmpeg default settings detected
use an encoding preset (e.g. -vpre medium)
preset usage: -vpre <speed> -vpre <profile>
speed presets are listed in x264 --help
profile is optional; x264 defaults to high
failure to open codec: Generic error in an external library
failure to initialize video encoder case two
Is this the right approach to use? How do I set the encoding preset? The code appears already to do that.