/// <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)); }
/// <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); }
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); }
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>()); } }
/*!\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); }
/*!\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>"); }