示例#1
0
        public static void vp8_init_mbmode_probs(VP8_COMMON x)
        {
            //memcpy(x.fc.ymode_prob, vp8_entropymodeldata.vp8_ymode_prob, sizeof(vp8_ymode_prob));
            //memcpy(x.fc.uv_mode_prob, vp8_entropymodeldata.vp8_uv_mode_prob, sizeof(vp8_uv_mode_prob));
            //memcpy(x.fc.sub_mv_ref_prob, sub_mv_ref_prob, sizeof(sub_mv_ref_prob));

            Array.Copy(vp8_entropymodedata.vp8_ymode_prob, x.fc.ymode_prob, vp8_entropymodedata.vp8_ymode_prob.Length);
            Array.Copy(vp8_entropymodedata.vp8_uv_mode_prob, x.fc.uv_mode_prob, vp8_entropymodedata.vp8_uv_mode_prob.Length);
            Array.Copy(sub_mv_ref_prob, x.fc.sub_mv_ref_prob, x.fc.sub_mv_ref_prob.Length);
        }
示例#2
0
        private static int get_free_fb(VP8_COMMON cm)
        {
            int i;

            for (i = 0; i < VP8_COMMON.NUM_YV12_BUFFERS; ++i)
            {
                if (cm.fb_idx_ref_cnt[i] == 0)
                {
                    break;
                }
            }

            //assert(i < NUM_YV12_BUFFERS);
            cm.fb_idx_ref_cnt[i] = 1;
            return(i);
        }
示例#3
0
        public static void vp8_de_alloc_frame_buffers(VP8_COMMON oci)
        {
            int i;

            for (i = 0; i < VP8_COMMON.NUM_YV12_BUFFERS; ++i)
            {
                yv12config.vp8_yv12_de_alloc_frame_buffer(ref oci.yv12_fb[i]);
            }

            yv12config.vp8_yv12_de_alloc_frame_buffer(ref oci.temp_scale_frame);

            //vpx_mem.vpx_free(oci.above_context);
            //vpx_mem.vpx_free(oci.mip);

            oci.above_context = null;
            oci.mip           = null;
        }
示例#4
0
        public static void vp8_setup_version(VP8_COMMON cm)
        {
            switch (cm.version)
            {
            case 0:
                cm.no_lpf                 = 0;
                cm.filter_type            = LOOPFILTERTYPE.NORMAL_LOOPFILTER;
                cm.use_bilinear_mc_filter = 0;
                cm.full_pixel             = 0;
                break;

            case 1:
                cm.no_lpf                 = 0;
                cm.filter_type            = LOOPFILTERTYPE.SIMPLE_LOOPFILTER;
                cm.use_bilinear_mc_filter = 1;
                cm.full_pixel             = 0;
                break;

            case 2:
                cm.no_lpf                 = 1;
                cm.filter_type            = LOOPFILTERTYPE.NORMAL_LOOPFILTER;
                cm.use_bilinear_mc_filter = 1;
                cm.full_pixel             = 0;
                break;

            case 3:
                cm.no_lpf                 = 1;
                cm.filter_type            = LOOPFILTERTYPE.SIMPLE_LOOPFILTER;
                cm.use_bilinear_mc_filter = 1;
                cm.full_pixel             = 1;
                break;

            default:
                /*4,5,6,7 are reserved for future use*/
                cm.no_lpf                 = 0;
                cm.filter_type            = LOOPFILTERTYPE.NORMAL_LOOPFILTER;
                cm.use_bilinear_mc_filter = 0;
                cm.full_pixel             = 0;
                break;
            }
        }
示例#5
0
        public static void vp8_create_common(VP8_COMMON oci)
        {
            systemdependent.vp8_machine_specific_config(oci);

            entropymode.vp8_init_mbmode_probs(oci);
            entropymode.vp8_default_bmode_probs(oci.fc.bmode_prob);

            oci.mb_no_coeff_skip       = 1;
            oci.no_lpf                 = 0;
            oci.filter_type            = LOOPFILTERTYPE.NORMAL_LOOPFILTER;
            oci.use_bilinear_mc_filter = 0;
            oci.full_pixel             = 0;
            oci.multi_token_partition  = TOKEN_PARTITION.ONE_PARTITION;
            oci.clamp_type             = CLAMP_TYPE.RECON_CLAMP_REQUIRED;

            /* Initialize reference frame sign bias structure to defaults */
            //memset(oci.ref_frame_sign_bias, 0, sizeof(oci->ref_frame_sign_bias));

            /* Default disable buffer to buffer copying */
            oci.copy_buffer_to_gf  = 0;
            oci.copy_buffer_to_arf = 0;
        }
