Browse code

libavcodec/dnxhdenc: add edge emulate for dnxhr

Fixes handling for resolutions that are not multiples of 16.

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

Mark Reid authored on 2016/08/08 08:15:27
Showing 2 changed files
... ...
@@ -368,6 +368,9 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
368 368
     ff_pixblockdsp_init(&ctx->m.pdsp, avctx);
369 369
     ff_dct_encode_init(&ctx->m);
370 370
 
371
+    if (ctx->profile != FF_PROFILE_DNXHD)
372
+        ff_videodsp_init(&ctx->m.vdsp, bit_depth);
373
+
371 374
     if (!ctx->m.dct_quantize)
372 375
         ctx->m.dct_quantize = ff_dct_quantize_c;
373 376
 
... ...
@@ -617,6 +620,10 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
617 617
 {
618 618
     const int bs = ctx->block_width_l2;
619 619
     const int bw = 1 << bs;
620
+    int dct_y_offset = ctx->dct_y_offset;
621
+    int dct_uv_offset = ctx->dct_uv_offset;
622
+    int linesize = ctx->m.linesize;
623
+    int uvlinesize = ctx->m.uvlinesize;
620 624
     const uint8_t *ptr_y = ctx->thread[0]->src[0] +
621 625
                            ((mb_y << 4) * ctx->m.linesize) + (mb_x << bs + 1);
622 626
     const uint8_t *ptr_u = ctx->thread[0]->src[1] +
... ...
@@ -624,26 +631,56 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
624 624
     const uint8_t *ptr_v = ctx->thread[0]->src[2] +
625 625
                            ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs);
626 626
     PixblockDSPContext *pdsp = &ctx->m.pdsp;
627
+    VideoDSPContext *vdsp = &ctx->m.vdsp;
628
+
629
+    if (vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.avctx->width ||
630
+                                   (mb_y << 4) + 16 > ctx->m.avctx->height)) {
631
+        int y_w = ctx->m.avctx->width  - (mb_x << 4);
632
+        int y_h = ctx->m.avctx->height - (mb_y << 4);
633
+        int uv_w = (y_w + 1) / 2;
634
+        int uv_h = y_h;
635
+        linesize = 16;
636
+        uvlinesize = 8;
637
+
638
+        vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y,
639
+                               linesize, ctx->m.linesize,
640
+                               linesize, 16,
641
+                               0, 0, y_w, y_h);
642
+        vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u,
643
+                               uvlinesize, ctx->m.uvlinesize,
644
+                               uvlinesize, 16,
645
+                               0, 0, uv_w, uv_h);
646
+        vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v,
647
+                               uvlinesize, ctx->m.uvlinesize,
648
+                               uvlinesize, 16,
649
+                               0, 0, uv_w, uv_h);
650
+
651
+        dct_y_offset =  bw * linesize;
652
+        dct_uv_offset = bw * uvlinesize;
653
+        ptr_y = &ctx->edge_buf_y[0];
654
+        ptr_u = &ctx->edge_buf_uv[0][0];
655
+        ptr_v = &ctx->edge_buf_uv[1][0];
656
+    }
627 657
 
628
-    pdsp->get_pixels(ctx->blocks[0], ptr_y,      ctx->m.linesize);
629
-    pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, ctx->m.linesize);
630
-    pdsp->get_pixels(ctx->blocks[2], ptr_u,      ctx->m.uvlinesize);
631
-    pdsp->get_pixels(ctx->blocks[3], ptr_v,      ctx->m.uvlinesize);
658
+    pdsp->get_pixels(ctx->blocks[0], ptr_y,      linesize);
659
+    pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize);
660
+    pdsp->get_pixels(ctx->blocks[2], ptr_u,      uvlinesize);
661
+    pdsp->get_pixels(ctx->blocks[3], ptr_v,      uvlinesize);
632 662
 
633
-    if (mb_y + 1 == ctx->m.mb_height && (ctx->m.avctx->height % 16) != 0) {
663
+    if (mb_y + 1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
634 664
         if (ctx->interlaced) {
635 665
             ctx->get_pixels_8x4_sym(ctx->blocks[4],
636
-                                    ptr_y + ctx->dct_y_offset,
637
-                                    ctx->m.linesize);
666
+                                    ptr_y + dct_y_offset,
667
+                                    linesize);
638 668
             ctx->get_pixels_8x4_sym(ctx->blocks[5],
639
-                                    ptr_y + ctx->dct_y_offset + bw,
640
-                                    ctx->m.linesize);
669
+                                    ptr_y + dct_y_offset + bw,
670
+                                    linesize);
641 671
             ctx->get_pixels_8x4_sym(ctx->blocks[6],
642
-                                    ptr_u + ctx->dct_uv_offset,
643
-                                    ctx->m.uvlinesize);
672
+                                    ptr_u + dct_uv_offset,
673
+                                    uvlinesize);
644 674
             ctx->get_pixels_8x4_sym(ctx->blocks[7],
645
-                                    ptr_v + ctx->dct_uv_offset,
646
-                                    ctx->m.uvlinesize);
675
+                                    ptr_v + dct_uv_offset,
676
+                                    uvlinesize);
647 677
         } else {
648 678
             ctx->bdsp.clear_block(ctx->blocks[4]);
649 679
             ctx->bdsp.clear_block(ctx->blocks[5]);
... ...
@@ -652,13 +689,13 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
652 652
         }
653 653
     } else {
654 654
         pdsp->get_pixels(ctx->blocks[4],
655
-                         ptr_y + ctx->dct_y_offset, ctx->m.linesize);
655
+                         ptr_y + dct_y_offset, linesize);
656 656
         pdsp->get_pixels(ctx->blocks[5],
657
-                         ptr_y + ctx->dct_y_offset + bw, ctx->m.linesize);
657
+                         ptr_y + dct_y_offset + bw, linesize);
658 658
         pdsp->get_pixels(ctx->blocks[6],
659
-                         ptr_u + ctx->dct_uv_offset, ctx->m.uvlinesize);
659
+                         ptr_u + dct_uv_offset, uvlinesize);
660 660
         pdsp->get_pixels(ctx->blocks[7],
661
-                         ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize);
661
+                         ptr_v + dct_uv_offset, uvlinesize);
662 662
     }
663 663
 }
664 664
 
... ...
@@ -71,6 +71,8 @@ typedef struct DNXHDEncContext {
71 71
     int intra_quant_bias;
72 72
 
73 73
     DECLARE_ALIGNED(16, int16_t, blocks)[8][64];
74
+    uint8_t edge_buf_y[256];
75
+    uint8_t edge_buf_uv[2][128];
74 76
 
75 77
     int      (*qmatrix_c)     [64];
76 78
     int      (*qmatrix_l)     [64];