diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 375dc52..4a27841 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -40,6 +40,7 @@ enum {
     PRORES_PROFILE_LT,
     PRORES_PROFILE_STANDARD,
     PRORES_PROFILE_HQ,
+    PRORES_PROFILE_4444,
 };
 
 #define NUM_MB_LIMITS 4
@@ -57,7 +58,7 @@ static const struct prores_profile {
     int         max_quant;
     int         br_tab[NUM_MB_LIMITS];
     uint8_t     quant[64];
-} prores_profile_info[4] = {
+} prores_profile_info[5] = {
     {
         .full_name = "proxy",
         .tag       = MKTAG('a', 'p', 'c', 'o'),
@@ -125,8 +126,24 @@ static const struct prores_profile {
              4,  4,  4,  4,  5,  5,  6,  7,
              4,  4,  4,  4,  5,  6,  7,  7,
         },
+    },
+    {
+        .full_name = "4444",
+        .tag       = MKTAG('a', 'p', '4', 'h'),
+        .min_quant = 1, // TODO
+        .max_quant = 6, // TODO
+        .br_tab    = { 2350, 1828, 1600, 1425 },
+        .quant     = {
+             4,  4,  4,  4,  4,  4,  4,  4,
+             4,  4,  4,  4,  4,  4,  4,  4,
+             4,  4,  4,  4,  4,  4,  4,  4,
+             4,  4,  4,  4,  4,  4,  4,  4,
+             4,  4,  4,  4,  4,  4,  4,  4,
+             4,  4,  4,  4,  4,  4,  4,  4,
+             4,  4,  4,  4,  4,  4,  4,  4,
+             4,  4,  4,  4,  4,  4,  4,  4,
+        },
     }
-// for 4444 profile bitrate numbers are { 2350, 1828, 1600, 1425 }
 };
 
 #define TRELLIS_WIDTH 16
