2010-08-24 7 views
18

Я пытаюсь закодировать видео, используя libavcodec/libavformat. Аудио отлично работает, но когда я пытаюсь кодировать видео я получаю следующие ошибки:Как закодировать h.264 с помощью libavcodec/x264?

[libx264 @ 0x10182a000]broken ffmpeg default settings detected 
[libx264 @ 0x10182a000]use an encoding preset (vpre) 

легко исправить с помощью FFmpeg командной строки, но я пытаюсь сделать это в C. мои варианты

AVStream *pVideoOutStream = av_new_stream(pOutFormatCtx, 0); 
AVCodecContext *pVideoOutCodecCtx = pVideoOutStream->codec; 

pVideoOutCodecCtx->codec_id  = CODEC_ID_H264;  
pVideoOutCodecCtx->codec_type  = CODEC_TYPE_VIDEO; 
pVideoOutCodecCtx->bit_rate  = pVideoInCodecCtx->bit_rate; 
pVideoOutCodecCtx->width   = pVideoInCodecCtx->width;  
pVideoOutCodecCtx->height   = pVideoInCodecCtx->height; 
pVideoOutCodecCtx->pix_fmt   = pVideoInCodecCtx->pix_fmt;  
pVideoOutCodecCtx->sample_rate  = pVideoInCodecCtx->sample_rate;  
pVideoOutCodecCtx->gop_size  = 30; 

, но avcodec_open() не работает.

Какие еще значения необходимо установить, чтобы сделать x264 счастливым?

+1

Посмотрите на рабочие примеры: официальные https://github.com/FFmpeg/FFmpeg/tree/n3.0/doc/examples, мое: HTTP: // StackOverflow .com/a/36405714/895245 –

ответ

10

Не уверен, что у вас это работает, но для меня работают следующие параметры.

ctx->bit_rate = 500*1000; 
ctx->bit_rate_tolerance = 0; 
ctx->rc_max_rate = 0; 
ctx->rc_buffer_size = 0; 
ctx->gop_size = 40; 
ctx->max_b_frames = 3; 
ctx->b_frame_strategy = 1; 
ctx->coder_type = 1; 
ctx->me_cmp = 1; 
ctx->me_range = 16; 
ctx->qmin = 10; 
ctx->qmax = 51; 
ctx->scenechange_threshold = 40; 
ctx->flags |= CODEC_FLAG_LOOP_FILTER; 
ctx->me_method = ME_HEX; 
ctx->me_subpel_quality = 5; 
ctx->i_quant_factor = 0.71; 
ctx->qcompress = 0.6; 
ctx->max_qdiff = 4; 
ctx->directpred = 1; 
ctx->flags2 |= CODEC_FLAG2_FASTPSKIP; 

сообщение об ошибке, broken ffmpeg default settings detected отображается в библиотеке x264 в x264/encoder/encoder.c, когда слишком много параметров настройки по умолчанию FFmpeg (например qmin = 2, qmax = 31, qcompress = 0.5), изменяя эти три значения к чему-то еще, например, qmin = 10, qmax = 51, qcompress = 0.6, устраняет ошибку.

+0

Мне нужно больше узнать о 'ctx-> flags' и' ctx-> flags2'. Где я могу найти? – nmxprime

+0

Я получаю ошибку «обнаруженный бит AAC» после – Setheron

3

Я кодирую изображения YUV420P в разные форматы, используя различные кодеки. CodecID, который я взял из AVOutputFormat после использования функции guess_format (...). Но другие настройки кодека (Все они были взяты из исходного кода Примеры FFmpeg):

c->codec_id = (CodecID)CODEC_ID_H264; //This is your codec id 
c->codec_type = CODEC_TYPE_VIDEO; 

c->bit_rate = 1000000; 
c->width = <...>; 
c->height = <...>; 
c->time_base.den = 25; 
c->time_base.num = 1; 
c->gop_size = 12; 
c->pix_fmt = PIX_FMT_YUV420P; 
if (c->codec_id == CODEC_ID_MPEG1VIDEO) //It not necessary for you 
    c->mb_decision=2; 
// some formats want stream headers to be separate 
if(oc->oformat->flags & AVFMT_GLOBALHEADER) 
    c->flags |= CODEC_FLAG_GLOBAL_HEADER; 

Эта установка должна работать для большинства кодеков, но у меня была проблема с кадров в секунду: не все кодеки поддерживает любой кадр значения (и некоторые другие параметры).

