Example #1
0
        public void TestClipSetValid()
        {
            AtemMockServerWrapper.Each(_output, _pool, SetValidCommandHandler, DeviceTestCases.MediaPlayerClips, helper =>
            {
                for (int i = 0; i < 3; i++)
                {
                    AtemState stateBefore = helper.Helper.BuildLibState();
                    uint index            = Randomiser.RangeInt((uint)stateBefore.MediaPool.Clips.Count);
                    IBMDSwitcherClip clip = GetClip(helper, index);

                    string name     = Guid.NewGuid().ToString();
                    uint frameCount = Randomiser.RangeInt(5) + 3;

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { clip.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    var clipState        = stateBefore.MediaPool.Clips[(int)index];
                    clipState.IsUsed     = true;
                    clipState.Name       = name;
                    clipState.FrameCount = frameCount;

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        clip.SetValid(name, frameCount);
                    });

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        clip.Unlock(cb);
                    });
                }
            });
        }
Example #2
0
        public void TestLockAndUnlock()
        {
            AtemMockServerWrapper.Each(_output, _pool, UploadJobWorker.LockCommandHandler, DeviceTestCases.MediaPlayerClips, helper =>
            {
                helper.DisposeSdkClient = true;

                int clipCount = helper.Helper.BuildLibState().MediaPool.Clips.Count;
                for (int index = 0; index < clipCount; index++)
                {
                    IBMDSwitcherClip clip = GetClip(helper, (uint)index);

                    AtemState stateBefore = helper.Helper.BuildLibState();

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { clip.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    helper.Helper.CheckStateChanges(stateBefore);

                    uint timeBefore = helper.Server.CurrentTime;

                    helper.SendAndWaitForChange(stateBefore, () => { clip.Unlock(cb); });

                    // It should have sent a response, but we dont expect any comparable data
                    Assert.NotEqual(timeBefore, helper.Server.CurrentTime);

                    helper.Helper.CheckStateChanges(stateBefore);
                }
            });
        }
Example #3
0
        public void TestLockAndUnlock()
        {
            AtemMockServerWrapper.Each(_output, _pool, UploadJobWorker.LockCommandHandler, DeviceTestCases.MediaPlayer, helper =>
            {
                IBMDSwitcherStills stills = GetStillsPool(helper);

                AtemState stateBefore = helper.Helper.BuildLibState();

                var cb = new LockCallback();
                helper.SendAndWaitForChange(stateBefore, () => { stills.Lock(cb); });
                Assert.True(cb.Wait.WaitOne(2000));

                helper.Helper.CheckStateChanges(stateBefore);

                uint timeBefore = helper.Server.CurrentTime;

                helper.SendAndWaitForChange(stateBefore, () =>
                {
                    stills.Unlock(cb);
                });

                // It should have sent a response, but we dont expect any comparable data
                Assert.NotEqual(timeBefore, helper.Server.CurrentTime);

                helper.Helper.CheckStateChanges(stateBefore);
            });
        }
Example #4
0
        public void TestAudioUpload()
        {
            UploadJobWorker worker = null;

            AtemMockServerWrapper.Each(_output, _pool, (a, b) => worker?.HandleCommand(a, b), DeviceTestCases.MediaPlayerClips, helper =>
            {
                helper.DisposeSdkClient = true;

                var pidCmd = helper.Server.GetParsedDataDump().OfType <ProductIdentifierCommand>().Single();

                IBMDSwitcherMediaPool pool = GetMediaPool(helper);

                for (int i = 0; i < 3; i++)
                {
                    AtemState stateBefore = helper.Helper.BuildLibState();
                    uint index            = Randomiser.RangeInt((uint)stateBefore.MediaPool.Clips.Count);
                    IBMDSwitcherClip clip = GetClip(helper, index);

                    uint sampleCount = 10000;

                    string name = Guid.NewGuid().ToString();
                    worker      = new UploadJobWorker(sampleCount * 4, _output,
                                                      index + 1, 0, DataTransferUploadRequestCommand.TransferMode.Write2, false);

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { clip.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    byte[] bytes = MediaPoolUtil.RandomFrame(sampleCount);
                    pool.CreateAudio((uint)bytes.Length, out IBMDSwitcherAudio frame);
                    MediaPoolUtil.FillSdkAudio(frame, bytes);

                    var clipState          = stateBefore.MediaPool.Clips[(int)index];
                    clipState.Audio.IsUsed = true;
                    clipState.Audio.Name   = name;

                    var uploadCb = new TransferCallback();
                    clip.AddCallback(uploadCb);
                    clip.UploadAudio(name, frame);

                    helper.HandleUntil(uploadCb.Wait, 5000);
                    Assert.True(uploadCb.Wait.WaitOne(500));
                    Assert.Equal(_BMDSwitcherMediaPoolEventType.bmdSwitcherMediaPoolEventTypeTransferCompleted,
                                 uploadCb.Result);

                    // TODO - this needs a better rule that can be properly exposed via the lib
                    byte[] flippedBytes = pidCmd.Model >= ModelId.PS4K
                        ? MediaPoolUtil.FlipAudio(bytes)
                        : bytes;
                    Assert.Equal(BitConverter.ToString(flippedBytes), BitConverter.ToString(worker.Buffer));

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        clip.Unlock(cb);
                    });
                }
            });
        }
