Пример #1
0
        static vpx_image_t vp8_get_frame(vpx_codec_alg_priv_t ctx, vpx_codec_iter_t iter)
        {
            vpx_image_t img = null;

            /* iter acts as a flip flop, so an image is only returned on the first
             * call to get_frame.
             */
            if (iter == IntPtr.Zero && ctx.yv12_frame_buffers.pbi[0] != null)
            {
                YV12_BUFFER_CONFIG sd = new YV12_BUFFER_CONFIG();
                long          time_stamp = 0, time_end_stamp = 0;
                vp8_ppflags_t flags = new vp8_ppflags_t();
                // Port AC: ppflags struct will be initialised to zero by default.
                //vp8_zero(flags);

                //if ([email protected]_flags & VPX_CODEC_USE_POSTPROC) {
                //    flags.post_proc_flag = ctx->postproc_cfg.post_proc_flag;
                //    flags.deblocking_level = ctx->postproc_cfg.deblocking_level;
                //    flags.noise_level = ctx->postproc_cfg.noise_level;
                //}

                if (0 == onyxd.vp8dx_get_raw_frame(ctx.yv12_frame_buffers.pbi[0], ref sd,
                                                   out time_stamp, out time_end_stamp, ref flags))
                {
                    yuvconfig2image(ctx.img, sd, ctx.user_priv);

                    img = ctx.img;
                    //*iter = img;
                }
            }

            return(img);
        }
Пример #2
0
        internal static vpx_codec_err_t vp8_destroy(vpx_codec_alg_priv_t ctx)
        {
            onyxd.vp8_remove_decoder_instances(ctx.yv12_frame_buffers);

            //vpx_free(ctx);

            return(vpx_codec_err_t.VPX_CODEC_OK);
        }
Пример #3
0
        public static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t ctx, vpx_internal_error_info error)
        {
            vpx_codec_err_t res = error.error_code;

            if (res != vpx_codec_err_t.VPX_CODEC_OK)
            {
                [email protected]_detail = error.has_detail > 0 ? error.detail : null;
            }

            return(res);
        }
Пример #4
0
        /// <summary>
        /// Update the input fragment data.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="data"></param>
        /// <param name="data_sz"></param>
        /// <param name="res"></param>
        /// <returns>
        /// <=0: Error.
        /// 1: OK.
        /// </returns>
        public unsafe static int update_fragments(vpx_codec_alg_priv_t ctx, byte *data,
                                                  uint data_sz, out vpx_codec_err_t res)
        {
            res = vpx_codec_err_t.VPX_CODEC_OK;

            if (ctx.fragments.count == 0)
            {
                /* New frame, reset fragment pointers and sizes */
                //memset((void*)ctx.fragments.ptrs, 0, sizeof(ctx.fragments.ptrs));
                //memset(ctx.fragments.sizes, 0, sizeof(ctx.fragments.sizes));
                Array.Clear(ctx.fragments.ptrs, 0, ctx.fragments.ptrs.Length);
                Array.Clear(ctx.fragments.sizes, 0, ctx.fragments.sizes.Length);
            }
            if (ctx.fragments.enabled > 0 && !(data == null && data_sz == 0))
            {
                /* Store a pointer to this fragment and return. We haven't
                 * received the complete frame yet, so we will wait with decoding.
                 */
                ctx.fragments.ptrs[ctx.fragments.count]  = data;
                ctx.fragments.sizes[ctx.fragments.count] = data_sz;
                ctx.fragments.count++;
                if (ctx.fragments.count > (1 << (int)TOKEN_PARTITION.EIGHT_PARTITION) + 1)
                {
                    ctx.fragments.count = 0;
                    res = vpx_codec_err_t.VPX_CODEC_INVALID_PARAM;
                    return(-1);
                }
                return(0);
            }

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

            if (ctx.fragments.enabled == 0)
            {
                ctx.fragments.ptrs[0]  = data;
                ctx.fragments.sizes[0] = data_sz;
                ctx.fragments.count    = 1;
            }

            return(1);
        }
Пример #5
0
        private static int vp8_init_ctx(vpx_codec_ctx_t ctx)
        {
            //vpx_codec_alg_priv_t priv = (vpx_codec_alg_priv_t)vpx_calloc(1, sizeof(*priv));
            //if (!priv) return 1;
            vpx_codec_alg_priv_t priv = new vpx_codec_alg_priv_t();

            //ctx.priv = new vpx_codec_priv_t();
            ctx.priv = new vpx_codec_alg_priv_t();
            //ctx.priv.init_flags = ctx.init_flags;

            //priv.si.sz = sizeof(priv->si);
            //priv.decrypt_cb = null;
            //priv.decrypt_state = IntPtr.Zero;

            //if (ctx.dec_cfg != null)            {
            /* Update the reference to the config structure to an internal copy. */
            //priv.cfg = *ctx->config.dec;
            ctx.dec_cfg = priv.cfg; //&priv->cfg;
            //}

            return(0);
        }
Пример #6
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);
            }
        }