Example #1
0
 /// <summary>
 /// Convenience macro for vpx_codec_dec_init_ver()
 ///
 /// Ensures the ABI version parameter is properly set.
 /// </summary>
 public static vpx_codec_err_t vpx_codec_dec_init(vpx_codec_ctx_t ctx,
                                                  vpx_codec_iface_t iface,
                                                  vpx_codec_dec_cfg_t cfg,
                                                  vpx_codec_flags_t flags)
 {
     return(vpx_codec_dec_init_ver(ctx, iface, cfg, flags));
 }
Example #2
0
        /// <summary>
        /// Initialize a decoder instance.
        ///
        /// Initializes a decoder context using the given interface. Applications
        /// should call the vpx_codec_dec_init convenience macro instead of this
        /// function directly, to ensure that the ABI version number parameter
        /// is properly initialized.
        ///
        /// If the library was configured with --disable-multithread, this call
        /// is not thread safe and should be guarded with a lock if being used
        /// in a multithreaded context.
        /// </summary>
        /// <param name="ctx">Pointer to this instance's context.</param>
        /// <param name="iface">Pointer to the algorithm interface to use.</param>
        /// <param name="cfg">Configuration to use, if known. May be NULL.</param>
        /// <param name="flags">Bitfield of VPX_CODEC_USE_* flags.</param>
        /// <param name="ver">ABI version number. Must be set to VPX_DECODER_ABI_VERSION.</param>
        /// <returns>
        /// VPX_CODEC_OK The decoder algorithm initialized.
        /// VPX_CODEC_MEM_ERROR Memory allocation failed.
        /// </returns>
        public static vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t ctx,
                                                             vpx_codec_iface_t iface,
                                                             vpx_codec_dec_cfg_t cfg,
                                                             vpx_codec_flags_t flags,
                                                             int ver = VPX_DECODER_ABI_VERSION)
        {
            vpx_codec_err_t res;

            if (ver != VPX_DECODER_ABI_VERSION)
            {
                res = vpx_codec_err_t.VPX_CODEC_ABI_MISMATCH;
            }
            else if (ctx == null || iface == null)
            {
                res = vpx_codec_err_t.VPX_CODEC_INVALID_PARAM;
            }
            else if (iface.abi_version != vpx_codec_internal.VPX_CODEC_INTERNAL_ABI_VERSION)
            {
                res = vpx_codec_err_t.VPX_CODEC_ABI_MISMATCH;
            }
            else if (((flags & VPX_CODEC_USE_POSTPROC) > 0) &&
                     ((iface.caps & VPX_CODEC_CAP_POSTPROC) == 0))
            {
                res = vpx_codec_err_t.VPX_CODEC_INCAPABLE;
            }
            else if (((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) > 0) &&
                     ((iface.caps & VPX_CODEC_CAP_ERROR_CONCEALMENT) == 0))
            {
                res = vpx_codec_err_t.VPX_CODEC_INCAPABLE;
            }
            else if (((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) > 0) &&
                     ((iface.caps & VPX_CODEC_CAP_INPUT_FRAGMENTS) == 0))
            {
                res = vpx_codec_err_t.VPX_CODEC_INCAPABLE;
            }
            else if ((iface.caps & vpx_codec.VPX_CODEC_CAP_DECODER) == 0)
            {
                res = vpx_codec_err_t.VPX_CODEC_INCAPABLE;
            }
            else
            {
                //memset(ctx, 0, sizeof(*ctx));
                ctx.iface      = iface;
                ctx.name       = iface.name;
                ctx.priv       = null;
                ctx.init_flags = flags;
                //ctx.config.dec = cfg;
                ctx.dec_cfg = cfg;

                res = ctx.iface.init(ctx, null);
                if (res != vpx_codec_err_t.VPX_CODEC_OK)
                {
                    //ctx.err_detail = ctx.priv != null ? ctx.priv.err_detail : null;
                    vpx_codec.vpx_codec_destroy(ctx);
                }
            }

            //return SAVE_STATUS(ctx, res);
            return(ctx != null ? (ctx.err = res) : res);
        }