Example #5
0
        public void WithLock(LockCallback callback)
        {
            IntPtr pixels;
            int    pitch;

            Lock(out pixels, out pitch);
            callback(pixels, pitch);
            Unlock();
        }
Example #6
0
        private void DoUpload(int iterations, int timeout, Func <uint, uint, byte[]> frameBytes)
        {
            UploadJobWorker worker = null;

            AtemMockServerWrapper.Each(_output, _pool, (a, b) => worker?.HandleCommand(a, b), DeviceTestCases.MediaPlayer, helper =>
            {
                helper.DisposeSdkClient = true;

                IBMDSwitcherMediaPool pool = GetMediaPool(helper);
                IBMDSwitcherStills stills  = GetStillsPool(helper);

                for (int i = 0; i < iterations; i++)
                {
                    AtemState stateBefore         = helper.Helper.BuildLibState();
                    Tuple <uint, uint> resolution = stateBefore.Settings.VideoMode.GetResolution().GetSize();

                    uint index  = Randomiser.RangeInt((uint)stateBefore.MediaPool.Stills.Count);
                    string name = Guid.NewGuid().ToString();
                    worker      = new UploadJobWorker(resolution.Item1 * resolution.Item2 * 4, _output,
                                                      (uint)MediaPoolFileType.Still, index, DataTransferUploadRequestCommand.TransferMode.Write);

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { stills.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    pool.CreateFrame(_BMDSwitcherPixelFormat.bmdSwitcherPixelFormat10BitYUVA, resolution.Item1,
                                     resolution.Item2, out IBMDSwitcherFrame frame);
                    byte[] bytes = frameBytes(resolution.Item1, resolution.Item2);
                    if (bytes.Length > 0)
                    {
                        MediaPoolUtil.FillSdkFrame(frame, bytes);
                    }

                    var stillState      = stateBefore.MediaPool.Stills[(int)index];
                    stillState.IsUsed   = true;
                    stillState.Filename = name;

                    var uploadCb = new TransferCallback();
                    stills.AddCallback(uploadCb);
                    stills.Upload(index, name, frame);

                    helper.HandleUntil(uploadCb.Wait, timeout);
                    Assert.True(uploadCb.Wait.WaitOne(500));
                    Assert.Equal(_BMDSwitcherMediaPoolEventType.bmdSwitcherMediaPoolEventTypeTransferCompleted,
                                 uploadCb.Result);
                    Assert.Equal(BitConverter.ToString(bytes), BitConverter.ToString(worker.Buffer));

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        stills.Unlock(cb);
                    });
                }
            });
        }
Example #7
0
        private async Task runTest(int count)
        {
            var nodes        = new WriteLock[count];
            var lockCallback = new LockCallback();

            for (int i = 0; i < count; i++)
            {
                ZooKeeper keeper = await createClient();

                WriteLock leader = new WriteLock(keeper, "/test", null);
                leader.setLockListener(lockCallback);
                nodes[i] = leader;

                await leader.Lock();
            }

            // lets wait for any previous leaders to die and one of our new
            // nodes to become the new leader
            Assert.assertTrue(await lockCallback.TaskCompletionSource.Task.WithTimeout(30 * 1000));

            WriteLock first = nodes[0];

            dumpNodes(nodes, count);

            // lets assert that the first election is the leader
            Assert.assertTrue("The first znode should be the leader " + first.Id, first.Owner);

            for (int i = 1; i < count; i++)
            {
                WriteLock node = nodes[i];
                Assert.assertFalse("Node should not be the leader " + node.Id, node.Owner);
            }

            if (count > 1)
            {
                LOG.debug("Now killing the leader");
                // now lets kill the leader
                lockCallback.TaskCompletionSource = new TaskCompletionSource <bool>();
                await first.unlock();

                Assert.assertTrue(await lockCallback.TaskCompletionSource.Task.WithTimeout(30 * 1000));
                WriteLock second = nodes[1];
                dumpNodes(nodes, count);
                // lets assert that the first election is the leader
                Assert.assertTrue("The second znode should be the leader " + second.Id, second.Owner);

                for (int i = 2; i < count; i++)
                {
                    WriteLock node = nodes[i];
                    Assert.assertFalse("Node should not be the leader " + node.Id, node.Owner);
                }
            }
        }
