void VideoStartup(StreamInfoArgs args) //, string profToken) { { vidBuff = new VideoBuffer((int)args.sourceResolution.Width, (int)args.sourceResolution.Height); VideoPlayerView playview = new VideoPlayerView(); disposables.Add(playview); player.Child = playview; playview.Init(new VideoPlayerView.Model( streamSetup: args.streamSetup, mediaUri: new MediaUri() { uri = args.streamUri }, encoderResolution: new VideoResolution() { height = (int)args.sourceResolution.Height, width = (int)args.sourceResolution.Width }, isUriEnabled: false, metadataReceiver: null )); }
public override void update(ref VideoBuffer videoBuffer) { try { /*// loops through image and copied it into the buffer * for (int y = _positionY; y < _image.Height + _positionY; y++) * { * for (int x = _positionX; x < _image.Width + _positionY; x++) * { * if(x >= 0 && y >= 0 && x < videoBuffer.Width && y < videoBuffer.Height) * videoBuffer.Buffer[y, x] = colorToRGB(_image.GetPixel(x, y)); * } * }*/ // loops through video buffer and for (int y = 0; y < videoBuffer.Height; y++) { for (int x = 0; x < videoBuffer.Width; x++) { if (x - _positionX >= 0 && y - _positionY >= 0 && x - _positionX < _image.Width && y - _positionY < _image.Height) { if (_image.GetPixel(x, y).A != 0) // dont render transparrent pixels { videoBuffer.setPixel(x, y, colorToRGB(_image.GetPixel(x - _positionX, y - _positionY))); } } } } } catch (Exception e) { //TODO: Proper exceptions } }
/// <summary> /// Encodes a frame. /// </summary> /// <param name="frame">The video buffer.</param> /// <returns></returns> public override byte[] Encode(VideoBuffer frame) { if (Encoder == null) { Encoder = new Encoder(); Encoder.Quality = 0.5; Encoder.Bitrate = 320; //Encoder.Scale = 1.0; } if (frame.ResetKeyFrame) { Encoder.ForceKeyframe(); } // frame -> vp8 int width, height; var rotate = frame.Rotate; if (rotate % 180 == 0) { width = frame.Width; height = frame.Height; } else { height = frame.Width; width = frame.Height; } return(Encoder.Encode(width, height, frame.Plane.Data, frame.FourCC, rotate)); }
public override void update(ref VideoBuffer videoBuffer) { if (!intervalReached()) { return; // only update if interval met } for (int y = 0; y <= this.endY; y++) { for (int x = 0; x <= this.endX; x++) { videoBuffer.setPixel(flip ? videoBuffer.Width - x - 1 : x, y, colour); } } endX++; if (endX >= videoBuffer.Width) { endX = 0; flip = !flip; endY++; } if (endY >= videoBuffer.Height) { endX = 0; endY = 0; } reset(); }
public override void update(ref VideoBuffer videoBuffer) { if (intervalReached()) { //Console.WriteLine("Frame: {0}/{1}", (_frameIndex + 1), _frameCount); // load current frame _gif.SelectActiveFrame(_frames, _frameIndex); _image = new Bitmap(_gif, new Size(_image.Width, _image.Height)); /*_image.RotateFlip(RotateFlipType.Rotate90FlipNone); * _image.RotateFlip(RotateFlipType.Rotate90FlipNone); * _image.RotateFlip(RotateFlipType.Rotate90FlipNone);*/ // increment frame _frameIndex++; if (_frameIndex >= _frameCount) { _frameIndex = 0; } // have the BitmapEffect code render the frame Timer.Restart(); } base.update(ref videoBuffer); }
private void DrawFrame(VideoBuffer videoBuffer, PlaybackStatistics statistics) { Bitmap bmp = img as Bitmap; BitmapData bd = null; try { bd = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);//bgra32 using (var md = videoBuffer.Lock()) { CopyMemory(bd.Scan0, md.value.scan0Ptr, videoBuff.stride * videoBuff.height); //bitmap.WritePixels( // new Int32Rect(0, 0, videoBuffer.width, videoBuffer.height), // md.value.scan0Ptr, videoBuffer.size, videoBuffer.stride, // 0, 0 //); } } catch (Exception err) { //errBox.Text = err.Message; Debug.Print("DrawFrame:: " + err.Message); } finally { bmp.UnlockBits(bd); } imageBox.Image = bmp; }
/// <summary> /// Encodes a frame. /// </summary> /// <param name="frame">The video buffer.</param> /// <returns></returns> public override byte[] Encode(VideoBuffer frame) { if (Encoder == null) { Encoder = new Encoder(); Encoder.Quality = 0.5; Encoder.Bitrate = 320; //Encoder.Scale = 1.0; } if (frame.ResetKeyFrame) { Encoder.ForceKeyframe(); } // frame -> vp8 int width, height; var rotate = frame.Rotate; if (rotate % 180 == 0) { width = frame.Width; height = frame.Height; } else { height = frame.Width; width = frame.Height; } return Encoder.Encode(width, height, frame.Plane.Data, frame.FourCC, rotate); }
public override void update(ref VideoBuffer videoBuffer) { if (!intervalReached()) { return; // only update if interval met } // loop through entire video buffer and generte random values for (int y = 0; y < videoBuffer.Height; y++) { for (int x = 0; x < videoBuffer.Width; x++) { // generate random RGB values int r = Random.Next(255); int g = Random.Next(255); int b = Random.Next(255); // bit shift the RGB values into one int int rgb = b << 8 | g; rgb = rgb << 8 | r; videoBuffer.setPixel(x, y, (uint)rgb); // set the VideoBuffer value at x, y to the randomised RGB value } } isComplete = true; reset(); }
private void InitPlayer(string videoUri, NetworkCredential account, Size size = default(Size)) { hostedPlayer = new HostedPlayer(); playerDisposables.Add(hostedPlayer); if (size != default(Size)) { videoBuffer = new VideoBuffer(size.Width, size.Height, PixFrmt.bgra32); } else { videoBuffer = new VideoBuffer(720, 576, PixFrmt.bgra32); } hostedPlayer.SetVideoBuffer(videoBuffer); MediaStreamInfo.Transport transport = MediaStreamInfo.Transport.Tcp; MediaStreamInfo streamInfo = null; if (account != null) { streamInfo = new MediaStreamInfo(videoUri, transport, new UserNameToken(account.UserName, account.Password)); } else { streamInfo = new MediaStreamInfo(videoUri, transport); } playerDisposables.Add( hostedPlayer.Play(streamInfo, this) ); InitPlayback(videoBuffer, true); }
protected override bool WriteFrameHeader(VideoFrame frame, VideoBuffer buffer) { var magicString = "FRAME"; var widthString = buffer.Width == _HeaderWidth ? null : buffer.Width.ToString(); var heightString = buffer.Height == _HeaderHeight ? null : buffer.Height.ToString(); var frameHeader = new StringBuilder(); // signature frameHeader.Append(magicString); // width if (widthString != null) { frameHeader.Append(" W"); frameHeader.Append(widthString); } // height if (heightString != null) { frameHeader.Append(" H"); frameHeader.Append(heightString); } frameHeader.Append("\n"); return Pipe.TryWrite(DataBuffer.Wrap(Encoding.ASCII.GetBytes(frameHeader.ToString()))); }
public override void update(ref VideoBuffer videoBuffer) { for (int y = 0; y < videoBuffer.Height; y++) { for (int x = 0; x < videoBuffer.Width; x++) { int r = BitConverter.GetBytes(videoBuffer.getPixel(x, y))[0]; int g = BitConverter.GetBytes(videoBuffer.getPixel(x, y))[1]; int b = BitConverter.GetBytes(videoBuffer.getPixel(x, y))[2]; //Color color = Color.FromArgb(r, g, b); //TODO: replace all this for ControlPaint.Light/ControlPaint.Darken using System.Drawing.Color instead double h = 0; double l = 0; double s = 0; RgbToHls(r, g, b, out h, out l, out s); //TODO: This is a quick way to get around transparency. Need a better way. if (videoBuffer.getPixel(x, y) != 0x000000) { l = Brightness; } HlsToRgb(h, l, s, out r, out g, out b); int rgb = b << 8 | g; rgb = rgb << 8 | r; videoBuffer.setPixel(x, y, (uint)rgb); } } }
protected override bool WriteStreamHeader(VideoFrame frame, VideoBuffer buffer) { _HeaderWidth = buffer.Width; _HeaderHeight = buffer.Height; var magicString = "YUV4MPEG2"; var widthString = buffer.Width.ToString(); var heightString = buffer.Height.ToString(); var colourSpace = "420"; var streamHeader = new StringBuilder(); // signature streamHeader.Append(magicString); // width streamHeader.Append(" W"); streamHeader.Append(widthString); // height streamHeader.Append(" H"); streamHeader.Append(heightString); // colour space streamHeader.Append(" C"); streamHeader.Append(colourSpace); streamHeader.Append("\n"); return Pipe.TryWrite(DataBuffer.Wrap(Encoding.ASCII.GetBytes(streamHeader.ToString()))); }
public override void update(ref VideoBuffer videoBuffer) { foreach (Line line in _lines) { for (int y = 0; y < line.Length; y++) { if (line.X >= 0 && line.Y >= 0 && line.X < videoBuffer.Width && line.Y + y < videoBuffer.Height) { videoBuffer.setPixel(line.X, line.Y + y, line.Colour); } } } if (!intervalReached()) { return; } foreach (Line line in _lines) { line.Y += _random.Next(3); if (line.Y >= videoBuffer.Height) { line.Y = 0; } line.X += _random.Next(2); if (line.X >= videoBuffer.Width) { line.X = 0; } } Timer.Restart(); }
private void DrawFrame(VideoBuffer videoBuffer) { if (isRecording) { Bitmap bitmap = new Bitmap(videoBuffer.width, videoBuffer.height); BitmapData bitmapData = null; try { bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); using (var md = videoBuffer.Lock()) { CopyMemory(bitmapData.Scan0, md.value.scan0Ptr, buffer.stride * buffer.height); } } catch (Exception e) { } finally { bitmap.UnlockBits(bitmapData); } bitmaps.Enqueue(bitmap); //bitmaps.Add(bitmap); } }
private WriteableBitmap PrepareForRendering(VideoBuffer videoBuffer) { PixelFormat pixelFormat; if (videoBuffer.pixelFormat == PixFrmt.rgb24) { pixelFormat = PixelFormats.Rgb24; } else if (videoBuffer.pixelFormat == PixFrmt.bgra32) { pixelFormat = PixelFormats.Bgra32; } else if (videoBuffer.pixelFormat == PixFrmt.bgr24) { pixelFormat = PixelFormats.Bgr24; } else { throw new Exception("unsupported pixel format"); } var bitmap = new WriteableBitmap( videoBuffer.width, videoBuffer.height, 96, 96, pixelFormat, null ); _imgVIew.Source = bitmap; return(bitmap); }
public void BindRectangleToSurface(VideoBuffer frame, int width, int height) { if (Rectangle.Width != width) { Rectangle.Width = width; Rectangle.Height = (int)(((float)frame.Height / (float)frame.Width) * width); } }
/// <summary> /// Initiate rendering loop /// </summary> /// <param name="videoBuffer"></param> public void InitPlayback(VideoBuffer videoBuffer) { if (videoBuffer == null) { throw new ArgumentNullException("videoBufferDescription"); } VerifyAccess(); TimeSpan renderinterval; try { int fps = AppDefaults.visualSettings.ui_video_rendering_fps; fps = (fps <= 0 || fps > 100) ? 100 : fps; renderinterval = TimeSpan.FromMilliseconds(1000 / fps); } catch { renderinterval = TimeSpan.FromMilliseconds(1000 / 30); } var cancellationTokenSource = new CancellationTokenSource(); renderSubscription.Disposable = Disposable.Create(() => { cancellationTokenSource.Cancel(); }); var bitmap = PrepareForRendering(videoBuffer); var cancellationToken = cancellationTokenSource.Token; var dispatcher = this.Dispatcher; //Application.Current.Dispatcher; var renderingTask = Task.Factory.StartNew(() => { var statistics = PlaybackStatistics.Start(); using (videoBuffer.Lock()) { try { //start rendering loop while (!cancellationToken.IsCancellationRequested) { using (var processingEvent = new ManualResetEventSlim(false)) { dispatcher.BeginInvoke(() => { using (Disposable.Create(() => processingEvent.Set())) { if (!cancellationToken.IsCancellationRequested) { //update statisitc info statistics.Update(videoBuffer); //render farme to screen DrawFrame(bitmap, videoBuffer, statistics); } } }); processingEvent.Wait(cancellationToken); } cancellationToken.WaitHandle.WaitOne(renderinterval); } } catch (OperationCanceledException) { //swallow exception } catch (Exception error) { dbg.Error(error); } } }, cancellationToken); }
private VideoBuffer GetBuffer(IVideoRequestType requestType, int timeoutMs, int pageSize) { if (!_ytVideoBuffers.ContainsKey(requestType)) { VideoContext context = new VideoContext(); _ytVideoBuffers[requestType] = new VideoBuffer(GetVideosInternal(requestType, timeoutMs, pageSize, context), context); } return(_ytVideoBuffers[requestType] as VideoBuffer); }
public override void update(ref VideoBuffer videoBuffer) { if (!intervalReached()) { return; } //for(int y = 0; videoBuffer) Timer.Restart(); }
public override void update(ref VideoBuffer videoBuffer) { for (int x = 0; x < videoBuffer.Width; x++) { for (int y = 0; y < videoBuffer.Height; y++) { videoBuffer.setPixel(x, y, colour); } } }
public NdiVideoSink(NDI.Sender ndiSender, int requestedWidth, int requestedHeight, int frameRateNumerator, int frameRateDenominator, VideoFormat format) : base(format) { _FrameRateNumerator = frameRateNumerator; _FrameRateDenominator = frameRateDenominator; _RequestedHeight = requestedHeight; _RequestedWidth = requestedWidth; _NdiSender = ndiSender; _VideoBuffer = VideoBuffer.CreateBlack(requestedWidth, requestedHeight, format.Name); }
void VideoStartup(Model model, VideoResolution resolution) { //subscribe to metadata IMetadataReceiver metadataReceiver = null; if (AppDefaults.visualSettings.EnableGraphicAnnotation) { string vaConfToken = model.engineConfToken; var eventMetadataProcessor = new EventMetadataProcessor(); //eventMetadataProcessor.Processors.Add(new ObjectMotionMetadataProcessor(null, vaConfToken, movingObjectsHolder.EntityInitialized, movingObjectsHolder.EntityChanged, movingObjectsHolder.EntityDeleted)); eventMetadataProcessor.Processors.Add(new MotionAlarmMetadataProcessor(null, vaConfToken, alarmsHolder.EntityInitialized, alarmsHolder.EntityChanged, alarmsHolder.EntityDeleted)); eventMetadataProcessor.Processors.Add(new RegionMotionAlarmMetadataProcessor(null, vaConfToken, alarmsHolder.EntityInitialized, alarmsHolder.EntityChanged, alarmsHolder.EntityDeleted)); eventMetadataProcessor.Processors.Add(new LoiteringAlarmMetadataProcessor(null, vaConfToken, alarmsHolder.EntityInitialized, alarmsHolder.EntityChanged, alarmsHolder.EntityDeleted)); eventMetadataProcessor.Processors.Add(new AbandonedItemAlarmMetadataProcessor(null, vaConfToken, alarmsHolder.EntityInitialized, alarmsHolder.EntityChanged, alarmsHolder.EntityDeleted)); eventMetadataProcessor.Processors.Add(new TripwireAlarmMetadataProcessor(null, vaConfToken, alarmsHolder.EntityInitialized, alarmsHolder.EntityChanged, alarmsHolder.EntityDeleted)); eventMetadataProcessor.Processors.Add(new TamperingDetectorAlarmMetadataProcessor(null, vaConfToken, alarmsHolder.EntityInitialized, alarmsHolder.EntityChanged, alarmsHolder.EntityDeleted)); var sceneMetadataProcessor = new SceneMetadataProcessor(movingObjectsHolder.EntityInitialized, movingObjectsHolder.EntityChanged, movingObjectsHolder.EntityDeleted); var metadataProcessor = new MetadataProcessor(eventMetadataProcessor, sceneMetadataProcessor); metadataReceiver = new MetadataFramer(metadataProcessor.Process); } vidBuff = new VideoBuffer(resolution.width, resolution.height); var streamSetup = new StreamSetup() { transport = new Transport() { protocol = AppDefaults.visualSettings.Transport_Type } }; VideoPlayerView playview = new VideoPlayerView(); disposables.Add(playview); player.Child = playview; playview.Init(new VideoPlayerView.Model( streamSetup: streamSetup, mediaUri: new MediaUri() { uri = model.uri }, encoderResolution: new VideoResolution() { height = resolution.height, width = resolution.width }, isUriEnabled: false, //TODO if true then annotation is not positioned correctly metadataReceiver: metadataReceiver )); uriString.Visibility = System.Windows.Visibility.Visible; uriString.Text = model.uri; }
protected virtual bool WriteFrame(VideoFrame frame, VideoBuffer inputBuffer) { foreach (var dataBuffer in inputBuffer.DataBuffers) { if (!Pipe.TryWrite(dataBuffer)) { return(false); } } return(true); }
public override void update(ref VideoBuffer videoBuffer) { base.update(ref videoBuffer); if (!intervalReached()) { return; } _textPositionX--; Timer.Restart(); }
/// <summary> /// Pops the content of the stack into Video RAM /// </summary> public static void PopContents() { VideoBuffer vb = vbufferStack.Pop(); byte * VideoRam = (byte *)0xB8000; for (int i = 0; i < 4250; i++) { VideoRam[i] = vb.data[i]; } CursorLeft = vb.X; CursorTop = vb.Y; }
public override void update(ref VideoBuffer videoBuffer) { for (int x = 0; x < videoBuffer.Width; x++) { for (int y = (videoBuffer.Height / 8) * 7; y < videoBuffer.Height; y++) { colour = (uint)random.Next(180, 255) << 8 | (uint)random.Next(180, 255); colour = this.colour << 8 | (uint)random.Next(100, 255); videoBuffer.setPixel(x, y, colour); } } }
public override void Render(VideoBuffer frame) { RunOnUIThread(() => { //if (DrawingSurface.Width != frame.Width || DrawingSurface.Height != frame.Height) //{ // DrawingSurface.Width = frame.Width; // DrawingSurface.Height = frame.Height; //} SharpDXRenderProvider.BindRectangleToSurface(frame, (int)DrawingSurface.Width, (int)DrawingSurface.Height); SharpDXRenderProvider.Render(frame); }); }
/// <summary> /// Raises a captured video buffer for processing to specific peers. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="peerIds">Peer identifiers.</param> protected override void RaiseFrame(VideoBuffer buffer, string[] peerIds) { // encode var encodedFrame = buffer.Encode(_Codec); // record _Recorder.Write(encodedFrame, buffer.Width, buffer.Height); // send to peers (if any) base.RaiseFrame(new VideoBuffer(buffer.Width, buffer.Height, new VideoPlane(encodedFrame)) { Encoded = true }, peerIds); }
protected override bool WriteStreamHeader(VideoFrame frame, VideoBuffer buffer) { _HeaderWidth = buffer.Width; _HeaderHeight = buffer.Height; var magicString = "YUV4MPEG2"; var widthString = buffer.Width.ToString(); var heightString = buffer.Height.ToString(); var colourSpace = "420"; var written = true; // signature foreach (var c in magicString) { written &= Write8(c); } // width written &= Write8(' '); written &= Write8('W'); foreach (var c in widthString) { written &= Write8(c); } // height written &= Write8(' '); written &= Write8('H'); foreach (var c in heightString) { written &= Write8(c); } // colour space written &= Write8(' '); written &= Write8('C'); foreach (var c in colourSpace) { written &= Write8(c); } written &= Write8('\n'); return(written); }
/// <summary> /// Pushes what is in video RAM onto a stack /// </summary> public static void PushContents() { VideoBuffer vb = new VideoBuffer(); byte * VideoRam = (byte *)0xB8000; vb.data = new byte[4250]; for (int i = 0; i < 4250; i++) { byte b = VideoRam[i]; vb.data[i] = b; } vb.X = AConsole.CursorLeft; vb.Y = CursorTop; vbufferStack.Push(vb); }
public WaterEffect(int interval, VideoBuffer videoBuffer) { this.Interval = interval; this._lines = new ArrayList(); this._random = new Random(); play(); for (int y = -videoBuffer.Height; y < 0; y += 8) { for (int x = 0; x < videoBuffer.Width; x += _random.Next(2)) { _lines.Add(new Line(x, y + _random.Next(8), 3, 1, 0xFFFFFF)); } } }
public override byte[] Encode(VideoBuffer frame) { if (_Encoder == null) { _Encoder = new Win8_VP8.Encoder(); } if (frame.ResetKeyFrame) { _Encoder.ForceKeyframe(); } // buffer -> bitmap var bitmap = new Win8_VP8.Yuy2Bitmap(frame.Width, frame.Height) { Buffer = frame.Plane.Data }; // bitmap -> vp8 return _Encoder.Encode(bitmap); }
/// <summary> /// Encodes a frame. /// </summary> /// <param name="videoBuffer">The video buffer.</param> /// <returns></returns> public override byte[] Encode(VideoBuffer videoBuffer) { if (Encoder == null) { Encoder = new Encoder(); } // frame -> vp8 int width, height; var rotate = videoBuffer.Rotate; if (rotate % 180 == 0) { width = videoBuffer.Width; height = videoBuffer.Height; } else { height = videoBuffer.Width; width = videoBuffer.Height; } return Encoder.Encode(width, height, videoBuffer.Plane.Data, LibVpxEnc.FOURCC_NV21, rotate); }
public void Render(VideoBuffer videoBuffer) { if(GraphicsDevice == null) { return; } if (RenderTarget2D == null) { RenderTarget2D = RenderTarget2D.New(GraphicsDevice, videoBuffer.Width, videoBuffer.Height, PixelFormat.B8G8R8A8.UNorm); } else if (RenderTarget2D != null && (RenderTarget2D.Width != videoBuffer.Width || RenderTarget2D.Height != videoBuffer.Height)) { RenderTarget2D.Dispose(); RenderTarget2D = null; RenderTarget2D = RenderTarget2D.New(GraphicsDevice, videoBuffer.Width, videoBuffer.Height, PixelFormat.B8G8R8A8.UNorm); } if (RenderTarget2D != null) { var x = 0; var data = videoBuffer.Plane.Data; var argb = new int[videoBuffer.Width * videoBuffer.Height]; for (var i = 0; i < argb.Length; i++) { var r = data[x++]; var g = data[x++]; var b = data[x++]; var a = data[x++]; argb[i] = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0); } RenderTarget2D.SetData<int>(argb); } }
public override void Render(VideoBuffer frame) { }
public override async void Render(VideoBuffer frame) { if (!Rendering) { Rendering = true; var stream = new InMemoryRandomAccessStream(); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream); encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Ignore, (uint)frame.Width, (uint)frame.Height, 96, 96, frame.Plane.Data); await encoder.FlushAsync(); stream.Seek(0); Win8LayoutManager.SafeInvoke(async () => { await Bitmap.SetSourceAsync(stream); Rendering = false; }); } }
private VideoBuffer GetBuffer(IVideoRequestType requestType, int timeoutMs, int pageSize) { if (!_ytVideoBuffers.ContainsKey(requestType)) { VideoContext context = new VideoContext(); _ytVideoBuffers[requestType] = new VideoBuffer(GetVideosInternal(requestType, timeoutMs, pageSize, context), context); } return _ytVideoBuffers[requestType] as VideoBuffer; }
/// <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(); } } }