Browse code

libavcodec/dnxhdenc: add support for variable mircoblock counts

dnxhr has variable resolution, 8160 is the mb num for 1920x1080

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

Mark Reid authored on 2016/07/17 11:37:38
Showing 2 changed files
... ...
@@ -271,11 +271,11 @@ fail:
271 271
 
272 272
 static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx)
273 273
 {
274
-    FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_rc, (ctx->m.avctx->qmax + 1), 8160 * sizeof(RCEntry), fail);
274
+    FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_rc, (ctx->m.avctx->qmax + 1),
275
+                          ctx->m.mb_num * sizeof(RCEntry), fail);
275 276
     if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)
276 277
         FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp,
277 278
                           ctx->m.mb_num, sizeof(RCCMPEntry), fail);
278
-
279 279
     ctx->frame_bits = (ctx->cid_table->coding_unit_size -
280 280
                        640 - 4 - ctx->min_padding) * 8;
281 281
     ctx->qscale = 1;
... ...
@@ -661,8 +661,8 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg,
661 661
                 ssd += dnxhd_ssd_block(block, src_block);
662 662
             }
663 663
         }
664
-        ctx->mb_rc[qscale][mb].ssd  = ssd;
665
-        ctx->mb_rc[qscale][mb].bits = ac_bits + dc_bits + 12 +
664
+        ctx->mb_rc[(qscale * ctx->m.mb_num) + mb].ssd  = ssd;
665
+        ctx->mb_rc[(qscale * ctx->m.mb_num) + mb].bits = ac_bits + dc_bits + 12 +
666 666
                                       8 * ctx->vlc_bits[0];
667 667
     }
668 668
     return 0;
... ...
@@ -818,17 +818,20 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
818 818
                 unsigned min = UINT_MAX;
819 819
                 int qscale = 1;
820 820
                 int mb     = y * ctx->m.mb_width + x;
821
+                int rc = 0;
821 822
                 for (q = 1; q < avctx->qmax; q++) {
822
-                    unsigned score = ctx->mb_rc[q][mb].bits * lambda +
823
-                                     ((unsigned) ctx->mb_rc[q][mb].ssd << LAMBDA_FRAC_BITS);
823
+                    int i = (q*ctx->m.mb_num) + mb;
824
+                    unsigned score = ctx->mb_rc[i].bits * lambda +
825
+                                     ((unsigned) ctx->mb_rc[i].ssd << LAMBDA_FRAC_BITS);
824 826
                     if (score < min) {
825 827
                         min    = score;
826 828
                         qscale = q;
829
+                        rc = i;
827 830
                     }
828 831
                 }
829
-                bits += ctx->mb_rc[qscale][mb].bits;
832
+                bits += ctx->mb_rc[rc].bits;
830 833
                 ctx->mb_qscale[mb] = qscale;
831
-                ctx->mb_bits[mb]   = ctx->mb_rc[qscale][mb].bits;
834
+                ctx->mb_bits[mb]   = ctx->mb_rc[rc].bits;
832 835
             }
833 836
             bits = (bits + 31) & ~31; // padding
834 837
             if (bits > ctx->frame_bits)
... ...
@@ -889,7 +892,7 @@ static int dnxhd_find_qscale(DNXHDEncContext *ctx)
889 889
                                NULL, NULL, ctx->m.mb_height);
890 890
         for (y = 0; y < ctx->m.mb_height; y++) {
891 891
             for (x = 0; x < ctx->m.mb_width; x++)
892
-                bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits;
892
+                bits += ctx->mb_rc[(qscale*ctx->m.mb_num) + (y*ctx->m.mb_width+x)].bits;
893 893
             bits = (bits+31)&~31; // padding
894 894
             if (bits > ctx->frame_bits)
895 895
                 break;
... ...
@@ -998,17 +1001,18 @@ static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
998 998
     for (y = 0; y < ctx->m.mb_height; y++) {
999 999
         for (x = 0; x < ctx->m.mb_width; x++) {
1000 1000
             int mb = y * ctx->m.mb_width + x;
1001
+            int rc = (ctx->qscale * ctx->m.mb_num ) + mb;
1001 1002
             int delta_bits;
1002 1003
             ctx->mb_qscale[mb] = ctx->qscale;
1003
-            ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits;
1004
-            max_bits += ctx->mb_rc[ctx->qscale][mb].bits;
1004
+            ctx->mb_bits[mb] = ctx->mb_rc[rc].bits;
1005
+            max_bits += ctx->mb_rc[rc].bits;
1005 1006
             if (!RC_VARIANCE) {
1006
-                delta_bits = ctx->mb_rc[ctx->qscale][mb].bits -
1007
-                             ctx->mb_rc[ctx->qscale + 1][mb].bits;
1007
+                delta_bits = ctx->mb_rc[rc].bits -
1008
+                             ctx->mb_rc[rc + ctx->m.mb_num].bits;
1008 1009
                 ctx->mb_cmp[mb].mb = mb;
1009 1010
                 ctx->mb_cmp[mb].value =
1010
-                    delta_bits ? ((ctx->mb_rc[ctx->qscale][mb].ssd -
1011
-                                   ctx->mb_rc[ctx->qscale + 1][mb].ssd) * 100) /
1011
+                    delta_bits ? ((ctx->mb_rc[rc].ssd -
1012
+                                   ctx->mb_rc[rc + ctx->m.mb_num].ssd) * 100) /
1012 1013
                                   delta_bits
1013 1014
                                : INT_MIN; // avoid increasing qscale
1014 1015
             }
... ...
@@ -1022,10 +1026,11 @@ static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
1022 1022
         radix_sort(ctx->mb_cmp, ctx->m.mb_num);
1023 1023
         for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
1024 1024
             int mb = ctx->mb_cmp[x].mb;
1025
-            max_bits -= ctx->mb_rc[ctx->qscale][mb].bits -
1026
-                        ctx->mb_rc[ctx->qscale + 1][mb].bits;
1025
+            int rc = (ctx->qscale * ctx->m.mb_num ) + mb;
1026
+            max_bits -= ctx->mb_rc[rc].bits -
1027
+                        ctx->mb_rc[rc + ctx->m.mb_num].bits;
1027 1028
             ctx->mb_qscale[mb] = ctx->qscale + 1;
1028
-            ctx->mb_bits[mb]   = ctx->mb_rc[ctx->qscale + 1][mb].bits;
1029
+            ctx->mb_bits[mb]   = ctx->mb_rc[rc + ctx->m.mb_num].bits;
1029 1030
         }
1030 1031
     }
1031 1032
     return 0;
... ...
@@ -89,7 +89,7 @@ typedef struct DNXHDEncContext {
89 89
     uint8_t  *mb_qscale;
90 90
 
91 91
     RCCMPEntry *mb_cmp;
92
-    RCEntry   (*mb_rc)[8160];
92
+    RCEntry    *mb_rc;
93 93
 
94 94
     void (*get_pixels_8x4_sym)(int16_t * /* align 16 */,
95 95
                                const uint8_t *, ptrdiff_t);