Example #8
0
 private void Lock(Control target, bool enable)
 {
     if (this.InvokeRequired)
     {
         LockCallback lockCallback = new LockCallback(Lock);
         this.Invoke(lockCallback, target, enable);
     }
     else
     {
         target.Enabled = enable;
     }
 }
Example #9
0
        public void TestClipFrameUpload()
        {
            UploadJobWorker worker = null;

            AtemMockServerWrapper.Each(_output, _pool, (a, b) => worker?.HandleCommand(a, b), DeviceTestCases.MediaPlayerClips, helper =>
            {
                helper.DisposeSdkClient = true;

                IBMDSwitcherMediaPool pool = GetMediaPool(helper);

                for (int i = 0; i < 3; i++)
                {
                    AtemState stateBefore         = helper.Helper.BuildLibState();
                    Tuple <uint, uint> resolution = stateBefore.Settings.VideoMode.GetResolution().GetSize();
                    uint index            = Randomiser.RangeInt((uint)stateBefore.MediaPool.Clips.Count);
                    uint frameIndex       = Randomiser.RangeInt(stateBefore.MediaPool.Clips[(int)index].MaxFrames);
                    IBMDSwitcherClip clip = GetClip(helper, index);

                    worker = new UploadJobWorker(resolution.Item1 * resolution.Item2 * 4, _output,
                                                 index + 1, frameIndex, DataTransferUploadRequestCommand.TransferMode.Write);

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { clip.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    pool.CreateFrame(_BMDSwitcherPixelFormat.bmdSwitcherPixelFormat10BitYUVA, resolution.Item1,
                                     resolution.Item2, out IBMDSwitcherFrame frame);
                    byte[] bytes = MediaPoolUtil.SolidColour(resolution.Item1 * resolution.Item2, 100, 0, 0, 255);
                    MediaPoolUtil.FillSdkFrame(frame, bytes);

                    var clipState = stateBefore.MediaPool.Clips[(int)index];
                    clipState.Frames[(int)frameIndex].IsUsed = true;
                    //clipState.Audio.Name = name;

                    var uploadCb = new TransferCallback();
                    clip.AddCallback(uploadCb);
                    clip.UploadFrame(frameIndex, frame);

                    helper.HandleUntil(uploadCb.Wait, 5000);
                    Assert.True(uploadCb.Wait.WaitOne(500));
                    Assert.Equal(_BMDSwitcherMediaPoolEventType.bmdSwitcherMediaPoolEventTypeTransferCompleted,
                                 uploadCb.Result);
                    Assert.Equal(BitConverter.ToString(bytes), BitConverter.ToString(worker.Buffer));

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        clip.Unlock(cb);
                    });
                }
            });
        }
Example #10
0
        public void TestAbortingAudioUpload()
        {
            AbortedUploadJobWorker worker = null;

            AtemMockServerWrapper.Each(_output, _pool, (a, b) => worker?.HandleCommand(a, b), DeviceTestCases.MediaPlayerClips, helper =>
            {
                helper.DisposeSdkClient = true;

                IBMDSwitcherMediaPool pool = GetMediaPool(helper);

                for (int i = 0; i < 3; i++)
                {
                    AtemState stateBefore = helper.Helper.BuildLibState();
                    uint index            = Randomiser.RangeInt((uint)stateBefore.MediaPool.Clips.Count);
                    IBMDSwitcherClip clip = GetClip(helper, index);

                    uint sampleCount = 10000;

                    string name = Guid.NewGuid().ToString();
                    worker      = new AbortedUploadJobWorker(_output);

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { clip.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    byte[] bytes = MediaPoolUtil.RandomFrame(sampleCount);
                    pool.CreateAudio((uint)bytes.Length, out IBMDSwitcherAudio frame);
                    MediaPoolUtil.FillSdkAudio(frame, bytes);

                    var uploadCb = new TransferCallback();
                    clip.AddCallback(uploadCb);
                    clip.UploadAudio(name, frame);

                    // Short bit of work before the abort
                    helper.HandleUntil(uploadCb.Wait, 1000);
                    clip.CancelTransfer();

                    helper.HandleUntil(uploadCb.Wait, 1000);
                    Assert.True(uploadCb.Wait.WaitOne(500));
                    Assert.Equal(_BMDSwitcherMediaPoolEventType.bmdSwitcherMediaPoolEventTypeTransferCancelled,
                                 uploadCb.Result);

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        clip.Unlock(cb);
                    });
                }
            });
        }