+0

Спасибо! Я попробую сегодня и посмотрю, что произойдет. – szatmary

+1

Привет, если 'c-> flags | = CODEC_FLAG_GLOBAL_HEADER' также будет настроен для потоковой передачи? Что оно делает? Будет ли он добавлять этот заголовок Non-VCL к полезной нагрузке VCL несколько раз (или сразу) или он дает данные NALU без VCL отдельно, что мы должны отправлять отдельно? – nmxprime

15

Ниже перечислены способы интерпретации пресетов f2mpeg x264.

К сожалению, я не знаю, как легко импортировать пресеты, такие как ffmpeg. Вы можете найти предустановленные значения x264, которые все хранятся в /usr/local/share/ffmpeg/libx264-{name}.ffpreset, где {name} указано для ffmpeg в качестве аргумента командной строки -vpre {name}. Так обычно FFmpeg будет включать libx264-medium.ffpreset, а затем libx264-main.ffpreset, указанный в качестве FFmpeg -vpre среды -vpre главный

Вы можете поиска все варианты (как это определено в libx264- {имя} .ffpreset файлы), чтобы получить имена их структур, просмотрев файл libavcodec/options.c, который можно найти в репозиториях SVN ffmpeg.

Вот как среда и основные пресеты будут переведены в код C:

// libx264-medium.ffpreset preset 
ctx->coder_type = 1; // coder = 1 
ctx->flags|=CODEC_FLAG_LOOP_FILTER; // flags=+loop 
ctx->me_cmp|= 1; // cmp=+chroma, where CHROMA = 1 
ctx->partitions|=X264_PART_I8X8+X264_PART_I4X4+X264_PART_P8X8+X264_PART_B8X8; // partitions=+parti8x8+parti4x4+partp8x8+partb8x8 
ctx->me_method=ME_HEX; // me_method=hex 
ctx->me_subpel_quality = 7; // subq=7 
ctx->me_range = 16; // me_range=16 
ctx->gop_size = 250; // g=250 
ctx->keyint_min = 25; // keyint_min=25 
ctx->scenechange_threshold = 40; // sc_threshold=40 
ctx->i_quant_factor = 0.71; // i_qfactor=0.71 
ctx->b_frame_strategy = 1; // b_strategy=1 
ctx->qcompress = 0.6; // qcomp=0.6 
ctx->qmin = 10; // qmin=10 
ctx->qmax = 51; // qmax=51 
ctx->max_qdiff = 4; // qdiff=4 
ctx->max_b_frames = 3; // bf=3 
ctx->refs = 3; // refs=3 
ctx->directpred = 1; // directpred=1 
ctx->trellis = 1; // trellis=1 
ctx->flags2|=CODEC_FLAG2_BPYRAMID+CODEC_FLAG2_MIXED_REFS+CODEC_FLAG2_WPRED+CODEC_FLAG2_8X8DCT+CODEC_FLAG2_FASTPSKIP; // flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip 
ctx->weighted_p_pred = 2; // wpredp=2 

// libx264-main.ffpreset preset 
ctx->flags2|=CODEC_FLAG2_8X8DCT;c->flags2^=CODEC_FLAG2_8X8DCT; // flags2=-dct8x8 

Вы должны посмотреть на исходный код FFmpeg, если вы хотите, чтобы автоматически анализировать эти пресеты.

Я надеюсь, что информация, которую я только что дал бы помочь вам немного больше :)

+0

Спасибо за очистку отображения между значениями в файлах ffpreset и настройками AVCodecContext ... на первый взгляд это было явно не очевидно :) – Karthik

+0

, поэтому вы не можете использовать пресетов в коде? – rogerdpack

21

Не забудьте использовать x264 частные варианты. Вы всегда можете установить профиль:

av_dict_set(&This->opts, "vprofile", "baseline", 0) 

Или установить наименьшую кодирования латентность:

av_dict_set(&This->opts, "tune", "zerolatency", 0); 

Или выберите предустановку:

av_dict_set(&This->opts, "preset","ultrafast",0); 

Перед открытием, кодеку

avcodec_open2(This->context, This->codec, &This->opts) 
0

se Эмс, что FFmpeg версия 20130302 требует что-то вроде

c->profile = FF_PROFILE_H264_BASELINE; 

 Смежные вопросы

  • Нет связанных вопросов^_^