/// <summary> /// Decodes an encoded frame. /// </summary> /// <param name="encodedFrame">The encoded frame.</param> /// <returns></returns> public override VideoBuffer Decode(byte[] encodedFrame) { if (_Decoder == null) { _Decoder = new CocoaVp8Decoder(); } if (_Padep.SequenceNumberingViolated) { _Decoder.NeedsKeyFrame = true; return(null); } using (var pool = new NSAutoreleasePool()) { GCHandle encodedFrameHandle = GCHandle.Alloc(encodedFrame, GCHandleType.Pinned); try { IntPtr encodedFramePointer = encodedFrameHandle.AddrOfPinnedObject(); using (var encodedFrameData = NSData.FromBytesNoCopy(encodedFramePointer, (uint)encodedFrame.Length, false)) { using (var buffer = new CocoaVp8Buffer()) { if (_Decoder.DecodeFrame(encodedFrameData, buffer)) { var planeYData = new byte[buffer.PlaneY.Length]; var planeUData = new byte[buffer.PlaneU.Length]; var planeVData = new byte[buffer.PlaneV.Length]; Marshal.Copy(buffer.PlaneY.Bytes, planeYData, 0, (int)buffer.PlaneY.Length); Marshal.Copy(buffer.PlaneU.Bytes, planeUData, 0, (int)buffer.PlaneU.Length); Marshal.Copy(buffer.PlaneV.Bytes, planeVData, 0, (int)buffer.PlaneV.Length); return(new VideoBuffer(buffer.Width, buffer.Height, new[] { new VideoPlane(planeYData, buffer.StrideY), new VideoPlane(planeUData, buffer.StrideU), new VideoPlane(planeVData, buffer.StrideV) }, VideoFormat.I420)); } return(null); } } } finally { encodedFrameHandle.Free(); } } }
/// <summary> /// Encodes a frame. /// </summary> /// <param name="frame">The frame.</param> /// <returns></returns> public override byte[] Encode(VideoBuffer frame) { if (_Encoder == null) { _Encoder = new CocoaVp8Encoder(); _Encoder.Quality = 0.5; _Encoder.Bitrate = 320; //_Encoder.Scale = 1.0; } if (frame.ResetKeyFrame) { _Encoder.SendKeyframe(); } using (var pool = new NSAutoreleasePool()) { VideoPlane planeY = frame.Planes[0]; VideoPlane planeU = frame.Planes[1]; VideoPlane planeV = frame.Planes[2]; GCHandle planeYDataHandle = GCHandle.Alloc(planeY.Data, GCHandleType.Pinned); GCHandle planeUDataHandle = GCHandle.Alloc(planeU.Data, GCHandleType.Pinned); GCHandle planeVDataHandle = GCHandle.Alloc(planeV.Data, GCHandleType.Pinned); try { IntPtr planeYDataPointer = planeYDataHandle.AddrOfPinnedObject(); IntPtr planeUDataPointer = planeUDataHandle.AddrOfPinnedObject(); IntPtr planeVDataPointer = planeVDataHandle.AddrOfPinnedObject(); //TODO: index/length using (var buffer = new CocoaVp8Buffer { PlaneY = NSData.FromBytesNoCopy(planeYDataPointer, (uint)planeY.Data.Length, false), PlaneU = NSData.FromBytesNoCopy(planeUDataPointer, (uint)planeU.Data.Length, false), PlaneV = NSData.FromBytesNoCopy(planeVDataPointer, (uint)planeV.Data.Length, false), StrideY = planeY.Stride, StrideU = planeU.Stride, StrideV = planeV.Stride, Width = frame.Width, Height = frame.Height }) { using (var encodedFrame = new NSMutableData()) { if (_Encoder.EncodeBuffer(buffer, encodedFrame)) { return(encodedFrame.ToArray()); } return(null); } } } finally { planeYDataHandle.Free(); planeUDataHandle.Free(); planeVDataHandle.Free(); } } }
/// <summary> /// Encodes a frame. /// </summary> /// <param name="frame">The frame.</param> /// <returns></returns> public override byte[] Encode(VideoBuffer frame) { if (_Encoder == null) { _Encoder = new CocoaVp8Encoder(); _Encoder.Quality = 0.5; _Encoder.Bitrate = 320; //_Encoder.Scale = 1.0; } if (frame.ResetKeyFrame) { _Encoder.SendKeyframe(); } using (var pool = new NSAutoreleasePool()) { VideoPlane planeY = frame.Planes[0]; VideoPlane planeU = frame.Planes[1]; VideoPlane planeV = frame.Planes[2]; GCHandle planeYDataHandle = GCHandle.Alloc(planeY.Data, GCHandleType.Pinned); GCHandle planeUDataHandle = GCHandle.Alloc(planeU.Data, GCHandleType.Pinned); GCHandle planeVDataHandle = GCHandle.Alloc(planeV.Data, GCHandleType.Pinned); try { IntPtr planeYDataPointer = planeYDataHandle.AddrOfPinnedObject(); IntPtr planeUDataPointer = planeUDataHandle.AddrOfPinnedObject(); IntPtr planeVDataPointer = planeVDataHandle.AddrOfPinnedObject(); //TODO: index/length using (var buffer = new CocoaVp8Buffer { PlaneY = NSData.FromBytesNoCopy(planeYDataPointer, (uint)planeY.Data.Length, false), PlaneU = NSData.FromBytesNoCopy(planeUDataPointer, (uint)planeU.Data.Length, false), PlaneV = NSData.FromBytesNoCopy(planeVDataPointer, (uint)planeV.Data.Length, false), StrideY = planeY.Stride, StrideU = planeU.Stride, StrideV = planeV.Stride, Width = frame.Width, Height = frame.Height }) { using (var encodedFrame = new NSMutableData()) { if (_Encoder.EncodeBuffer(buffer, encodedFrame)) { return encodedFrame.ToArray(); } return null; } } } finally { planeYDataHandle.Free(); planeUDataHandle.Free(); planeVDataHandle.Free(); } } }
/// <summary> /// Decodes an encoded frame. /// </summary> /// <param name="encodedFrame">The encoded frame.</param> /// <returns></returns> public override VideoBuffer Decode(byte[] encodedFrame) { if (_Decoder == null) { _Decoder = new CocoaVp8Decoder(); } if (_Padep.SequenceNumberingViolated) { _Decoder.NeedsKeyFrame = true; return null; } using (var pool = new NSAutoreleasePool()) { GCHandle encodedFrameHandle = GCHandle.Alloc(encodedFrame, GCHandleType.Pinned); try { IntPtr encodedFramePointer = encodedFrameHandle.AddrOfPinnedObject(); using (var encodedFrameData = NSData.FromBytesNoCopy(encodedFramePointer, (uint)encodedFrame.Length, false)) { using (var buffer = new CocoaVp8Buffer()) { if (_Decoder.DecodeFrame(encodedFrameData, buffer)) { var planeYData = new byte[buffer.PlaneY.Length]; var planeUData = new byte[buffer.PlaneU.Length]; var planeVData = new byte[buffer.PlaneV.Length]; Marshal.Copy(buffer.PlaneY.Bytes, planeYData, 0, (int)buffer.PlaneY.Length); Marshal.Copy(buffer.PlaneU.Bytes, planeUData, 0, (int)buffer.PlaneU.Length); Marshal.Copy(buffer.PlaneV.Bytes, planeVData, 0, (int)buffer.PlaneV.Length); return new VideoBuffer(buffer.Width, buffer.Height, new[] { new VideoPlane(planeYData, buffer.StrideY), new VideoPlane(planeUData, buffer.StrideU), new VideoPlane(planeVData, buffer.StrideV) }, VideoFormat.I420); } return null; } } } finally { encodedFrameHandle.Free(); } } }