Example #11
0
        static public void SyncStart(string message, LockCallback callback, object state)
        {
            if (SyncLockedGUIForm == null)
            {
                SyncLockedGUIForm = new FreeCL.Forms.LockedGuiForm();
                SyncLockedGUIForm.Init();
            }
            SyncLockedGUIForm.savedCallBack     = callback;
            SyncLockedGUIForm.savedState        = state;
            SyncLockedGUIForm.tCallback.Enabled = true;

            SyncLockedGUIForm.StartWaiting(message);

            Application.DoEvents();
        }
Example #12
0
        public void TestAbortingStillUpload()
        {
            AbortedUploadJobWorker worker = null;

            AtemMockServerWrapper.Each(_output, _pool, (a, b) => worker?.HandleCommand(a, b), DeviceTestCases.MediaPlayerStillTransfer, helper =>
            {
                helper.DisposeSdkClient = true;

                IBMDSwitcherMediaPool pool = GetMediaPool(helper);
                IBMDSwitcherStills stills  = GetStillsPool(helper);

                for (int i = 0; i < 3; i++)
                {
                    AtemState stateBefore         = helper.Helper.BuildLibState();
                    Tuple <uint, uint> resolution = stateBefore.Settings.VideoMode.GetResolution().GetSize();

                    uint index  = Randomiser.RangeInt((uint)stateBefore.MediaPool.Stills.Count);
                    string name = Guid.NewGuid().ToString();
                    worker      = new AbortedUploadJobWorker(_output);

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { stills.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    pool.CreateFrame(_BMDSwitcherPixelFormat.bmdSwitcherPixelFormat10BitYUVA, resolution.Item1,
                                     resolution.Item2, out IBMDSwitcherFrame frame);
                    MediaPoolUtil.FillSdkFrame(frame, MediaPoolUtil.RandomFrame(resolution.Item1 * resolution.Item2));

                    var uploadCb = new TransferCallback();
                    stills.AddCallback(uploadCb);
                    stills.Upload(index, name, frame);

                    // Short bit of work before the abort
                    helper.HandleUntil(uploadCb.Wait, 1000);
                    stills.CancelTransfer();

                    helper.HandleUntil(uploadCb.Wait, 1000);
                    Assert.True(uploadCb.Wait.WaitOne(500));
                    Assert.Equal(_BMDSwitcherMediaPoolEventType.bmdSwitcherMediaPoolEventTypeTransferCancelled,
                                 uploadCb.Result);

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        stills.Unlock(cb);
                    });
                }
            });
        }
Example #13
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="handle"></param>
 /// <returns></returns>
 public bool TryEnterLock(LockCallback handle)
 {
     using (var l = Lock())
     {
         if (l != null && l.TryEnterLock())
         {
             if (handle != null)
             {
                 handle();
             }
         }
         else
         {
             TraceLog.WriteError("Monitor lock timeout:{0}", _timeOut);
         }
         return l != null && l.IsLocked;
     }
 }
Example #14
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="handle"></param>
 /// <returns></returns>
 public bool TryEnterLock(LockCallback handle)
 {
     using (var l = Lock())
     {
         if (l != null && l.TryEnterLock())
         {
             if (handle != null)
             {
                 handle();
             }
         }
         else
         {
             TraceLog.WriteError("Monitor lock timeout:{0}", _timeOut);
         }
         return(l != null && l.IsLocked);
     }
 }
Example #15
0
        public void SyncLock(string message, LockCallback callback, object state)
        {
            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            locked = true;
            if (FreeCL.UI.Application.MainForm != null)
            {
                FreeCL.Forms.LockedGuiForm.SyncStart(
                    message,
                    new FreeCL.Forms.LockCallback(SyncLockCallback),
                    new LockCallbackData(callback, state));
            }
            else
            {
                callback(state);
            }
            locked = false;
        }
