示例#1
0
        public static void vp8_build_intra_predictors_mbuv_s(
            MACROBLOCKD x, byte *uabove_row, byte *vabove_row,
            byte *uleft, byte *vleft, int left_stride,
            byte *upred_ptr, byte *vpred_ptr, int pred_stride)
        {
            MB_PREDICTION_MODE uvmode = (MB_PREDICTION_MODE)x.mode_info_context.get().mbmi.uv_mode;

            byte *uleft_col = stackalloc byte[8];
            byte *vleft_col = stackalloc byte[8];

            int           i;
            intra_pred_fn fn;

            for (i = 0; i < 8; ++i)
            {
                uleft_col[i] = uleft[i * left_stride];
                vleft_col[i] = vleft[i * left_stride];
            }

            if (uvmode == MB_PREDICTION_MODE.DC_PRED)
            {
                fn = dc_pred[x.left_available, x.up_available, (int)PredictionSizes.SIZE_8];
            }
            else
            {
                fn = pred[(int)uvmode, (int)PredictionSizes.SIZE_8];
            }

            fn(upred_ptr, pred_stride, uabove_row, uleft_col);
            fn(vpred_ptr, pred_stride, vabove_row, vleft_col);
        }
示例#2
0
        public static void vp8_build_intra_predictors_mby_s(MACROBLOCKD x, byte *yabove_row,
                                                            byte *yleft, int left_stride,
                                                            byte *ypred_ptr, int y_stride)
        {
            MB_PREDICTION_MODE mode = (MB_PREDICTION_MODE)x.mode_info_context.get().mbmi.mode;
            //DECLARE_ALIGNED(16, uint8_t, yleft_col[16]);
            byte *        yleft_col = stackalloc byte[16];
            int           i;
            intra_pred_fn fn;

            for (i = 0; i < 16; ++i)
            {
                yleft_col[i] = yleft[i * left_stride];
            }

            if (mode == MB_PREDICTION_MODE.DC_PRED)
            {
                fn = dc_pred[x.left_available, x.up_available, (int)PredictionSizes.SIZE_16];
            }
            else
            {
                fn = pred[(int)mode, (int)PredictionSizes.SIZE_16];
            }

            fn(ypred_ptr, y_stride, yabove_row, yleft_col);
        }
示例#3
0
        public static unsafe void DumpSubBlockCoefficients(MACROBLOCKD macroBlock)
        {
            Debug.WriteLine($"MacroBlock subblock qcoeff:");

            for (int i = 0; i < macroBlock.block.Length; i++)
            {
                var    subBlock = macroBlock.block[i];
                string qCoeff   = null;
                for (int j = subBlock.qcoeff.Index; j < subBlock.qcoeff.Index + 16; j++)
                {
                    qCoeff += subBlock.qcoeff.src()[j].ToString() + ",";
                }
                Debug.WriteLine($"block[{i}].qcoeff={qCoeff}");
            }

            Debug.WriteLine("");

            Debug.WriteLine($"MacroBlock subblock dqcoeff:");

            for (int i = 0; i < macroBlock.block.Length; i++)
            {
                var    subBlock = macroBlock.block[i];
                string dqCoeff  = null;
                for (int j = subBlock.dqcoeff.Index; j < subBlock.dqcoeff.Index + 16; j++)
                {
                    dqCoeff += subBlock.dqcoeff.src()[j].ToString() + ",";
                }
                Debug.WriteLine($"block[{i}].dqcoeff={dqCoeff}");
            }

            Debug.WriteLine("");
        }
示例#4
0
        public static void intra_prediction_down_copy(MACROBLOCKD xd, byte *above_right_src)
        {
            int   dst_stride      = xd.dst.y_stride;
            byte *above_right_dst = xd.dst.y_buffer - dst_stride + 16;

            uint *src_ptr  = (uint *)above_right_src;
            uint *dst_ptr0 = (uint *)(above_right_dst + 4 * dst_stride);
            uint *dst_ptr1 = (uint *)(above_right_dst + 8 * dst_stride);
            uint *dst_ptr2 = (uint *)(above_right_dst + 12 * dst_stride);

            *dst_ptr0 = *src_ptr;
            *dst_ptr1 = *src_ptr;
            *dst_ptr2 = *src_ptr;
        }