Example #3
0
        public unsafe static vpx_codec_iface_t vpx_codec_vp8_dx()
        {
            if (_singleton == null)
            {
                _singleton = new vpx_codec_iface_t
                {
                    name        = $"{VERSION_STRING_PREFIX}{vpx_version.VERSION_STRING}",
                    abi_version = vpx_codec_internal.VPX_CODEC_INTERNAL_ABI_VERSION,
                    caps        = vpx_codec.VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT |
                                  vpx_decoder.VPX_CODEC_CAP_INPUT_FRAGMENTS,
                    init      = vp8_init,
                    destroy   = vp8_destroy,
                    ctrl_maps = vp8_ctf_maps,
                    dec       = new vpx_codec_dec_iface_t
                    {
                        peek_si = vp8_peek_si,
                        //get_si = vp8_get_si,
                        decode    = vp8_decode,
                        get_frame = vp8_get_frame,
                        set_fb_fn = null
                    },
                    enc = new vpx_codec_enc_iface_t
                    {
                        cfg_map_count = 0,
                        //cfg_maps = null,
                        //get_cx_data = null,
                        //cfg_set = null,
                        get_glob_hdrs = null,
                        get_preview   = null,
                        //mr_get_mem_loc = null
                    }
                };
            }

            return(_singleton);
        }
Example #4
0
        public unsafe IEnumerable <VideoSample> DecodeVideo(byte[] frame, VideoPixelFormatsEnum pixelFormat, VideoCodecsEnum codec)
        {
            lock (_decoderLock)
            {
                if (_vp8Decoder == null)
                {
                    _vp8Decoder = new vpx_codec_ctx_t();
                    vpx_codec_iface_t   algo = vp8_dx.vpx_codec_vp8_dx();
                    vpx_codec_dec_cfg_t cfg  = new vpx_codec_dec_cfg_t {
                        threads = 1
                    };
                    vpx_codec_err_t res = vpx_decoder.vpx_codec_dec_init(_vp8Decoder, algo, cfg, 0);
                }

                //logger.LogDebug($"Attempting to decode {frame.Length} bytes.");
                //Console.WriteLine(frame.HexStr());

                fixed(byte *pFrame = frame)
                {
                    var result = vpx_decoder.vpx_codec_decode(_vp8Decoder, pFrame, (uint)frame.Length, IntPtr.Zero, 0);

                    //logger.LogDebug($"VP8 decode result {result}.");
                    if (result != vpx_codec_err_t.VPX_CODEC_OK)
                    {
                        logger.LogWarning($"VP8 decode of video sample failed with {result}.");
                    }
                }

                IntPtr iter = IntPtr.Zero;
                var    img  = vpx_decoder.vpx_codec_get_frame(_vp8Decoder, iter);

                if (img == null)
                {
                    logger.LogWarning("Image could not be acquired from VP8 decoder stage.");
                }
                else
                {
                    int dwidth  = (int)img.d_w;
                    int dheight = (int)img.d_h;
                    int sz      = dwidth * dheight;

                    var yPlane = img.planes[0];
                    var uPlane = img.planes[1];
                    var vPlane = img.planes[2];

                    byte[] decodedBuffer = new byte[dwidth * dheight * 3 / 2];

                    for (uint row = 0; row < dheight; row++)
                    {
                        Marshal.Copy((IntPtr)(yPlane + row * img.stride[0]), decodedBuffer, (int)(row * dwidth), (int)dwidth);

                        if (row < dheight / 2)
                        {
                            Marshal.Copy((IntPtr)(uPlane + row * img.stride[1]), decodedBuffer, (int)(sz + row * (dwidth / 2)), (int)dwidth / 2);
                            Marshal.Copy((IntPtr)(vPlane + row * img.stride[2]), decodedBuffer, (int)(sz + sz / 4 + row * (dwidth / 2)), (int)dwidth / 2);
                        }
                    }

                    byte[] rgb = PixelConverter.I420toBGR(decodedBuffer, dwidth, dheight, out _);
                    return(new List <VideoSample> {
                        new VideoSample {
                            Width = img.d_w, Height = img.d_h, Sample = rgb
                        }
                    });
                }

                return(new List <VideoSample>());
            }
        }
Example #5
0
        /*!\brief Get the capabilities of an algorithm.
         *
         * Retrieves the capabilities bitfield from the algorithm's interface.
         *
         * \param[in] iface   Pointer to the algorithm interface
         *
         */
        // vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface);

        public static vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t iface)
        {
            return((iface != null) ? iface.caps : 0);
        }
Example #6
0
        /*!\brief Return the name for a given interface
         *
         * Returns a human readable string for name of the given codec interface.
         *
         * \param[in]    iface     Interface pointer
         *
         */
        //const char* vpx_codec_iface_name(vpx_codec_iface_t * iface);

        public static string vpx_codec_iface_name(vpx_codec_iface_t iface)
        {
            return(iface != null ? iface.name : "<invalid interface>");
        }