summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorRamiro Polla <ramiro.polla@gmail.com>2019-10-23 21:12:32 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2019-10-24 19:45:17 +0200
commit531fbce0b281be2450bbf0230c2de539230a7d84 (patch)
treee3877cf6dc62207f045d0144bd610b92471c1221 /libavcodec
parent3d5d0301c3d8b0c550db78730e9cfc017d6db5fb (diff)
downloadffmpeg-531fbce0b281be2450bbf0230c2de539230a7d84.tar.gz
mpegvideo_enc: add intra_penalty option for p frames
This option allows more control over the use of intra macroblocks in predictive frames. By using '-intra_penalty max', intra macroblocks are never used 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. Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/motion_est.c10
-rw-r--r--libavcodec/motion_est.h2
-rw-r--r--libavcodec/mpegvideo.h3
-rw-r--r--libavcodec/mpegvideo_enc.c6
-rw-r--r--libavcodec/svq1enc.c2
5 files changed, 13 insertions, 10 deletions
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 759eea479d..02c75fd470 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->intra_penalty)
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){
@@ -1040,7 +1040,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
intra_score= s->mecc.mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16);
}
- intra_score += c->mb_penalty_factor*16;
+ intra_score += c->mb_penalty_factor*16 + s->intra_penalty;
if(intra_score < dmin){
mb_type= CANDIDATE_MB_TYPE_INTRA;
@@ -1648,7 +1648,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
}
}
-void ff_fix_long_p_mvs(MpegEncContext * s)
+void ff_fix_long_p_mvs(MpegEncContext * s, int type)
{
MotionEstContext * const c= &s->me;
const int f_code= s->f_code;
@@ -1682,8 +1682,8 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
if( mx >=range || mx <-range
|| my >=range || my <-range){
s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V;
- s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA;
- s->current_picture.mb_type[i] = CANDIDATE_MB_TYPE_INTRA;
+ s->mb_type[i] |= type;
+ s->current_picture.mb_type[i] = type;
}
}
}
diff --git a/libavcodec/motion_est.h b/libavcodec/motion_est.h
index 3b3a8d7341..817220f340 100644
--- a/libavcodec/motion_est.h
+++ b/libavcodec/motion_est.h
@@ -127,7 +127,7 @@ int ff_get_mb_score(struct MpegEncContext *s, int mx, int my, int src_index,
int ff_get_best_fcode(struct MpegEncContext *s,
int16_t (*mv_table)[2], int type);
-void ff_fix_long_p_mvs(struct MpegEncContext *s);
+void ff_fix_long_p_mvs(struct MpegEncContext *s, int type);
void ff_fix_long_mvs(struct MpegEncContext *s, uint8_t *field_select_table,
int field_select, int16_t (*mv_table)[2], int f_code,
int type, int truncate);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index e1ff5f97dc..29e692f245 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -580,6 +580,8 @@ typedef struct MpegEncContext {
int scenechange_threshold;
int noise_reduction;
+
+ int intra_penalty;
} MpegEncContext;
/* mpegvideo_enc common options */
@@ -664,6 +666,7 @@ FF_MPV_OPT_CMP_FUNC, \
{"ps", "RTP payload size in bytes", FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"mepc", "Motion estimation bitrate penalty compensation (1.0 = 256)", FF_MPV_OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"mepre", "pre motion estimation", FF_MPV_OFFSET(me_pre), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"intra_penalty", "Penalty for intra blocks in block decision", FF_MPV_OFFSET(intra_penalty), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX/2, FF_MPV_OPT_FLAGS }, \
{"a53cc", "Use A53 Closed Captions (if available)", FF_MPV_OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FF_MPV_OPT_FLAGS }, \
extern const AVOption ff_mpv_generic_options[];
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index f12e603215..96f5b4a666 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3761,14 +3761,14 @@ static int encode_picture(MpegEncContext *s, int picture_number)
s->f_code= FFMAX3(s->f_code, a, b);
}
- 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_p_mvs(s, s->intra_penalty ? CANDIDATE_MB_TYPE_INTER : CANDIDATE_MB_TYPE_INTRA);
+ ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, !!s->intra_penalty);
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, !!s->intra_penalty);
}
}
}
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 80a8af1ef7..651013588f 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -345,7 +345,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
s->m.first_slice_line = 0;
}
- ff_fix_long_p_mvs(&s->m);
+ ff_fix_long_p_mvs(&s->m, CANDIDATE_MB_TYPE_INTRA);
ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code,
CANDIDATE_MB_TYPE_INTER, 0);
}