From bf2474c74f2c0b956c069f50483c7d104d856d8b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 30 Jul 2015 04:42:16 +0200 Subject: [PATCH] avcodec/mpeg12enc: extend QP range to 28 for non linear quantizers Signed-off-by: Michael Niedermayer --- libavcodec/mpeg12enc.c | 10 ++++++---- libavcodec/mpegvideo_enc.c | 30 +++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 8bf8e516e2..6f87117058 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -42,9 +42,10 @@ #include "mpegutils.h" #include "mpegvideo.h" - -static const uint8_t inv_non_linear_qscale[] = { +static const int8_t inv_non_linear_qscale[] = { 0, 2, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, + -1,17,-1,18,-1,19, -1, 20, -1, 21, -1, 22, -1, + 23,-1,24,-1,-1,-1 }; static const uint8_t svcd_scan_offset_placeholder[] = { @@ -402,8 +403,9 @@ static inline void encode_mb_skip_run(MpegEncContext *s, int run) static av_always_inline void put_qscale(MpegEncContext *s) { if (s->q_scale_type) { - av_assert2(s->qscale >= 1 && s->qscale <= 12); - put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]); + int qp = inv_non_linear_qscale[s->qscale]; + av_assert2(s->qscale >= 1 && qp > 0); + put_bits(&s->pb, 5, qp); } else { put_bits(&s->pb, 5, s->qscale); } diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index e39114244c..c7b710172b 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -163,9 +163,29 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64], static inline void update_qscale(MpegEncContext *s) { - s->qscale = (s->lambda * 139 + FF_LAMBDA_SCALE * 64) >> - (FF_LAMBDA_SHIFT + 7); - s->qscale = av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax); + if (s->q_scale_type == 1) { + int i; + int bestdiff=INT_MAX; + int best = 1; + static const uint8_t non_linear_qscale[] = { + 1,2,3,4,5,6,7,8,9,10,11,12,14,16,18,20,24,26,28 + }; + + for (i = 0 ; ilambda * 139); + if (non_linear_qscale[i] < s->avctx->qmin || non_linear_qscale[i] > s->avctx->qmax) + continue; + if (diff < bestdiff) { + bestdiff = diff; + best = non_linear_qscale[i]; + } + } + s->qscale = best; + } else { + s->qscale = (s->lambda * 139 + FF_LAMBDA_SCALE * 64) >> + (FF_LAMBDA_SHIFT + 7); + s->qscale = av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax); + } s->lambda2 = (s->lambda * s->lambda + FF_LAMBDA_SCALE / 2) >> FF_LAMBDA_SHIFT; @@ -616,9 +636,9 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (s->q_scale_type == 1) { - if (avctx->qmax > 12) { + if (avctx->qmax > 28) { av_log(avctx, AV_LOG_ERROR, - "non linear quant only supports qmax <= 12 currently\n"); + "non linear quant only supports qmax <= 28 currently\n"); return -1; } }