[FFmpeg-cvslog] avcodec/mpeg12enc: extend QP range to 28 for non linear quantizers

Michael Niedermayer git at videolan.org
Thu Jul 30 05:11:04 CEST 2015


ffmpeg | branch: master | Michael Niedermayer <michael at niedermayer.cc> | Thu Jul 30 04:42:16 2015 +0200| [bf2474c74f2c0b956c069f50483c7d104d856d8b] | committer: Michael Niedermayer

avcodec/mpeg12enc: extend QP range to 28 for non linear quantizers

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=bf2474c74f2c0b956c069f50483c7d104d856d8b
---

 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 8bf8e51..6f87117 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 e391142..c7b7101 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 ; i<FF_ARRAY_ELEMS(non_linear_qscale); i++) {
+            int diff = FFABS((non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 7)) - (int)s->lambda * 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;
         }
     }



More information about the ffmpeg-cvslog mailing list