]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dnxhdenc.c
Merge commit 'eccfb9778ae939764d17457f34338d140832d9e1'
[ffmpeg] / libavcodec / dnxhdenc.c
index b0ee8a20502fbf4c6003c8d677ebf4872d8d1522..60bea83c1fe7532d9f0b2c842c74316759a78b74 100644 (file)
@@ -288,9 +288,12 @@ static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx)
 {
     FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_rc, (ctx->m.avctx->qmax + 1),
                           ctx->m.mb_num * sizeof(RCEntry), fail);
-    if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)
+    if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) {
         FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp,
                           ctx->m.mb_num, sizeof(RCCMPEntry), fail);
+        FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp_tmp,
+                          ctx->m.mb_num, sizeof(RCCMPEntry), fail);
+    }
     ctx->frame_bits = (ctx->coding_unit_size -
                        ctx->data_offset - 4 - ctx->min_padding) * 8;
     ctx->qscale = 1;
@@ -324,7 +327,7 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    if (ctx->profile == FF_PROFILE_DNXHR_HQX ||
+    if (ctx->profile == FF_PROFILE_DNXHR_444 ||
         ctx->profile == FF_PROFILE_DNXHR_HQX) {
         avpriv_report_missing_feature(avctx,
                "dnxhr_444 or dnxhr_hqx profile");
@@ -368,6 +371,9 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
     ff_pixblockdsp_init(&ctx->m.pdsp, avctx);
     ff_dct_encode_init(&ctx->m);
 
+    if (ctx->profile != FF_PROFILE_DNXHD)
+        ff_videodsp_init(&ctx->m.vdsp, bit_depth);
+
     if (!ctx->m.dct_quantize)
         ctx->m.dct_quantize = ff_dct_quantize_c;
 
@@ -617,6 +623,10 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
 {
     const int bs = ctx->block_width_l2;
     const int bw = 1 << bs;
+    int dct_y_offset = ctx->dct_y_offset;
+    int dct_uv_offset = ctx->dct_uv_offset;
+    int linesize = ctx->m.linesize;
+    int uvlinesize = ctx->m.uvlinesize;
     const uint8_t *ptr_y = ctx->thread[0]->src[0] +
                            ((mb_y << 4) * ctx->m.linesize) + (mb_x << bs + 1);
     const uint8_t *ptr_u = ctx->thread[0]->src[1] +
@@ -624,26 +634,56 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
     const uint8_t *ptr_v = ctx->thread[0]->src[2] +
                            ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs);
     PixblockDSPContext *pdsp = &ctx->m.pdsp;
+    VideoDSPContext *vdsp = &ctx->m.vdsp;
+
+    if (vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.avctx->width ||
+                                   (mb_y << 4) + 16 > ctx->m.avctx->height)) {
+        int y_w = ctx->m.avctx->width  - (mb_x << 4);
+        int y_h = ctx->m.avctx->height - (mb_y << 4);
+        int uv_w = (y_w + 1) / 2;
+        int uv_h = y_h;
+        linesize = 16;
+        uvlinesize = 8;
+
+        vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y,
+                               linesize, ctx->m.linesize,
+                               linesize, 16,
+                               0, 0, y_w, y_h);
+        vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u,
+                               uvlinesize, ctx->m.uvlinesize,
+                               uvlinesize, 16,
+                               0, 0, uv_w, uv_h);
+        vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v,
+                               uvlinesize, ctx->m.uvlinesize,
+                               uvlinesize, 16,
+                               0, 0, uv_w, uv_h);
+
+        dct_y_offset =  bw * linesize;
+        dct_uv_offset = bw * uvlinesize;
+        ptr_y = &ctx->edge_buf_y[0];
+        ptr_u = &ctx->edge_buf_uv[0][0];
+        ptr_v = &ctx->edge_buf_uv[1][0];
+    }
 
-    pdsp->get_pixels(ctx->blocks[0], ptr_y,      ctx->m.linesize);
-    pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, ctx->m.linesize);
-    pdsp->get_pixels(ctx->blocks[2], ptr_u,      ctx->m.uvlinesize);
-    pdsp->get_pixels(ctx->blocks[3], ptr_v,      ctx->m.uvlinesize);
+    pdsp->get_pixels(ctx->blocks[0], ptr_y,      linesize);
+    pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize);
+    pdsp->get_pixels(ctx->blocks[2], ptr_u,      uvlinesize);
+    pdsp->get_pixels(ctx->blocks[3], ptr_v,      uvlinesize);
 