Example #16
0
        public static void SyncStart(string message, LockCallback callback, object state)
        {
            if(SyncLockedGUIForm == null)
            {
                SyncLockedGUIForm = new FreeCL.Forms.LockedGuiForm();
                SyncLockedGUIForm.Init();
            }
            SyncLockedGUIForm.savedCallBack = callback;
            SyncLockedGUIForm.savedState = state;
            SyncLockedGUIForm.tCallback.Enabled = true;

            SyncLockedGUIForm.StartWaiting(message);

            Application.DoEvents();
        }
Example #17
0
        public void TestClipFrameDownload()
        {
            DownloadJobWorker worker = null;

            AtemMockServerWrapper.Each(_output, _pool, (a, b) => worker?.HandleCommand(a, b), DeviceTestCases.MediaPlayerClips, helper =>
            {
                helper.DisposeSdkClient = true;

                IBMDSwitcherMediaPool pool = GetMediaPool(helper);

                for (int i = 0; i < 3; i++)
                {
                    AtemState stateBefore         = helper.Helper.BuildLibState();
                    Tuple <uint, uint> resolution = stateBefore.Settings.VideoMode.GetResolution().GetSize();
                    uint index            = Randomiser.RangeInt((uint)stateBefore.MediaPool.Clips.Count);
                    uint frameIndex       = Randomiser.RangeInt(stateBefore.MediaPool.Clips[(int)index].MaxFrames);
                    IBMDSwitcherClip clip = GetClip(helper, index);

                    {
                        var frameState    = stateBefore.MediaPool.Clips[(int)index].Frames[(int)frameIndex];
                        frameState.IsUsed = true;
                        frameState.Hash   = new byte[16];
                        helper.SendFromServerAndWaitForChange(stateBefore, new MediaPoolFrameDescriptionCommand
                        {
                            Bank     = (MediaPoolFileType)index + 1,
                            Filename = "",
                            Index    = frameIndex,
                            IsUsed   = true
                        });
                    }
                    stateBefore = helper.Helper.BuildLibState();

                    byte[] bytes = new byte[resolution.Item1 * resolution.Item2 * 4];
                    worker       = new DownloadJobWorker(_output, index + 1, frameIndex, FrameEncodingUtil.EncodeRLE(bytes));

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { clip.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    var downloadCb = new TransferCallback();
                    clip.AddCallback(downloadCb);
                    clip.DownloadFrame(frameIndex);

                    helper.HandleUntil(downloadCb.Wait, 5000);
                    Assert.True(downloadCb.Wait.WaitOne(500));

                    Assert.Equal(_BMDSwitcherMediaPoolEventType.bmdSwitcherMediaPoolEventTypeTransferCompleted,
                                 downloadCb.Result);
                    Assert.NotNull(downloadCb.Frame);
                    Assert.Null(downloadCb.Audio);

                    byte[] sdkBytes = MediaPoolUtil.GetSdkFrameBytes(downloadCb.Frame);
                    Assert.Equal(BitConverter.ToString(bytes), BitConverter.ToString(sdkBytes));

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        clip.Unlock(cb);
                    });
                }
            });
        }
