/// <summary> /// Destroys the codec. /// </summary> public override void Destroy() { if (_Encoder != null) { _Encoder.Destroy(); _Encoder.Dispose(); _Encoder = null; } if (_Decoder != null) { _Decoder.Destroy(); _Decoder.Dispose(); _Decoder = null; } }
/// <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(); } } }