-    if (mb_y + 1 == ctx->m.mb_height && (ctx->m.avctx->height % 16) != 0) {
+    if (mb_y + 1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
         if (ctx->interlaced) {
             ctx->get_pixels_8x4_sym(ctx->blocks[4],
-                                    ptr_y + ctx->dct_y_offset,
-                                    ctx->m.linesize);
+                                    ptr_y + dct_y_offset,
+                                    linesize);
             ctx->get_pixels_8x4_sym(ctx->blocks[5],
-                                    ptr_y + ctx->dct_y_offset + bw,
-                                    ctx->m.linesize);
+                                    ptr_y + dct_y_offset + bw,
+                                    linesize);
             ctx->get_pixels_8x4_sym(ctx->blocks[6],
-                                    ptr_u + ctx->dct_uv_offset,
-                                    ctx->m.uvlinesize);
+                                    ptr_u + dct_uv_offset,
+                                    uvlinesize);
             ctx->get_pixels_8x4_sym(ctx->blocks[7],
-                                    ptr_v + ctx->dct_uv_offset,
-                                    ctx->m.uvlinesize);
+                                    ptr_v + dct_uv_offset,
+                                    uvlinesize);
         } else {
             ctx->bdsp.clear_block(ctx->blocks[4]);
             ctx->bdsp.clear_block(ctx->blocks[5]);
@@ -652,13 +692,13 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
         }
     } else {
         pdsp->get_pixels(ctx->blocks[4],
-                         ptr_y + ctx->dct_y_offset, ctx->m.linesize);
+                         ptr_y + dct_y_offset, linesize);
         pdsp->get_pixels(ctx->blocks[5],
-                         ptr_y + ctx->dct_y_offset + bw, ctx->m.linesize);
+                         ptr_y + dct_y_offset + bw, linesize);
         pdsp->get_pixels(ctx->blocks[6],
-                         ptr_u + ctx->dct_uv_offset, ctx->m.uvlinesize);
+                         ptr_u + dct_uv_offset, uvlinesize);
         pdsp->get_pixels(ctx->blocks[7],
-                         ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize);
+                         ptr_v + dct_uv_offset, uvlinesize);
     }
 }
 
@@ -1035,10 +1075,9 @@ static void radix_sort_pass(RCCMPEntry *dst, const RCCMPEntry *data,
     }
 }
 
-static void radix_sort(RCCMPEntry *data, int size)
+static void radix_sort(RCCMPEntry *data, RCCMPEntry *tmp, int size)
 {
     int buckets[RADIX_PASSES][NBUCKETS];
-    RCCMPEntry *tmp = av_malloc_array(size, sizeof(*tmp));
     radix_count(data, size, buckets);
     radix_sort_pass(tmp, data, size, buckets[0], 0);
     radix_sort_pass(data, tmp, size, buckets[1], 1);
@@ -1046,7 +1085,6 @@ static void radix_sort(RCCMPEntry *data, int size)
         radix_sort_pass(tmp, data, size, buckets[2], 2);
         radix_sort_pass(data, tmp, size, buckets[3], 3);
     }
-    av_free(tmp);
 }
 
 static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
@@ -1080,7 +1118,7 @@ static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
         if (RC_VARIANCE)
             avctx->execute2(avctx, dnxhd_mb_var_thread,
                             NULL, NULL, ctx->m.mb_height);
-        radix_sort(ctx->mb_cmp, ctx->m.mb_num);
+        radix_sort(ctx->mb_cmp, ctx->mb_cmp_tmp, ctx->m.mb_num);
         for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
             int mb = ctx->mb_cmp[x].mb;
             int rc = (ctx->qscale * ctx->m.mb_num ) + mb;
@@ -1197,6 +1235,7 @@ static av_cold int dnxhd_encode_end(AVCodecContext *avctx)
     av_freep(&ctx->mb_qscale);
     av_freep(&ctx->mb_rc);
     av_freep(&ctx->mb_cmp);
+    av_freep(&ctx->mb_cmp_tmp);
     av_freep(&ctx->slice_size);
     av_freep(&ctx->slice_offs);