]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libx264.c
Fix broken vbv_buffer_init handling in libx264.c
[ffmpeg] / libavcodec / libx264.c
index df7b2e806b6f95f4a257ebfa950f7ce52f79c45b..185287c1cff12e0deae78ce1810c1d79b7a3b7c5 100644 (file)
@@ -89,6 +89,7 @@ static int X264_frame(AVCodecContext *ctx, uint8_t *buf,
     int nnal, i;
     x264_picture_t pic_out;
 
+    x264_picture_init( &x4->pic );
     x4->pic.img.i_csp   = X264_CSP_I420;
     x4->pic.img.i_plane = 3;
 
@@ -99,15 +100,25 @@ static int X264_frame(AVCodecContext *ctx, uint8_t *buf,
         }
 
         x4->pic.i_pts  = frame->pts;
-        x4->pic.i_type = X264_TYPE_AUTO;
+        x4->pic.i_type =
+            frame->pict_type == FF_I_TYPE ? X264_TYPE_KEYFRAME :
+            frame->pict_type == FF_P_TYPE ? X264_TYPE_P :
+            frame->pict_type == FF_B_TYPE ? X264_TYPE_B :
+                                            X264_TYPE_AUTO;
+        if (x4->params.b_tff != frame->top_field_first) {
+            x4->params.b_tff = frame->top_field_first;
+            x264_encoder_reconfig(x4->enc, &x4->params);
+        }
     }
 
+    do {
     if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
         return -1;
 
     bufsize = encode_nals(ctx, buf, bufsize, nal, nnal, 0);
     if (bufsize < 0)
         return -1;
+    } while (!bufsize && !frame && x264_encoder_delayed_frames(x4->enc));
 
     /* FIXME: libx264 now provides DTS, but AVFrame doesn't have a field for it. */
     x4->out_pic.pts = pic_out.i_pts;
@@ -156,6 +167,7 @@ static av_cold int X264_init(AVCodecContext *avctx)
     x4->params.p_log_private        = avctx;
 
     x4->params.i_keyint_max         = avctx->gop_size;
+    x4->params.b_intra_refresh      = avctx->flags2 & CODEC_FLAG2_INTRA_REFRESH;
     x4->params.rc.i_bitrate         = avctx->bit_rate       / 1000;
     x4->params.rc.i_vbv_buffer_size = avctx->rc_buffer_size / 1000;
     x4->params.rc.i_vbv_max_bitrate = avctx->rc_max_rate    / 1000;
@@ -166,6 +178,7 @@ static av_cold int X264_init(AVCodecContext *avctx)
         if (avctx->crf) {
             x4->params.rc.i_rc_method   = X264_RC_CRF;
             x4->params.rc.f_rf_constant = avctx->crf;
+            x4->params.rc.f_rf_constant_max = avctx->crf_max;
         } else if (avctx->cqp > -1) {
             x4->params.rc.i_rc_method   = X264_RC_CQP;
             x4->params.rc.i_qp_constant = avctx->cqp;
@@ -264,15 +277,11 @@ static av_cold int X264_init(AVCodecContext *avctx)
     if (avctx->level > 0)
         x4->params.i_level_idc = avctx->level;
 
-    x4->params.rc.f_rate_tolerance =
-        (float)avctx->bit_rate_tolerance/avctx->bit_rate;
-
-    if ((avctx->rc_buffer_size != 0) &&
+    if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy &&
         (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) {
         x4->params.rc.f_vbv_buffer_init =
             (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size;
-    } else
-        x4->params.rc.f_vbv_buffer_init = 0.9;
+    }
 
     x4->params.rc.b_mb_tree               = !!(avctx->flags2 & CODEC_FLAG2_MBTREE);
     x4->params.rc.f_ip_factor             = 1 / fabs(avctx->i_quant_factor);
@@ -289,6 +298,10 @@ static av_cold int X264_init(AVCodecContext *avctx)
 
     x4->params.b_interlaced   = avctx->flags & CODEC_FLAG_INTERLACED_DCT;
 
+    x4->params.i_slice_count  = avctx->slices;
+
+    x4->params.vui.b_fullrange = avctx->pix_fmt == PIX_FMT_YUVJ420P;
+
     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER)
         x4->params.b_repeat_headers = 0;
 
@@ -315,7 +328,7 @@ static av_cold int X264_init(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodec libx264_encoder = {
+AVCodec ff_libx264_encoder = {
     .name           = "libx264",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = CODEC_ID_H264,
@@ -324,6 +337,6 @@ AVCodec libx264_encoder = {
     .encode         = X264_frame,
     .close          = X264_close,
     .capabilities   = CODEC_CAP_DELAY,
-    .pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_NONE },
+    .pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_YUVJ420P, PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
 };