@@ -171,7 +188,7 @@ typedef struct ProresContext {
 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
                            int linesize, int x, int y, int w, int h,
                            DCTELEM *blocks,
-                           int mbs_per_slice, int blocks_per_mb)
+                           int mbs_per_slice, int blocks_per_mb, int is_chroma)
 {
     const uint16_t *esrc;
     const int mb_width = 4 * blocks_per_mb;
@@ -189,38 +206,50 @@ static void get_slice_data(ProresContext *ctx, const uint16_t *src,
             elinesize = linesize;
         } else {
             int bw, bh, pix;
-            const int estride = 16 / sizeof(*ctx->emu_buf);
 
             esrc      = ctx->emu_buf;
-            elinesize = 16;
+            elinesize = 16 * sizeof(*ctx->emu_buf);
 
             bw = FFMIN(w - x, mb_width);
             bh = FFMIN(h - y, 16);
 
             for (j = 0; j < bh; j++) {
-                memcpy(ctx->emu_buf + j * estride, src + j * linesize,
+                memcpy(ctx->emu_buf + j * 16,
+		       (const uint8_t *)src + j * linesize,
                        bw * sizeof(*src));
-                pix = ctx->emu_buf[j * estride + bw - 1];
+                pix = ctx->emu_buf[j * 16 + bw - 1];
                 for (k = bw; k < mb_width; k++)
-                    ctx->emu_buf[j * estride + k] = pix;
+                    ctx->emu_buf[j * 16 + k] = pix;
             }
             for (; j < 16; j++)
-                memcpy(ctx->emu_buf + j * estride,
-                       ctx->emu_buf + (bh - 1) * estride,
+                memcpy(ctx->emu_buf + j * 16,
+                       ctx->emu_buf + (bh - 1) * 16,
                        mb_width * sizeof(*ctx->emu_buf));
         }
-        ctx->dsp.fdct(esrc, elinesize, blocks);
-        blocks += 64;
-        if (blocks_per_mb > 2) {
-            ctx->dsp.fdct(src + 8, linesize, blocks);
-            blocks += 64;
-        }
-        ctx->dsp.fdct(src + linesize * 4, linesize, blocks);
-        blocks += 64;
-        if (blocks_per_mb > 2) {
-            ctx->dsp.fdct(src + linesize * 4 + 8, linesize, blocks);
-            blocks += 64;
-        }
+	if(!is_chroma) { /* luma */
+	    ctx->dsp.fdct(esrc, elinesize, blocks);
+	    blocks += 64;
+	    ctx->dsp.fdct(esrc + 8, elinesize, blocks);
+	    blocks += 64;
+	    ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
+	    blocks += 64;
+	    ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
+	    blocks += 64;
+	} else if(blocks_per_mb == 2) { /* 4:2:2 chroma */
+	    ctx->dsp.fdct(esrc, elinesize, blocks);
+	    blocks += 64;
+	    ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
+	    blocks += 64;
+	} else { /* 4:4:4 chroma */
+	    ctx->dsp.fdct(esrc, elinesize, blocks);
+	    blocks += 64;
+	    ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
+	    blocks += 64;
+	    ctx->dsp.fdct(esrc + 8, elinesize, blocks);
+	    blocks += 64;
+	    ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
+	    blocks += 64;
+	}
 
         x += mb_width;
     }
@@ -366,14 +395,13 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
     for (i = 0; i < ctx->num_planes; i++) {
         is_chroma    = (i == 1 || i == 2);
         plane_factor = slice_width_factor + 2;
-        if (is_chroma)
-            plane_factor += ctx->chroma_factor - 3;
         if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
             xp          = x << 4;
             yp          = y << 4;
             num_cblocks = 4;
             pwidth      = avctx->width;
         } else {
+	    plane_factor += ctx->chroma_factor - 3;
             xp          = x << 3;
             yp          = y << 4;
             num_cblocks = 2;
@@ -383,7 +411,7 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
 
         get_slice_data(ctx, src, pic->linesize[i], xp, yp,
                        pwidth, avctx->height, ctx->blocks[0],
-                       mbs_per_slice, num_cblocks);
+                       mbs_per_slice, num_cblocks, is_chroma);
         sizes[i] = encode_slice_plane(ctx, pb, src, pic->linesize[i],
                                       mbs_per_slice, ctx->blocks[0],
                                       num_cblocks, plane_factor,
@@ -522,14 +550,13 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
     for (i = 0; i < ctx->num_planes; i++) {
         is_chroma[i]    = (i == 1 || i == 2);
         plane_factor[i] = slice_width_factor + 2;
-        if (is_chroma[i])
-            plane_factor[i] += ctx->chroma_factor - 3;
         if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
             xp             = x << 4;
             yp             = y << 4;
             num_cblocks[i] = 4;
             pwidth         = avctx->width;
         } else {
+	    plane_factor[i] += ctx->chroma_factor - 3;
             xp             = x << 3;
             yp             = y << 4;
             num_cblocks[i] = 2;
@@ -539,7 +566,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
 
         get_slice_data(ctx, src, pic->linesize[i], xp, yp,
                        pwidth, avctx->height, ctx->blocks[i],
-                       mbs_per_slice, num_cblocks[i]);
+                       mbs_per_slice, num_cblocks[i], is_chroma[i]);
     }
 
     for (q = min_quant; q < max_quant + 2; q++) {
@@ -676,9 +703,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     bytestream_put_be16  (&buf, avctx->height);
     bytestream_put_byte  (&buf, ctx->chroma_factor << 6); // frame flags
     bytestream_put_byte  (&buf, 0);             // reserved
-    bytestream_put_byte  (&buf, 0);             // primaries
-    bytestream_put_byte  (&buf, 0);             // transfer function
-    bytestream_put_byte  (&buf, 6);             // colour matrix - ITU-R BT.601-4
+    bytestream_put_byte  (&buf, avctx->color_primaries);
+    bytestream_put_byte  (&buf, avctx->color_trc);
+    bytestream_put_byte  (&buf, avctx->colorspace);
     bytestream_put_byte  (&buf, 0x40);          // source format and alpha information
     bytestream_put_byte  (&buf, 0);             // reserved
     bytestream_put_byte  (&buf, 0x03);          // matrix flags - both matrices are present
@@ -855,7 +882,7 @@ static const AVOption options[] = {
         AV_OPT_TYPE_INT, { 8 }, 1, MAX_MBS_PER_SLICE, VE },
     { "profile",       NULL, OFFSET(profile), AV_OPT_TYPE_INT,
         { PRORES_PROFILE_STANDARD },
-        PRORES_PROFILE_PROXY, PRORES_PROFILE_HQ, VE, "profile" },
+        PRORES_PROFILE_PROXY, PRORES_PROFILE_4444, VE, "profile" },
     { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_PROXY },
         0, 0, VE, "profile" },
     { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_LT },
@@ -864,6 +891,8 @@ static const AVOption options[] = {
         0, 0, VE, "profile" },
     { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_HQ },
         0, 0, VE, "profile" },
+    { "4444",          NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_4444 },
+        0, 0, VE, "profile" },
     { NULL }
 };
 
