0
votes

I tryed to use ffmpeg for encoding video/ But it fails on initialization of AVCodecContext annd AVCodec. What I do:

_codec = avcodec_find_encoder(CODEC_ID_H264);
_codecContext = avcodec_alloc_context3(_codec);
_codecContext->coder_type = 0;
_codecContext->me_cmp|= 1;
_codecContext->me_method=ME_HEX;
_codecContext->me_subpel_quality = 0;
_codecContext->me_range = 16;
_codecContext->gop_size = 12;
_codecContext->scenechange_threshold = 40;
_codecContext->i_quant_factor = 0.71;
_codecContext->b_frame_strategy = 1;
_codecContext->qcompress = 0.5;
_codecContext->qmin = 2;
_codecContext->qmax = 31;
_codecContext->max_qdiff = 4;
_codecContext->max_b_frames = 3;
_codecContext->refs = 3;
_codecContext->trellis = 1;
_codecContext->width = format.biWidth;
_codecContext->height = format.biHeight;
_codecContext->time_base.num = 1;
_codecContext->time_base.den = 30;
_codecContext->pix_fmt = PIX_FMT_YUV420P; 
_codecContext->chromaoffset = 0;
_codecContext->thread_count =1;
_codecContext->bit_rate = (int)(128000.f * 0.80f);
_codecContext->bit_rate_tolerance = (int) (128000.f * 0.20f);
int error = avcodec_open2(_codecContext, _codec, NULL);
if(error<   )
{
    std::cout<<"Open codec fail. Error "<<error<<"\n";
    return NULL;    
}

In such way ii fails on avopen_codec2() with:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xae1fdb70 (LWP 30675)]
0xb2eb2cbb in x264_param_default () from /usr/lib/libx264.so.120

If i comment all AVCodecContext parameters settins - I have :

[libx264 @ 0xac75edd0] invalid width x height (0x0)

And avcodec_open retunrs negative value. Which steps, I'm doing, are wrong?

Thanks for any help (ffmpeg 0.10 && libx264 daily snapshot for yesterday)

1
Do you also have preinstalled versions of ffmpeg or x264 on your system apart from the builds you did?av501
I haven't any versions of this packets before it, I installed ffmpeg with x264 flag, emerge packet manager installed both of them automaticaly.mmmaaak
You have to build and install x264 first. Then you build ffmpeg with --enable-libx264 from source. As long as you did that it should be fine. I was wondering if you have a clash of preexisting installs and your buildsav501

1 Answers

1
votes

In my experience you should give FFMPEG the least amount of information when initialising your codec as possible. This may seem counter intuitive but it means that FFMPEG will use it's default settings that are more likely to work than your own guesses. See what I would include below:

AVStream *st;
m_video_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
st = avformat_new_stream(_outputCodec, m_video_codec);
_outputCodecContext = st->codec;
_outputCodecContext->codec_id = m_fmt->video_codec;
_outputCodecContext->bit_rate = m_AVIMOV_BPS;           //Bits Per Second 
_outputCodecContext->width    = m_AVIMOV_WIDTH;         //Note Resolution must be a multiple of 2!!
_outputCodecContext->height   = m_AVIMOV_HEIGHT;        //Note Resolution must be a multiple of 2!!
_outputCodecContext->time_base.den = m_AVIMOV_FPS;      //Frames per second
_outputCodecContext->time_base.num = 1;
_outputCodecContext->gop_size      = m_AVIMOV_GOB;      // Intra frames per x P frames
_outputCodecContext->pix_fmt       = AV_PIX_FMT_YUV420P;//Do not change this, H264 needs YUV format not RGB

As in previous answers, here is a working example of the FFMPEG library encoding RGB frames to a H264 video:

http://www.imc-store.com.au/Articles.asp?ID=276

An extra thought on your code though:

  • Have you called register all like below?

    avcodec_register_all();

    av_register_all();

    If you don't call these two functions near the start of your code your subsequent calls to FFMPEG will fail and you'll most likely seg-fault.

Have a look at the linked example, I tested it on VC++2010 and it works perfectly.