示例#6
0
        public static int check_fragments_for_errors(VP8D_COMP pbi)
        {
            if (pbi.ec_active == 0 && pbi.fragments.count <= 1 &&
                pbi.fragments.sizes[0] == 0)
            {
                VP8_COMMON cm = pbi.common;

                /* If error concealment is disabled we won't signal missing frames
                 * to the decoder.
                 */
                if (cm.fb_idx_ref_cnt[cm.lst_fb_idx] > 1)
                {
                    /* The last reference shares buffer with another reference
                     * buffer. Move it to its own buffer before setting it as
                     * corrupt, otherwise we will make multiple buffers corrupt.
                     */
                    int prev_idx = cm.lst_fb_idx;
                    cm.fb_idx_ref_cnt[prev_idx]--;
                    cm.lst_fb_idx = get_free_fb(cm);
                    yv12extend.vp8_yv12_copy_frame(cm.yv12_fb[prev_idx], cm.yv12_fb[cm.lst_fb_idx]);
                }

                /* This is used to signal that we are missing frames.
                 * 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.
                 */
                cm.yv12_fb[cm.lst_fb_idx].corrupted = 1;

                /* Signal that we have no frame to show. */
                cm.show_frame = 0;

                /* Nothing more to do. */
                return(0);
            }

            return(1);
        }
示例#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
        /* If any buffer copy / swapping is signalled it should be done here. */
        public static int swap_frame_buffers(VP8_COMMON cm)
        {
            int err = 0;

            /* The alternate reference frame or golden frame can be updated
             *  using the new, last, or golden/alt ref frame.  If it
             *  is updated using the newly decoded frame it is a refresh.
             *  An update using the last or golden/alt ref frame is a copy.
             */
            if (cm.copy_buffer_to_arf > 0)
            {
                int new_fb = 0;

                if (cm.copy_buffer_to_arf == 1)
                {
                    new_fb = cm.lst_fb_idx;
                }
                else if (cm.copy_buffer_to_arf == 2)
                {
                    new_fb = cm.gld_fb_idx;
                }
                else
                {
                    err = -1;
                }

                ref_cnt_fb(cm.fb_idx_ref_cnt, ref cm.alt_fb_idx, new_fb);
            }

            if (cm.copy_buffer_to_gf > 0)
            {
                int new_fb = 0;

                if (cm.copy_buffer_to_gf == 1)
                {
                    new_fb = cm.lst_fb_idx;
                }
                else if (cm.copy_buffer_to_gf == 2)
                {
                    new_fb = cm.alt_fb_idx;
                }
                else
                {
                    err = -1;
                }

                ref_cnt_fb(cm.fb_idx_ref_cnt, ref cm.gld_fb_idx, new_fb);
            }

            if (cm.refresh_golden_frame > 0)
            {
                ref_cnt_fb(cm.fb_idx_ref_cnt, ref cm.gld_fb_idx, cm.new_fb_idx);
            }

            if (cm.refresh_alt_ref_frame > 0)
            {
                ref_cnt_fb(cm.fb_idx_ref_cnt, ref cm.alt_fb_idx, cm.new_fb_idx);
            }

            if (cm.refresh_last_frame > 0)
            {
                ref_cnt_fb(cm.fb_idx_ref_cnt, ref cm.lst_fb_idx, cm.new_fb_idx);

                cm.frame_to_show = cm.yv12_fb[cm.lst_fb_idx];
            }
            else
            {
                cm.frame_to_show = cm.yv12_fb[cm.new_fb_idx];
            }

            cm.fb_idx_ref_cnt[cm.new_fb_idx]--;

            return(err);
        }
示例#9
0
        public static int vp8dx_receive_compressed_data(VP8D_COMP pbi, Int64 time_stamp)
        {
            VP8_COMMON cm      = pbi.common;
            int        retcode = -1;

            pbi.common.error.error_code = vpx_codec_err_t.VPX_CODEC_OK;

            retcode = check_fragments_for_errors(pbi);
            if (retcode <= 0)
            {
                return(retcode);
            }

            cm.new_fb_idx = get_free_fb(cm);

            /* setup reference frames for vp8_decode_frame */
            pbi.dec_fb_ref[(int)MV_REFERENCE_FRAME.INTRA_FRAME]  = cm.yv12_fb[cm.new_fb_idx];
            pbi.dec_fb_ref[(int)MV_REFERENCE_FRAME.LAST_FRAME]   = cm.yv12_fb[cm.lst_fb_idx];
            pbi.dec_fb_ref[(int)MV_REFERENCE_FRAME.GOLDEN_FRAME] = cm.yv12_fb[cm.gld_fb_idx];
            pbi.dec_fb_ref[(int)MV_REFERENCE_FRAME.ALTREF_FRAME] = cm.yv12_fb[cm.alt_fb_idx];

            retcode = decodeframe.vp8_decode_frame(pbi);

            if (retcode < 0)
            {
                if (cm.fb_idx_ref_cnt[cm.new_fb_idx] > 0)
                {
                    cm.fb_idx_ref_cnt[cm.new_fb_idx]--;
                }

                pbi.common.error.error_code = vpx_codec_err_t.VPX_CODEC_ERROR;
                // Propagate the error info.
                if (pbi.mb.error_info.error_code != vpx_codec_err_t.VPX_CODEC_ERROR)
                {
                    pbi.common.error.error_code = pbi.mb.error_info.error_code;
                    //memcpy(pbi.common.error.detail, pbi.mb.error_info.detail,
                    //       sizeof(pbi.mb.error_info.detail));
                    pbi.common.error.detail = pbi.mb.error_info.detail;
                }
                goto decode_exit;
            }

            if (swap_frame_buffers(cm) != 0)
            {
                pbi.common.error.error_code = vpx_codec_err_t.VPX_CODEC_ERROR;
                goto decode_exit;
            }

            //vpx_clear_system_state();

            if (cm.show_frame > 0)
            {
                cm.current_video_frame++;
                cm.show_frame_mi = cm.mi;
            }

            pbi.ready_for_new_data = 0;
            pbi.last_time_stamp    = time_stamp;

decode_exit:
            //vpx_clear_system_state();
            return(retcode);
        }