Example #18
0
        private void DoDownload(int iterations, int timeout, Func <uint, uint, Tuple <byte[], byte[]> > rawBytesGen)
        {
            DownloadJobWorker worker = null;

            AtemMockServerWrapper.Each(_output, _pool, (a, b) => worker?.HandleCommand(a, b), DeviceTestCases.MediaPlayerStillTransfer, helper =>
            {
                helper.DisposeSdkClient = true;

                IBMDSwitcherStills stills = GetStillsPool(helper);

                for (int i = 0; i < iterations; i++)
                {
                    AtemState stateBefore         = helper.Helper.BuildLibState();
                    Tuple <uint, uint> resolution = stateBefore.Settings.VideoMode.GetResolution().GetSize();

                    uint index = Randomiser.RangeInt((uint)stateBefore.MediaPool.Stills.Count);

                    {
                        var stillState      = stateBefore.MediaPool.Stills[(int)index];
                        stillState.Filename = "Some file";
                        stillState.IsUsed   = true;
                        stillState.Hash     = new byte[16];
                        helper.SendFromServerAndWaitForChange(stateBefore, new MediaPoolFrameDescriptionCommand
                        {
                            Bank     = MediaPoolFileType.Still,
                            Filename = "Some file",
                            Index    = index,
                            IsUsed   = true
                        });
                    }
                    stateBefore = helper.Helper.BuildLibState();

                    Tuple <byte[], byte[]> rawBytes = rawBytesGen(resolution.Item1, resolution.Item2);
                    worker = new DownloadJobWorker(_output, (uint)MediaPoolFileType.Still, index,
                                                   rawBytes.Item2);

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { stills.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    var downloadCb = new TransferCallback();
                    stills.AddCallback(downloadCb);
                    stills.Download(index);

                    helper.HandleUntil(downloadCb.Wait, timeout);
                    Assert.True(downloadCb.Wait.WaitOne(500));
                    Assert.Equal(_BMDSwitcherMediaPoolEventType.bmdSwitcherMediaPoolEventTypeTransferCompleted,
                                 downloadCb.Result);

                    Assert.NotNull(downloadCb.Frame);
                    Assert.Equal(_BMDSwitcherPixelFormat.bmdSwitcherPixelFormat10BitYUVA,
                                 downloadCb.Frame.GetPixelFormat());
                    Assert.Equal(resolution.Item1, (uint)downloadCb.Frame.GetWidth());
                    Assert.Equal(resolution.Item2, (uint)downloadCb.Frame.GetHeight());
                    byte[] sdkBytes = MediaPoolUtil.GetSdkFrameBytes(downloadCb.Frame);
                    Assert.Equal(BitConverter.ToString(rawBytes.Item1), BitConverter.ToString(sdkBytes));

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        stills.Unlock(cb);
                    });
                }
            });
        }
Example #19
0
 public LockCallbackData(LockCallback callBack, object state)
 {
     Callback = callBack;
     State    = state;
 }
Example #20
0
        public void TestAudioDownload()
        {
            DownloadJobWorker worker = null;

            AtemMockServerWrapper.Each(_output, _pool, (a, b) => worker?.HandleCommand(a, b), DeviceTestCases.MediaPlayerClips, helper =>
            {
                helper.DisposeSdkClient = true;

                var pidCmd = helper.Server.GetParsedDataDump().OfType <ProductIdentifierCommand>().Single();

                for (int i = 0; i < 3; i++)
                {
                    AtemState stateBefore = helper.Helper.BuildLibState();
                    uint index            = Randomiser.RangeInt((uint)stateBefore.MediaPool.Clips.Count);
                    IBMDSwitcherClip clip = GetClip(helper, index);

                    uint sampleCount = 10000;

                    {
                        var clipState          = stateBefore.MediaPool.Clips[(int)index];
                        clipState.Audio.Name   = "Some file";
                        clipState.Audio.IsUsed = true;
                        clipState.Audio.Hash   = new byte[16];
                        helper.SendFromServerAndWaitForChange(stateBefore, new MediaPoolAudioDescriptionCommand
                        {
                            Name   = "Some file",
                            Index  = index + 1,
                            IsUsed = true
                        });
                    }
                    stateBefore = helper.Helper.BuildLibState();

                    var bytes = MediaPoolUtil.RandomFrame(sampleCount);
                    worker    = new DownloadJobWorker(_output, index + 1, 0, bytes);

                    var cb = new LockCallback();
                    helper.SendAndWaitForChange(stateBefore, () => { clip.Lock(cb); });
                    Assert.True(cb.Wait.WaitOne(2000));

                    var downloadCb = new TransferCallback();
                    clip.AddCallback(downloadCb);
                    clip.DownloadAudio();

                    helper.HandleUntil(downloadCb.Wait, 5000);
                    Assert.True(downloadCb.Wait.WaitOne(500));
                    Assert.Equal(_BMDSwitcherMediaPoolEventType.bmdSwitcherMediaPoolEventTypeTransferCompleted,
                                 downloadCb.Result);

                    Assert.Null(downloadCb.Frame);
                    Assert.NotNull(downloadCb.Audio);
                    Assert.Equal((int)(sampleCount * 4), downloadCb.Audio.GetSize());
                    byte[] sdkBytes = MediaPoolUtil.GetSdkAudioBytes(downloadCb.Audio);

                    // TODO - this needs a better rule that can be properly exposed via the lib
                    byte[] flippedBytes = pidCmd.Model >= ModelId.PS4K
                        ? MediaPoolUtil.FlipAudio(bytes)
                        : bytes;
                    Assert.Equal(BitConverter.ToString(flippedBytes), BitConverter.ToString(sdkBytes));

                    helper.SendAndWaitForChange(stateBefore, () =>
                    {
                        clip.Unlock(cb);
                    });
                }
            });
        }
 public bool TryExecute(string key, int timeoutMs, LockCallback success)
 {
     return(TryExecuteAsync(key, timeoutMs, delegate() { success();  return Task.FromResult(false); }).Result);
 }