示例#5
0
        public static unsafe void DumpMacroBlock(MACROBLOCKD macroBlock, int macroBlockIndex)
        {
            Debug.WriteLine($"MacroBlock {macroBlockIndex}:");

            Debug.Write("eobs: ");
            for (int i = 0; i < macroBlock.eobs.Length; i++)
            {
                Debug.Write($"{macroBlock.eobs[i]}, ");
            }
            Debug.WriteLine("");

            Debug.WriteLine($"y: {DebugProbeHexStr.ToHexStr(macroBlock.dst.y_buffer, macroBlock.dst.y_width)}");
            Debug.WriteLine($"u: {DebugProbeHexStr.ToHexStr(macroBlock.dst.u_buffer, macroBlock.dst.uv_width)}");
            Debug.WriteLine($"v: {DebugProbeHexStr.ToHexStr(macroBlock.dst.v_buffer, macroBlock.dst.uv_width)}");
            Debug.WriteLine("");
        }
示例#6
0
        public static void vp8_reset_mb_tokens_context(MACROBLOCKD x)
        {
            //ENTROPY_CONTEXT* a_ctx = ((ENTROPY_CONTEXT*)x->above_context);
            //ENTROPY_CONTEXT* l_ctx = ((ENTROPY_CONTEXT*)x->left_context);

            //memset(a_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
            //memset(l_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);

            x.above_context.get().Clear(false);
            x.left_context.Clear(false);

            /* Clear entropy contexts for Y2 blocks */
            if (x.mode_info_context.get().mbmi.is_4x4 == 0)
            {
                //a_ctx[8] = l_ctx[8] = 0;
                x.above_context.get().y2 = x.left_context.y2 = default;
            }
        }