示例#10
0
        public unsafe static int vp8_alloc_frame_buffers(VP8_COMMON oci, int width, int height)
        {
            int i;

            vp8_de_alloc_frame_buffers(oci);

            /* our internal buffers are always multiples of 16 */
            if ((width & 0xf) != 0)
            {
                width += 16 - (width & 0xf);
            }

            if ((height & 0xf) != 0)
            {
                height += 16 - (height & 0xf);
            }

            for (i = 0; i < VP8_COMMON.NUM_YV12_BUFFERS; ++i)
            {
                oci.fb_idx_ref_cnt[i] = 0;
                oci.yv12_fb[i].flags  = 0;
                if (yv12config.vp8_yv12_alloc_frame_buffer(ref oci.yv12_fb[i], width, height,
                                                           yv12config.VP8BORDERINPIXELS) < 0)
                {
                    goto allocation_fail;
                }
            }

            oci.new_fb_idx = 0;
            oci.lst_fb_idx = 1;
            oci.gld_fb_idx = 2;
            oci.alt_fb_idx = 3;

            oci.fb_idx_ref_cnt[0] = 1;
            oci.fb_idx_ref_cnt[1] = 1;
            oci.fb_idx_ref_cnt[2] = 1;
            oci.fb_idx_ref_cnt[3] = 1;

            if (yv12config.vp8_yv12_alloc_frame_buffer(ref oci.temp_scale_frame, width, 16,
                                                       yv12config.VP8BORDERINPIXELS) < 0)
            {
                goto allocation_fail;
            }

            oci.mb_rows          = height >> 4;
            oci.mb_cols          = width >> 4;
            oci.MBs              = oci.mb_rows * oci.mb_cols;
            oci.mode_info_stride = oci.mb_cols + 1;
            //oci.mip = vpx_calloc((oci.mb_cols + 1) * (oci.mb_rows + 1), sizeof(MODE_INFO));
            oci.mip = new MODE_INFO[(oci.mb_cols + 1) * (oci.mb_rows + 1)];
            // Port AC: NASTY, highly inefficient. Need to find a better way but running into problems
            // with C# only supporting fixed arrays of primitive types. Would need to re-design the
            // MODE_INFO.b_mode_info etc. C data structure which would then deviate significantly from
            // C code and make future maintenance difficult.
            for (int ii = 0; ii < oci.mip.Length; ii++)
            {
                oci.mip[ii] = new MODE_INFO();
            }

            //if (!oci->mip) goto allocation_fail;

            //oci.mi = oci.mip + oci.mode_info_stride + 1;
            //oci.mi = oci.mip[oci.mode_info_stride + 1];
            oci.mi = new ArrPtr <MODE_INFO>(oci.mip, oci.mode_info_stride + 1);

            /* Allocation of previous mode info will be done in vp8_decode_frame()
             * as it is a decoder only data */

            //oci->above_context =
            //vpx_calloc(sizeof(ENTROPY_CONTEXT_PLANES) * oci->mb_cols, 1);

            oci.above_context = new ENTROPY_CONTEXT_PLANES[oci.mb_cols];

            //if (!oci.above_context) goto allocation_fail;

            return(0);

allocation_fail:
            vp8_de_alloc_frame_buffers(oci);
            return(1);
        }
示例#11
0
 public static void vp8_remove_common(VP8_COMMON oci)
 {
     vp8_de_alloc_frame_buffers(oci);
 }
示例#12
0
 public static void vp8_default_coef_probs(VP8_COMMON pc)
 {
     //memcpy(pc->fc.coef_probs, default_coef_probs, sizeof(default_coef_probs));
     Array.Copy(default_coef_probs_c.default_coef_probs, pc.fc.coef_probs, default_coef_probs_c.default_coef_probs.Length);
 }