Example #22
0
        public void SyncLock(string message, LockCallback callback, object state)
        {
            if(callback == null)
                throw new ArgumentNullException("callback");

            locked = true;
            if(FreeCL.UI.Application.MainForm != null)
            {
                FreeCL.Forms.LockedGuiForm.SyncStart(
                    message,
                    new FreeCL.Forms.LockCallback(SyncLockCallback),
                    new LockCallbackData(callback, state));
            }
            else
            {
                callback(state);
            }
            locked = false;
        }
Example #23
0
        /// <summary>
        /// Attempts to execute the 'success' callback inside a lock based on 'key'.  If successful, returns true.
        /// If the lock cannot be acquired within 'timoutMs', returns false
        /// In a worst-case scenario, it could take up to twice as long as 'timeoutMs' to return false.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="success"></param>
        /// <param name="failure"></param>
        /// <param name="timeoutMs"></param>
        public bool TryExecute(string key, int timeoutMs, LockCallback success)
        {
            //Record when we started. We don't want an infinite loop.
            DateTime startedAt = DateTime.UtcNow;

            // Tracks whether the lock acquired is still correct
            bool validLock = true;
            // The lock corresponding to 'key'
            object itemLock = null;

            try {
                //We have to loop until we get a valid lock and it stays valid until we lock it.
                do
                {
                    // 1) Creation/aquire phase
                    lock (createLock) {
                        // We have to lock on dictionary writes, since otherwise
                        // two locks for the same file could be created and assigned
                        // at the same time. (i.e, between TryGetValue and the assignment)
                        if (!locks.TryGetValue(key, out itemLock))
                        {
                            locks[key] = itemLock = new Object(); //make a new lock!
                        }
                    }
                    // Loophole (part 1):
                    // Right here - this is where another thread (executing part 2) could remove 'itemLock'
                    // from the dictionary, and potentially, yet another thread could
                    // insert a new value for 'itemLock' into the dictionary... etc, etc..

                    // 2) Execute phase
                    if (System.Threading.Monitor.TryEnter(itemLock, timeoutMs))
                    {
                        try {
                            // May take minutes to acquire this lock.

                            // Trying to detect an occurence of loophole above
                            // Check that itemLock still exists and matches the dictionary
                            lock (createLock) {
                                object newLock = null;
                                validLock = locks.TryGetValue(key, out newLock);
                                validLock = validLock && newLock == itemLock;
                            }
                            // Only run the callback if the lock is valid
                            if (validLock)
                            {
                                success(); // Extremely long-running callback, perhaps throwing exceptions
                                return(true);
                            }
                        } finally {
                            System.Threading.Monitor.Exit(itemLock);//release lock
                        }
                    }
                    else
                    {
                        validLock = false; //So the finally clause doesn't try to clean up the lock, someone else will do that.
                        return(false);     //Someone else had the lock, they can clean it up.
                    }

                    //Are we out of time, still having an invalid lock?
                    if (!validLock && Math.Abs(DateTime.UtcNow.Subtract(startedAt).TotalMilliseconds) > timeoutMs)
                    {
                        //We failed to get a valid lock in time.
                        return(false);
                    }


                    // If we had an invalid lock, we have to try everything over again.
                } while (!validLock);
            } finally {
                if (validLock)
                {
                    // Loophole (part 2). When loophole part 1 and 2 cross paths,
                    // An lock object may be removed before being used, and be orphaned

                    // 3) Cleanup phase - Attempt cleanup of lock objects so we don't
                    //   have a *very* large and slow dictionary.
                    lock (createLock) {
                        //  TryEnter() fails instead of waiting.
                        //  A normal lock would cause a deadlock with phase 2.
                        //  Specifying a timeout would add great and pointless overhead.
                        //  Whoever has the lock will clean it up also.
                        if (System.Threading.Monitor.TryEnter(itemLock))
                        {
                            try {
                                // It succeeds, so no-one else is working on it
                                // (but may be preparing to, see loophole)
                                // Only remove the lock object if it
                                // still exists in the dictionary as-is
                                object existingLock = null;
                                if (locks.TryGetValue(key, out existingLock) &&
                                    existingLock == itemLock)
                                {
                                    locks.Remove(key);
                                }
                            } finally {
                                // Remove the lock
                                System.Threading.Monitor.Exit(itemLock);
                            }
                        }
                    }
                }
            }
            // Ideally the only objects in 'locks' will be open operations now.
            return(true);
        }