示例#7
0
        public unsafe static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t ctx,
                                                        byte *data, uint data_sz,
                                                        IntPtr user_priv, long deadline)
        {
            try
            {
                vpx_codec_err_t res = vpx_codec_err_t.VPX_CODEC_OK;
                uint            resolution_change = 0;
                uint            w, h;

                if (ctx.fragments.enabled == 0 && data == null && data_sz == 0)
                {
                    return(0);
                }

                /* Update the input fragment data */
                if (update_fragments(ctx, data, data_sz, out res) <= 0)
                {
                    return(res);
                }

                /* Determine the stream parameters. Note that we rely on peek_si to
                 * validate that we have a buffer that does not wrap around the top
                 * of the heap.
                 */
                w = ctx.si.w;
                h = ctx.si.h;

                //res = vp8_peek_si_internal(ctx.fragments.ptrs[0], ctx.fragments.sizes[0],
                //                           ctx.si, ctx.decrypt_cb, ctx.decrypt_state);

                res = vp8_peek_si_internal(ctx.fragments.ptrs[0], ctx.fragments.sizes[0],
                                           ref ctx.si, null, IntPtr.Zero);

                if (res == vpx_codec_err_t.VPX_CODEC_UNSUP_BITSTREAM && ctx.si.is_kf == 0)
                {
                    /* the peek function returns an error for non keyframes, however for
                     * this case, it is not an error */
                    res = vpx_codec_err_t.VPX_CODEC_OK;
                }

                if (ctx.decoder_init == 0 && ctx.si.is_kf == 0)
                {
                    res = vpx_codec_err_t.VPX_CODEC_UNSUP_BITSTREAM;
                }

                if ((ctx.si.h != h) || (ctx.si.w != w))
                {
                    resolution_change = 1;
                }

                /* Initialize the decoder instance on the first frame*/
                if (res == vpx_codec_err_t.VPX_CODEC_OK && ctx.decoder_init == 0)
                {
                    VP8D_CONFIG oxcf = new VP8D_CONFIG();

                    oxcf.Width             = (int)ctx.si.w;
                    oxcf.Height            = (int)ctx.si.h;
                    oxcf.Version           = 9;
                    oxcf.postprocess       = 0;
                    oxcf.max_threads       = (int)ctx.cfg.threads;
                    oxcf.error_concealment = (int)([email protected]_flags & vpx_decoder.VPX_CODEC_USE_ERROR_CONCEALMENT);

                    res = onyxd.vp8_create_decoder_instances(ctx.yv12_frame_buffers, oxcf);
                    if (res == vpx_codec_err_t.VPX_CODEC_OK)
                    {
                        ctx.decoder_init = 1;
                    }
                }

                if (res == vpx_codec_err_t.VPX_CODEC_OK)
                {
                    VP8D_COMP  pbi = ctx.yv12_frame_buffers.pbi[0];
                    VP8_COMMON pc  = pbi.common;
                    if (resolution_change > 0)
                    {
                        MACROBLOCKD xd = pbi.mb;

                        pc.Width  = (int)ctx.si.w;
                        pc.Height = (int)ctx.si.h;
                        {
                            int prev_mb_rows = pc.mb_rows;

                            // Port AC: TODO identify alternative error mechanism.
                            //if (setjmp(pbi.common.error.jmp))
                            //{
                            //    pbi.common.error.setjmp = 0;
                            //    /* on failure clear the cached resolution to ensure a full
                            //     * reallocation is attempted on resync. */
                            //    ctx.si.w = 0;
                            //    ctx.si.h = 0;
                            //    vpx_clear_system_state();
                            //    /* same return value as used in vp8dx_receive_compressed_data */
                            //    return -1;
                            //}

                            //pbi.common.error.setjmp = 1;

                            if (pc.Width <= 0)
                            {
                                pc.Width = (int)w;
                                vpx_codec.vpx_internal_error(ref pc.error, vpx_codec_err_t.VPX_CODEC_CORRUPT_FRAME,
                                                             "Invalid frame width");
                            }

                            if (pc.Height <= 0)
                            {
                                pc.Height = (int)h;
                                vpx_codec.vpx_internal_error(ref pc.error, vpx_codec_err_t.VPX_CODEC_CORRUPT_FRAME,
                                                             "Invalid frame height");
                            }

                            if (alloccommon.vp8_alloc_frame_buffers(pc, pc.Width, pc.Height) != 0)
                            {
                                vpx_codec.vpx_internal_error(ref pc.error, vpx_codec_err_t.VPX_CODEC_MEM_ERROR,
                                                             "Failed to allocate frame buffers");
                            }

                            xd.pre = pc.yv12_fb[pc.lst_fb_idx];
                            xd.dst = pc.yv12_fb[pc.new_fb_idx];

                            mbpitch.vp8_build_block_doffsets(pbi.mb);

                            // Port AC: Assume this cast was a noop to remove compiler warning.
                            //(void)prev_mb_rows;
                        }

                        // Port AC: TODO identify alternative error mechanism.
                        //pbi.common.error.setjmp = 0;

                        /* required to get past the first get_free_fb() call */
                        pbi.common.fb_idx_ref_cnt[0] = 0;
                    }

                    // Port AC: TODO identify alternative error mechanism.
                    //if (setjmp(pbi.common.error.jmp))
                    //{
                    //    vpx_clear_system_state();
                    //    /* We do not know if the missing frame(s) was supposed to update
                    //     * any of the reference buffers, but we act conservative and
                    //     * mark only the last buffer as corrupted.
                    //     */
                    //    pc.yv12_fb[pc.lst_fb_idx].corrupted = 1;

                    //    if (pc.fb_idx_ref_cnt[pc.new_fb_idx] > 0)
                    //    {
                    //        pc.fb_idx_ref_cnt[pc.new_fb_idx]--;
                    //    }
                    //    pc.error.setjmp = 0;

                    //    res = update_error_state(ctx, pbi.common.error);
                    //    return res;
                    //}

                    //pbi.common.error.setjmp = 1;

                    /* update the pbi fragment data */
                    pbi.fragments = ctx.fragments;

                    ctx.user_priv = user_priv;
                    if (onyxd.vp8dx_receive_compressed_data(pbi, deadline) != 0)
                    {
                        res = update_error_state(ctx, pbi.common.error);
                    }

                    /* get ready for the next series of fragments */
                    ctx.fragments.count = 0;
                }

                return(res);
            }
            catch (VpxException vpxExcp)
            {
                return(vpxExcp.ErrorCode);
            }
        }
