Pregunta

Estoy intentando codificar video usando LibavCodec/Libavformat. El audio funciona muy bien, pero cuando intento codificar el video obtengo los siguientes errores:

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

Fácil de solucionar usando la línea de comando ffmpeg, pero estoy tratando de hacer esto en C. Mis opciones son

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;  

Pero AvCodec_open () falla.

¿Qué otros valores necesito configurar para hacer feliz x264?

¿Fue útil?

Solución

No estoy seguro de si lo hizo funcionar, pero los siguientes parámetros funcionan para mí.

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;

El mensaje de error broken ffmpeg default settings detected se muestra en la biblioteca x264 en x264/encoder/encoder.c Cuando demasiadas configuraciones son la configuración predeterminada de FFMPEG (por ejemplo, qmin = 2, qmax = 31, qcompress = 0.5), cambiando estos tres valores a otra cosa, por ejemplo qmin = 10, qmax = 51, qcompress = 0.6, resuelve el error.

Otros consejos

No olvide usar opciones privadas X264. Siempre puedes establecer un perfil:

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

O establezca la latencia de codificación más baja:

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

O seleccione un preajuste:

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

Antes de abrir un códec

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

Lo siguiente es cómo interpretar los presets X264 de FFMPEG.

Desafortunadamente, no sé de una manera fácil de importar los preajustes como lo hace FFMPEG. Puede buscar los valores preestablecidos x264 que se almacenan en /usr/local/share/ffmpeg/libx264- =namehenghpress, donde {name} se especifica para ffmpeg como el argumento de línea -line -vpre {name}. Por lo tanto, típicamente FFMPEG incluiría libx264 -medium.ffPreset y luego libx264 -main.ffpreset, especificado como ffmpeg -vpre mediano -vpre principal

Puede buscar todas las opciones (como se define en los archivos libx264- {name} .ffPreset) para obtener sus nombres de estructura buscando en el archivo libavcodec/options.c, que se puede encontrar en los repositorios FFMPEG SVN.

Así es como se traduciría los preajustes medios y principales al código 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

Tendrá que mirar el código fuente de FFMPEG si desea analizar esos presets automáticamente.

Espero que la información que acabo de dar te ayude un poco más :)

Codifique las imágenes YUV420P en diferentes formatos, utilizando diferentes códecs. Codecid tomé de AvoutputFormat después de usar la función Guess_Format (...). Pero otras configuraciones de códec son (todas ellas se han tomado del código fuente de los ejemplos de 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; 

Esta configuración debe funcionar para la mayoría de los códecs, pero tuve un problema con FPS: no todos los códecs admiten ningún valor de FPS (y algunos otros parámetros también).

Parece que la versión 20130302 de FFMPEG requiere algo como

c->profile = FF_PROFILE_H264_BASELINE;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top