سؤال

أحاول تشفير الفيديو باستخدام libavcodec/libavformat. يعمل الصوت بشكل رائع ، لكن عندما أحاول تشفير الفيديو ، أحصل على الأخطاء التالية:

[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 سعيدًا؟

هل كانت مفيدة؟

المحلول

لست متأكدًا مما إذا كنت قد عملت ، ولكن المعلمات التالية تعمل بالنسبة لي.

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, ، يحل الخطأ.

نصائح أخرى

لا تنس استخدام الخيارات الخاصة 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)

ما يلي هو كيفية تفسير الإعدادات المسبقة لـ FFMPEG X264.

لسوء الحظ ، لا أعرف طريقة سهلة لاستيراد الإعدادات المسبقة مثل FFMPEG. يمكنك البحث عن قيم x264 مسبقًا يتم تخزينها جميعًا في /usr/local/share/ffmpeg/libx264- {name ).ffpreset ، حيث يتم تحديد {name} لـ FFMPEG كأحد الوسيطة -vpre {name} command-line. عادةً ما تشمل FFMPEG libx264 -medium.ffpreset ثم libx264-main.ffpreset ، المحددة على أنها ffmpeg -vpre main -vpre main

يمكنك البحث عن جميع الخيارات (كما هو محدد في ملفات libx264- {name} .ffpreset) للحصول على أسماء هيكلها من خلال البحث في ملف libavcodec/options.c ، والذي يمكن العثور عليه في مستودعات FFMPEG SVN.

إليك كيفية ترجمة الإعدادات المسبقة المتوسطة والرامية إلى رمز 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 إذا كنت ترغب في تحليل هذه الإعدادات المسبقة تلقائيًا.

آمل أن تساعدك المعلومات التي قدمتها للتو أكثر قليلاً :)

أقوم بتشفير صور YUV420p إلى تنسيقات مختلفة ، باستخدام برامج ترميز مختلفة. برامج الترميز التي أخذتها من 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; 

يجب أن يعمل هذا الإعداد على معظم برامج الترميز ، لكن كان لدي مشكلة في FPS: لا تدعم كل برامج الترميز أي قيم FPS (وبعض المعلمات الأخرى أيضًا).

يبدو أن إصدار FFMPEG 20130302 يتطلب شيئًا مثل

c->profile = FF_PROFILE_H264_BASELINE;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top