2010-08-24 16 views
18

Ich versuche, Video mit libavcodec/libavformat zu kodieren. Audio funktioniert gut, aber wenn ich versuche Video zu kodieren ich folgende Fehlermeldungen erhalten:Wie codiert man h.264 mit libavcodec/x264?

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

einfach die Befehlszeile ffmpeg zu beheben, aber ich bin versucht, dies in C zu tun meine Optionen sind

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; 

, aber avcodec_open() schlägt fehl.

Welche anderen Werte muss ich einstellen, um x264 glücklich zu machen?

+1

Blick auf die Arbeitsbeispiele: Amtlicher https://github.com/FFmpeg/FFmpeg/tree/n3.0/doc/examples, Mine: http: // Stackoverflow .com/a/36405714/895245 –

Antwort

10

Nicht sicher, ob Sie es funktioniert haben, aber die folgenden Parameter funktionieren für mich.

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; 

die Fehlermeldung broken ffmpeg default settings detected wird in der x264-Bibliothek in x264/encoder/encoder.c angezeigt, wenn zu viele Einstellungen die Standard ffmpeg Einstellungen (z qmin = 2, qmax = 31, qcompress = 0.5) sind, etwas diese drei Werte an sich ändernde sonst, zum Beispiel qmin = 10, qmax = 51, qcompress = 0.6, behebt den Fehler.

+0

Ich brauche mehr Einblick in 'ctx-> flags' und' ctx-> flags2'. Wo kann ich finden? – nmxprime

+0

Ich bekomme nach – Setheron

3

Ich kodiere YUV420P Bilder in verschiedene Formate, mit verschiedenen Codecs. CodecID, die ich von AVOutputFormat genommen habe, nachdem ich die Funktion guess_format (...) benutzt habe. Aber auch andere Codec-Einstellungen sind (Alle von ihnen wurde von ffmpeg Beispiele Quellcode genommen wurde):

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; 

Diese Einstellung zu den meisten Codecs arbeiten müssen, aber ich hatte ein Problem mit fps: nicht alle Codecs unterstützt jede fps Werte (und einige andere Parameter auch).

+0

Danke! Ich werde es heute ausprobieren und sehen, was passiert. – szatmary

+1

Hi, sollte 'c-> flags | = CODEC_FLAG_GLOBAL_HEADER' auch für Streamingzwecke gesetzt sein? Was es macht? Wird es diesen Non-VCL-Header wiederholt (oder auf einmal) zu VCL-Nutzdaten hinzufügen oder gibt es die Nicht-VCL-NALU-Daten getrennt, die wir separat senden sollten? – nmxprime

15

Im Folgenden wird erläutert, wie die x264-Voreinstellungen des ffmpegs zu interpretieren sind.

Leider kenne ich keine einfache Möglichkeit, die Voreinstellungen wie ffmpeg zu importieren. Sie können die x264-Vorgabewerte suchen, die alle in /usr/local/share/ffmpeg/libx264-{name}.ffpreset gespeichert sind, wobei {name} für ffmpeg als Befehlszeilenargument -vpre {name} angegeben ist. So typischerweise ffmpeg würde libx264-medium.ffpreset umfassen und dann libx264-main.ffpreset, angegeben als ffmpeg -vpre Medium -vpre Haupt

Sie können alle Optionen Nachschlag (wie im libx264- {name} definiert .ffpreset Dateien), um ihre Strukturnamen zu erhalten, indem Sie in der Datei libavcodec/options.c suchen, die sich in den ffmpeg SVN-Repositories befindet.

Hier ist, wie das Medium und Haupt Voreinstellungen in C-Code übersetzt werden würde:

// 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 

Sie werden auf die ffmpeg-Quellcode suchen, wenn Sie automatisch diese Voreinstellungen analysieren möchten.

Ich hoffe, dass die Informationen, die ich würde Sie nur gab helfen ein bisschen mehr aus :)

+0

ein 'Malformed AAC bitstream detected' Problem Danke für die Zuordnung zwischen den Werten in den ffpreset Dateien und den AVCodecContext Einstellungen ... es war definitiv nicht auf den ersten Blick offensichtlich :) – Karthik

+0

so können Sie nicht verwenden Voreinstellungen im Code? – rogerdpack

21

nicht x264 privaten Optionen verwenden Vergessen. Sie können immer ein Profil einstellen:

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

Oder die niedrigste Codierung Latenz eingestellt:

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

Oder eine Voreinstellung wählen:

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

Bevor ein Codec

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

se ems, dass die ffmpeg Version 20130302 erfordert etwas wie

c->profile = FF_PROFILE_H264_BASELINE;