示例#8
0
        public static int vp8_decode_mb_tokens(VP8D_COMP dx, MACROBLOCKD x)
        {
            BOOL_DECODER  bc = x.current_bc;
            FRAME_CONTEXT fc = dx.common.fc;

            //char* eobs = x->eobs;
            sbyte[] eobs = x.eobs;

            int i;
            int nonzeros;
            int eobtotal = 0;

            //short* qcoeff_ptr;
            //ProbaArray coef_probs;
            //int coefIndex = entropy.COEF_BANDS * entropy.PREV_COEF_CONTEXTS * entropy.ENTROPY_NODES;
            //ENTROPY_CONTEXT* a_ctx = ((ENTROPY_CONTEXT*)x->above_context);
            //ENTROPY_CONTEXT* l_ctx = ((ENTROPY_CONTEXT*)x->left_context);
            //ENTROPY_CONTEXT* a;
            //ENTROPY_CONTEXT* l;

            int blockSlice = entropy.COEF_BANDS * entropy.PREV_COEF_CONTEXTS * entropy.ENTROPY_NODES;

            fixed(byte *pCoefProbs = fc.coef_probs)
            {
                byte *coef_probs = null;

                fixed(sbyte *pAboveCtx = x.above_context.get().y1, pLeftContext = x.left_context.y1)
                {
                    ENTROPY_CONTEXT *a_ctx = pAboveCtx;
                    ENTROPY_CONTEXT *l_ctx = pLeftContext;
                    ENTROPY_CONTEXT *a;
                    ENTROPY_CONTEXT *l;

                    int skip_dc = 0;

                    //qcoeff_ptr = x.qcoeff[0];
                    fixed(short *pQcoeff = x.qcoeff)
                    {
                        short *qcoeff_ptr = pQcoeff;

                        if (x.mode_info_context.get().mbmi.is_4x4 == 0)
                        {
                            a = a_ctx + 8;
                            l = l_ctx + 8;

                            //coef_probs = fc.coef_probs[1];
                            coef_probs = pCoefProbs + blockSlice;

                            nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr + 24 * 16);
                            *a = *l = (sbyte)(nonzeros > 0 ? 1 : 0);

                            eobs[24]  = (sbyte)nonzeros;
                            eobtotal += nonzeros - 16;

                            //coef_probs = fc.coef_probs[0];
                            coef_probs = pCoefProbs;

                            skip_dc = 1;
                        }
                        else
                        {
                            //coef_probs = fc.coef_probs[3];
                            coef_probs = pCoefProbs + 3 * blockSlice;

                            skip_dc = 0;
                        }

                        for (i = 0; i < 16; ++i)
                        {
                            a = a_ctx + (i & 3);
                            l = l_ctx + ((i & 0xc) >> 2);

                            nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), skip_dc, qcoeff_ptr);
                            *a = *l = (sbyte)(nonzeros > 0 ? 1 : 0);

                            nonzeros   += skip_dc;
                            eobs[i]     = (sbyte)nonzeros;
                            eobtotal   += nonzeros;
                            qcoeff_ptr += 16;
                        }

                        //coef_probs = fc.coef_probs[2];
                        coef_probs = pCoefProbs + 2 * blockSlice;

                        a_ctx += 4;
                        l_ctx += 4;
                        for (i = 16; i < 24; ++i)
                        {
                            a = a_ctx + ((i > 19 ? 1 : 0) << 1) + (i & 1);
                            l = l_ctx + ((i > 19 ? 1 : 0) << 1) + ((i & 3) > 1 ? 1 : 0);

                            nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr);
                            *a = *l = (sbyte)(nonzeros > 0 ? 1 : 0);

                            eobs[i]     = (sbyte)nonzeros;
                            eobtotal   += nonzeros;
                            qcoeff_ptr += 16;
                        }
                    }
                }
            }

            return(eobtotal);
        }