public override DataTransferStatus OnMessage(ICommand command, AtemConnection connection) { if (command is DataTransferDataCommand dataCommand && dataCommand.TransferId == _id) { // TODO - do i need to track ids to avoid duplicate data on retransmits? _receivedData.Add(dataCommand.Body); connection.QueueCommand(new DataTransferAckCommand() { TransferId = _id, TransferIndex = _index, }); return(DataTransferStatus.OK); } if (command is DataTransferCompleteCommand completeCommand && completeCommand.TransferId == _id) { var fullData = _receivedData.SelectMany(d => d).ToArray(); _onComplete(AtemFrame.FromAtem(_resolution, "", fullData)); // TODO - name return(DataTransferStatus.Success); } return(DataTransferStatus.Unknown); }
public void updateLabel(string deviceId, string name, uint id) { var client = _repo.GetConnection(deviceId); if (client == null) { throw new Exception("Bad deviceId"); } var job = new UploadMultiViewJob(id, AtemFrame.FromYCbCr(name, MultiViewImage.Make(name)), uploadResult); client.Client.DataTransfer.QueueJob(job); }
public async Task <String> UploadStill(string deviceId, uint stillId, [FromBody] ImageUploadeData data) { AtemClientExt client = _repo.GetConnection(deviceId); if (client == null) { throw new Exception("Device not found"); } if (data.Image == null || data.Name == null) { throw new Exception("Missing image body"); } var resolution = VideoModeResolution._1080; var resolutionSize = resolution.GetSize(); byte[] rawBytes = Convert.FromBase64String(data.Image); using Image <Rgba32> image = Image.Load(rawBytes); image.Mutate(x => x.Resize(new ResizeOptions { Size = new Size((int)resolutionSize.Item1, (int)resolutionSize.Item2), Mode = ResizeMode.Pad })); byte[] rgbaBytes = GetBytes(image); var frame = AtemFrame.FromRGBA(data.Name, rgbaBytes, ColourSpace.BT709); // TODO - colorspace var completion = new TaskCompletionSource <bool>(); var job = new UploadMediaStillJob(stillId, frame, (success) => { Console.WriteLine("Still upload {0} completed with {1}", stillId, success); completion.SetResult(success); }); Console.WriteLine("Still upload {0} queued", stillId); client.Client.DataTransfer.QueueJob(job); // Wait for the upload before returning await completion.Task; // TOOD - report failure return("success"); }
public override DataTransferStatus OnMessage(ICommand command, AtemConnection connection) { if (_currentFrame != null) { DataTransferStatus r = _currentFrame.OnMessage(command, connection); switch (r) { case DataTransferStatus.OK: return(DataTransferStatus.OK); case DataTransferStatus.Error: _onComplete(false); return(DataTransferStatus.Error); } } else if (command.GetType() != typeof(MediaPoolClipDescriptionCommand)) // TODO - check the command values match { return(DataTransferStatus.OK); } // status was success, or is first frame if (_completedFrames >= _frames.Count) { connection.QueueCommand(new MediaPoolSetClipCommand() { Index = ClipIndex, Name = _name, Frames = (uint)_frames.Count, }); _onComplete(true); return(DataTransferStatus.Success); } int index = _completedFrames++; AtemFrame nextFrame = _frames[index]; _currentFrame = new UploadMediaFrameJob(StoreId, (uint)index, nextFrame, b => { }); ICommand cmd = _currentFrame.Start((uint)(_id + index + 5)); // TODO - proper id connection.QueueCommand(cmd); return(DataTransferStatus.OK); }
public async Task <IActionResult> GetImage(string deviceId, string hash) { // TODO - quality/format selector var client = _repo.GetConnection(deviceId); if (client == null) { return(BadRequest("Device not found")); } AtemMediaCacheItem image = client.GetImage(hash.ToUpper()); if (image == null) { return(NotFound()); } if (image.PreviewJpeg == null) { AtemFrame frame = await GetFrameFromJob(image); // TODO - this makes a lot of assumptions about color space and resolution using Image image2 = Image.LoadPixelData <Rgba32>(frame.GetRGBA(ColourSpace.BT709), 1920, 1080); // TODO - is this a good resolution? image2.Mutate(x => x.Resize(640, 0)); var outStream = new MemoryStream(); await image2.SaveAsJpegAsync(outStream); image.PreviewJpeg = outStream.ToArray(); } return(File(image.PreviewJpeg, "image/jpeg")); }
public UploadMediaStillJob(uint index, AtemFrame frame, Action <bool> onComplete, TimeSpan?timeout = null) : base(0, index, frame, onComplete, timeout) { }
public UploadMediaFrameJob(uint bank, uint index, AtemFrame frame, Action <bool> onComplete, TimeSpan?timeout = null) : base(bank, frame.GetRLEEncodedYCbCr(), onComplete, timeout) { _index = index; _frame = frame; }
public UploadMediaFrameJob(uint bank, uint index, AtemFrame frame, Action <bool> onComplete, TimeSpan?timeout = null) : base(bank, frame.GetYCbCrData() /*.GetRLEEncodedYCbCr() This doesnt work because it needs to line up with command boundaries */, onComplete, timeout) { _index = index; _frame = frame; }
public UploadMultiViewJob(uint index, AtemFrame frame, Action <bool> onComplete, TimeSpan?timeout = null) : base(0xffff, frame.GetRLEEncodedYCbCr(), onComplete, timeout) { _index = index; _frame = frame; }