2010-08-24 20 views
18

Estoy intentando codificar video usando libavcodec/libavformat. Audio funciona muy bien, pero cuando intento para codificar vídeo consigo los siguientes errores:Cómo codificar h.264 con libavcodec/x264?

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

fácil de solucionar mediante el ffmpeg línea de comandos, 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 falla avcodec_open().

¿Qué otros valores debo configurar para hacer feliz a x264?

+1

mirada a ejemplos de trabajo: https://github.com/FFmpeg/FFmpeg/tree/n3.0/doc/examples oficiales, la mía: http: // stackoverflow .com/a/36405714/895245 –

Respuesta

10

No estoy seguro de si funcionó, pero los siguientes parámetros me funcionan.

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 demasiados ajustes son los ajustes por defecto (por ejemplo ffmpeg qmin = 2, qmax = 31, qcompress = 0.5), el cambio de estos tres valores a otra cosa, por ejemplo, qmin = 10, qmax = 51, qcompress = 0.6, resuelve el error.

+0

necesito más información sobre 'ctx-> flags' y' ctx-> flags2'. ¿Donde puedo encontrar? – nmxprime

+0

Aparece un problema 'Bitstream AAC mal formado detectado * después de – Setheron

3

Codifico las imágenes de YUV420P en diferentes formatos, utilizando diferentes códecs. CodecID que tomé de AVOutputFormat después de usar la función guess_format (...). Sin embargo, otras configuraciones de codec están (Todos ellos se ha tomado de código fuente ejemplos 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; 

Este ajuste debe trabajar para la mayoría de los codecs, pero tuve un problema con fps: no todos los codecs soporta cualquier fps valores (y algunos otros parámetros también).

+0

¡Gracias! Voy a probarlo hoy y ver qué pasa. – szatmary

+1

Hola, ¿debería 'c-> flags | = CODEC_FLAG_GLOBAL_HEADER' establecerse también para la transmisión? ¿Que hace? ¿Agregará este encabezado No-VCL a la carga VCL repetidamente (o a la vez) o dará los datos de NALU no VCL por separado, que deberíamos enviar por separado? – nmxprime

15

A continuación se explica cómo interpretar los preajustes x264 de ffmpeg.

Desafortunadamente no sé de una manera fácil de importar los ajustes preestablecidos como ffmpeg hace. Usted puede buscar los valores x264 preestablecer los cuales están almacenados en /usr/local/share/ffmpeg/libx264-{name}.ffpreset, donde se especifica {nombre} para ffmpeg como el argumento -vpre {nombre} de línea de comandos. Así normalmente ffmpeg incluiría libx264-medium.ffpreset y luego libx264-main.ffpreset, especificado como ffmpeg -vpre medio -vpre principal

Usted puede buscar todas las opciones (como se define en el libx264- {nombre} .ffpreset archivos) para obtener sus nombres de estructura mirando en el archivo de libavcodec/options.c, que se puede encontrar en los repositorios SVN ffmpeg.

He aquí cómo el principal preajustes medio y se traducirían en 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 

Vas a tener que mirar el código fuente de FFmpeg si desea analizar los preajustes de forma automática.

espero que la información que acabo de dar le ayudaría un poco más :)

+0

Gracias por borrar la asignación entre los valores en los archivos ffpreset y la configuración AVCodecContext ... definitivamente no fue obvio a primera vista :) – Karthik

+0

por lo que no puede usar presets en el código? – rogerdpack

21

No se olvide de utilizar las opciones privadas x264. Siempre se puede establecer un perfil:

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

O establecer la codificación de baja latencia:

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

O seleccione una definición:

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

Antes de abrir un códec

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

se ems que la versión de ffmpeg 20130302 requiere algo así como

c->profile = FF_PROFILE_H264_BASELINE; 
Cuestiones relacionadas