public static int IMOS_XP_SetDecodeVideoMediaDataCB(int port, DecodeVideoDataCallback onDecodeVideoData, bool bContinue) { _decVideoCallbacks[port] = onDecodeVideoData; if (onDecodeVideoData != null) { IntPtr userParam = Marshal.GetFunctionPointerForDelegate(onDecodeVideoData); if (_isX64) { return(Native64.IMOS_XP_SetDecodeVideoMediaDataCB((uint)port, _onDecVideoData, bContinue, userParam)); } else { return(Native32.IMOS_XP_SetDecodeVideoMediaDataCB((uint)port, _onDecVideoData, bContinue, userParam)); } } else { if (_isX64) { return(Native64.IMOS_XP_SetDecodeVideoMediaDataCB((uint)port, null, bContinue, IntPtr.Zero)); } else { return(Native32.IMOS_XP_SetDecodeVideoMediaDataCB((uint)port, null, bContinue, IntPtr.Zero)); } } }
private static void onDecVideoData(uint ulPort, ref Native32.XP_PICTURE_DATA_S pPictureData, IntPtr lUserParam, IntPtr lReserved) { int width = (int)pPictureData.ulPicWidth; int height = (int)pPictureData.ulPicHeight; byte[] frame = new byte[width * height * 3 / 2]; int halfWidth = width / 2; int halfHeight = height / 2; int destOffset = 0; IntPtr srcPtr = (IntPtr)pPictureData.pucData[0]; for (int i = 0; i < height; i++) { Marshal.Copy(srcPtr, frame, destOffset, width); destOffset += width; srcPtr += (int)pPictureData.ulLineSize[0]; } srcPtr = (IntPtr)pPictureData.pucData[2]; for (int i = 0; i < halfHeight; i++) { Marshal.Copy(srcPtr, frame, destOffset, halfWidth); destOffset += halfWidth; srcPtr += (int)pPictureData.ulLineSize[2]; } srcPtr = (IntPtr)pPictureData.pucData[1]; for (int i = 0; i < halfHeight; i++) { Marshal.Copy(srcPtr, frame, destOffset, halfWidth); destOffset += halfWidth; srcPtr += (int)pPictureData.ulLineSize[1]; } DecodeVideoDataCallback onDecodeVideoData = (DecodeVideoDataCallback)Marshal.GetDelegateForFunctionPointer(lUserParam, typeof(DecodeVideoDataCallback)); onDecodeVideoData((int)ulPort, width, height, frame, (int)pPictureData.ulRenderTimeType, pPictureData.dlRenderTime); }