[FFmpeg-devel] [PATCH] mpegvideo_enc: add option to disable intra mbs in p frames

Ramiro Polla ramiro.polla at gmail.com
Wed May 9 21:44:25 EEST 2018


This option prevents the mpv encoders from using intra macroblocks in
predictive frames.

It is useful for glitch artists to generate input material. This option
allows them to split and merge two video files while maintaining fluid
motion from the second video without having intra macroblocks restoring
chunks of the first video.
---
 libavcodec/motion_est.c    | 4 ++--
 libavcodec/mpegvideo.h     | 2 ++
 libavcodec/mpegvideo_enc.c | 5 +++--
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 8b5ce2117a..827e2282f7 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -971,7 +971,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
         int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
         c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
 
-        if (vard*2 + 200*256 > varc)
+        if (vard*2 + 200*256 > varc && !(s->mpv_flags & FF_MPV_FLAG_NOPIMB))
             mb_type|= CANDIDATE_MB_TYPE_INTRA;
         if (varc*2 + 200*256 > vard || s->qscale > 24){
 //        if (varc*2 + 200*256 + 50*(s->lambda2>>FF_LAMBDA_SHIFT) > vard){
@@ -1042,7 +1042,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
         }
         intra_score += c->mb_penalty_factor*16;
 
-        if(intra_score < dmin){
+        if(intra_score < dmin && !(s->mpv_flags & FF_MPV_FLAG_NOPIMB)){
             mb_type= CANDIDATE_MB_TYPE_INTRA;
             s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
         }else
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index e16deb64e7..b7ac2c7b48 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -586,6 +586,7 @@ typedef struct MpegEncContext {
 #define FF_MPV_FLAG_CBP_RD       0x0008
 #define FF_MPV_FLAG_NAQ          0x0010
 #define FF_MPV_FLAG_MV0          0x0020
+#define FF_MPV_FLAG_NOPIMB       0x0040
 
 #define FF_MPV_OPT_CMP_FUNC \
 { "sad",    "Sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
@@ -617,6 +618,7 @@ FF_MPV_OPT_CMP_FUNC, \
 { "cbp_rd",         "use rate distortion optimization for CBP",          0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_CBP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
 { "naq",            "normalize adaptive quantization",                   0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_NAQ },    0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
 { "mv0",            "always try a mb with mv=<0,0>",                     0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_MV0 },    0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
+{ "nopimb",         "do not use intra mbs for predictive frames",        0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_NOPIMB }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
 { "luma_elim_threshold",   "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)",\
                                                                       FF_MPV_OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
 { "chroma_elim_threshold", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)",\
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 9fdab31a25..e41a8f40cf 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3752,6 +3752,7 @@ static int encode_picture(MpegEncContext *s, int picture_number)
 
     if(!s->umvplus){
         if(s->pict_type==AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
+            int truncate = s->mpv_flags & FF_MPV_FLAG_NOPIMB;
             s->f_code= ff_get_best_fcode(s, s->p_mv_table, CANDIDATE_MB_TYPE_INTER);
 
             if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
@@ -3762,13 +3763,13 @@ static int encode_picture(MpegEncContext *s, int picture_number)
             }
 
             ff_fix_long_p_mvs(s);
-            ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, 0);
+            ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, truncate);
             if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
                 int j;
                 for(i=0; i<2; i++){
                     for(j=0; j<2; j++)
                         ff_fix_long_mvs(s, s->p_field_select_table[i], j,
-                                        s->p_field_mv_table[i][j], s->f_code, CANDIDATE_MB_TYPE_INTER_I, 0);
+                                        s->p_field_mv_table[i][j], s->f_code, CANDIDATE_MB_TYPE_INTER_I, truncate);
                 }
             }
         }
-- 
2.11.0



More information about the ffmpeg-devel mailing list