Как использовать x264 для кодирования с помощью ffmpeg?

Я пытался использовать ffmpeg для кодирования видео, но он не работает при инициализации AVCodecContext и AVCodec. Что я делаю:

_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;    
}

Таким образом, ii терпит неудачу на avopen_codec2() с:

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

Если я прокомментирую все настройки параметров AVCodecContext - у меня будет:

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

А avcodec_open возвращает отрицательное значение. Какие шаги я делаю неправильно?

Спасибо за любую помощь (дневной снимок ffmpeg 0.10 && libx264 за вчерашний день)


person mmmaaak    schedule 14.10.2012    source источник
comment
У вас также есть предустановленные версии ffmpeg или x264 в вашей системе, помимо тех сборок, которые вы сделали?   -  person av501    schedule 15.10.2012
comment
До этого у меня не было версий этих пакетов, я установил ffmpeg с флагом x264, менеджер пакетов emerge установил оба автоматически.   -  person mmmaaak    schedule 15.10.2012
comment
Сначала нужно собрать и установить x264. Затем вы создаете ffmpeg с параметром --enable-libx264 из исходного кода. Пока вы это сделали, все должно быть в порядке. Мне было интересно, есть ли у вас конфликт ранее существовавших установок и ваших сборок.   -  person av501    schedule 15.10.2012


Ответы (1)


По моему опыту, вы должны предоставить FFMPEG как можно меньше информации при инициализации вашего кодека. Это может показаться нелогичным, но это означает, что FFMPEG будет использовать настройки по умолчанию, которые с большей вероятностью будут работать, чем ваши собственные предположения. Посмотрите, что я хотел бы включить ниже:

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

Как и в предыдущих ответах, вот рабочий пример библиотеки FFMPEG, кодирующей кадры RGB в видео H264:

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

Дополнительная мысль о вашем коде:

  • Вы вызвали регистрацию, как показано ниже?

    avcodec_register_all();

    av_register_all();

    Если вы не вызовете эти две функции в начале своего кода, ваши последующие вызовы FFMPEG завершатся ошибкой, и вы, скорее всего, столкнетесь с ошибкой сегментации.

Взгляните на связанный пример, я тестировал его на VC++ 2010, и он отлично работает.

person ALM865    schedule 20.05.2014