/// <summary> /// Encodes a frame. /// </summary> /// <param name="frame">The frame.</param> /// <returns></returns> public override byte[] Encode(AudioBuffer frame) { if (_Encoder == null) { _Encoder = new CocoaOpusEncoder(ClockRate, Channels, PacketTime); _Encoder.Quality = 1.0; _Encoder.Bitrate = 125; } using (var pool = new NSAutoreleasePool()) { GCHandle dataHandle = GCHandle.Alloc(frame.Data, GCHandleType.Pinned); try { IntPtr dataPointer = dataHandle.AddrOfPinnedObject(); using (var buffer = new CocoaOpusBuffer { Data = NSData.FromBytesNoCopy(dataPointer, (uint)frame.Data.Length, false), Index = frame.Index, Length = frame.Length }) { using (var encodedFrameData = _Encoder.EncodeBuffer(buffer)) { return(encodedFrameData.ToArray()); } } } finally { dataHandle.Free(); } } }
private AudioBuffer Decode(byte[] encodedFrame, bool fec) { using (var pool = new NSAutoreleasePool()) { GCHandle encodedFrameHandle = GCHandle.Alloc(encodedFrame, GCHandleType.Pinned); try { IntPtr encodedFramePointer = encodedFrame == null ? IntPtr.Zero : encodedFrameHandle.AddrOfPinnedObject(); using (var encodedFrameData = encodedFrame == null ? null : NSData.FromBytesNoCopy(encodedFramePointer, (uint)encodedFrame.Length, false)) { using (var buffer = _Decoder.DecodeFrame(encodedFrameData, fec)) { if (buffer == null) { return(null); } var frame = new byte[buffer.Length]; Marshal.Copy(buffer.Data.Bytes, frame, buffer.Index, buffer.Length); return(new AudioBuffer(frame, 0, frame.Length)); } } } finally { encodedFrameHandle.Free(); } } }
public void FromBytesNoCopyFree() { byte[] bytes = new byte[] { 1, 2, 3, 4 }; IntPtr ptr = Marshal.AllocHGlobal(bytes.Length); Marshal.Copy(bytes, 0, ptr, bytes.Length); var data = NSData.FromBytesNoCopy(ptr, (uint)bytes.Length, false); Assert.AreEqual(bytes.Length, data.Length); Assert.AreEqual(ptr, data.Bytes); }
/// <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(); } } }
public NSData MakeExternalForm() { var extForm = Marshal.AllocHGlobal(kAuthorizationExternalFormLength); var result = AuthorizationMakeExternalForm(Handle, extForm); if (result == 0) { return(NSData.FromBytesNoCopy( extForm, kAuthorizationExternalFormLength, freeWhenDone: true)); } Marshal.FreeHGlobal(extForm); throw new Exception($"AuthorizationMakeExternalForm returned {result}"); }
/// <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(); } } }