Example #24
0
 public LockCallbackData(LockCallback callBack, object state)
 {
     Callback = callBack;
     State = state;
 }
Example #25
0
        /// <summary>
        /// Attempts to execute the 'success' callback inside a lock based on 'key'.  If successful, returns true.
        /// If the lock cannot be acquired within 'timoutMs', returns false
        /// In a worst-case scenario, it could take up to twice as long as 'timeoutMs' to return false.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="success"></param>
        /// <param name="failure"></param>
        /// <param name="timeoutMs"></param>
        public bool TryExecute(string key, int timeoutMs, LockCallback success)
        {
            //Record when we started. We don't want an infinite loop.
            DateTime startedAt = DateTime.UtcNow;

            // Tracks whether the lock acquired is still correct
            bool validLock = true;
            // The lock corresponding to 'key'
            object itemLock = null;

            try {
                //We have to loop until we get a valid lock and it stays valid until we lock it.
                do {
                    // 1) Creation/aquire phase
                    lock (createLock) {
                        // We have to lock on dictionary writes, since otherwise
                        // two locks for the same file could be created and assigned
                        // at the same time. (i.e, between TryGetValue and the assignment)
                        if (!locks.TryGetValue(key, out itemLock))
                            locks[key] = itemLock = new Object(); //make a new lock!

                    }
                    // Loophole (part 1):
                    // Right here - this is where another thread (executing part 2) could remove 'itemLock'
                    // from the dictionary, and potentially, yet another thread could
                    // insert a new value for 'itemLock' into the dictionary... etc, etc..

                    // 2) Execute phase
                    if (System.Threading.Monitor.TryEnter(itemLock, timeoutMs)) {
                        try {
                            // May take minutes to acquire this lock.

                            // Trying to detect an occurence of loophole above
                            // Check that itemLock still exists and matches the dictionary
                            lock (createLock) {
                                object newLock = null;
                                validLock = locks.TryGetValue(key, out newLock);
                                validLock = validLock && newLock == itemLock;
                            }
                            // Only run the callback if the lock is valid
                            if (validLock) {
                                success(); // Extremely long-running callback, perhaps throwing exceptions
                                return true;
                            }

                        } finally {
                            System.Threading.Monitor.Exit(itemLock);//release lock
                        }
                    } else {
                        validLock = false; //So the finally clause doesn't try to clean up the lock, someone else will do that.
                        return false; //Someone else had the lock, they can clean it up.
                    }

                    //Are we out of time, still having an invalid lock?
                    if (!validLock && Math.Abs(DateTime.UtcNow.Subtract(startedAt).TotalMilliseconds) > timeoutMs) {
                        //We failed to get a valid lock in time.
                        return false;
                    }

                    // If we had an invalid lock, we have to try everything over again.
                } while (!validLock);
            } finally {
                if (validLock) {
                    // Loophole (part 2). When loophole part 1 and 2 cross paths,
                    // An lock object may be removed before being used, and be orphaned

                    // 3) Cleanup phase - Attempt cleanup of lock objects so we don't
                    //   have a *very* large and slow dictionary.
                    lock (createLock) {
                        //  TryEnter() fails instead of waiting.
                        //  A normal lock would cause a deadlock with phase 2.
                        //  Specifying a timeout would add great and pointless overhead.
                        //  Whoever has the lock will clean it up also.
                        if (System.Threading.Monitor.TryEnter(itemLock)) {
                            try {
                                // It succeeds, so no-one else is working on it
                                // (but may be preparing to, see loophole)
                                // Only remove the lock object if it
                                // still exists in the dictionary as-is
                                object existingLock = null;
                                if (locks.TryGetValue(key, out existingLock)
                                    && existingLock == itemLock)
                                    locks.Remove(key);
                            } finally {
                                // Remove the lock
                                System.Threading.Monitor.Exit(itemLock);
                            }
                        }
                    }
                }
            }
            // Ideally the only objects in 'locks' will be open operations now.
            return true;
        }