protected void MultipleStreamTestReduced(MediaConfigurationChangeLog changeLog, GetStreamSetup getStreamSetup) { //3. ONVIF Client will invoke GetVideoSourceConfigurationsRequest message to retrieve // all DUT video source configurations. //4. Verify the GetVideoSourceConfigurationsResponse message from the DUT. VideoSourceConfiguration[] sourceConfigurations = GetVideoSourceConfigurations(); CheckConfigurationsList(sourceConfigurations, "Video Source Configuration"); List <VideoSourceConfiguration> selectedConfigs = MediaTestUtils.SelectConfigurations(sourceConfigurations); foreach (VideoSourceConfiguration config in selectedConfigs) { //5. ONVIF Client will invoke GetGuaranteedNumberOfVideoEncoderInstancesRequest message // (ConfigurationToken = “VSCToken1”, where “VSCToken1” is a first video source configuration // token from GetVideoSourceConfigurationsResponse message) to retrieve guaranteed number of // video encoder instances per first video source configuration. int?jpeg; int?mpeg; int?h264; int totalNumber = GetGuaranteedNumberOfVideoEncoderInstances(config.token, out jpeg, out h264, out mpeg); //6. Verify the GetGuaranteedNumberOfVideoEncoderInstancesResponse message from the DUT. //7. Create or find number of profiles equal to TotalNumber from // GetGuaranteedNumberOfVideoEncoderInstancesResponse message that contains video source // configuration with token “VSCToken1” and video encoder configuration (see Annex A.9). List <Profile> profiles = GetProfilesForMultiStreamingTest(config.token, totalNumber, jpeg, mpeg, h264, changeLog); Assert(profiles.Count == totalNumber, "Required number of profiles could not be found or created", "Check that required number of profiles has been achieved"); SetResourcesUsageToMimimal(changeLog, profiles); //8. ONVIF Client invokes GetStreamUriRequest message (Profile Token, RTP-Unicast, // UDP transport) to retrieve media stream URI for the first media profile from step 7. //9. DUT sends RTSP URI and parameters defining the lifetime of the URI like // ValidUntilConnect, ValidUntilReboot and Timeout in the GetStreamUriResponse message. //10. ONVIF Client verifies the RTSP media stream URI provided by the DUT. //11. ONVIF Client invokes RTSP DESCRIBE request. //12. DUT sends 200 OK message and SDP information. //13. ONVIF Client invokes RTSP SETUP request with transport parameter as RTP/UDP. //14. DUT sends 200 OK message and the media stream information. //15. ONVIF Client invokes RTSP PLAY request. //16. DUT sends 200 OK message and starts media streaming. //17. DUT sends JPEG RTP media stream to ONVIF Client over UDP. //18. DUT sends RTCP sender report to ONVIF Client. //19. DUT validates the received RTP and RTCP packets, decodes and renders them. //20. Repeat steps 8-20 to start video streaming for all profiles from step 7. //21. ONVIF Client invokes RTSP TEARDOWN control request at the end of media streaming // to terminate the RTSP session for each started stream. //22. DUT sends 200 OK Response and terminates the RTSP Session. VideoUtils.ShowMultiple( this, _semaphore.StopEvent, _username, _password, _messageTimeout, getStreamSetup, _videoForm.NICIndex, profiles, GetStreamUri, (a, name, failTest) => RunStep2(a, name, failTest), (ex) => StepFailed(ex)); //23. Repeat steps 5-23 for the rest of video source configurations. } }
public static void ShowMultiple( IVideoFormEvent eventConsumer, WaitHandle stopEvent, string username, string password, int timeout, GetStreamSetup getStreamSetup, int NICIndex, List <Profile> profiles, Func <StreamSetup, string, MediaUri> getStreamUri, Action <Action, string, bool> runStep, Action <Exception> stepFailed) { List <VideoStreamForm> streams = new List <VideoStreamForm>(); List <WaitHandle> eventsWorkEnded = new List <WaitHandle>(); timeout = Math.Max(timeout, 2000 * profiles.Count()); WaitHandle signalCloseWindow = new AutoResetEvent(false); foreach (Profile profile in profiles) { Profile currentProfile = profile; StreamSetup streamSetup = getStreamSetup(ref currentProfile); if (currentProfile == null) { continue; } VideoStreamForm vsf = new VideoStreamForm(); vsf.streamSetup = streamSetup; vsf.profile = currentProfile; vsf.getStreamUri = getStreamUri; vsf.messageTimeout = timeout; vsf.username = username; vsf.password = password; vsf.signalCloseWindow = signalCloseWindow; vsf.eventConsumer = eventConsumer; vsf.NICIndex = NICIndex; streams.Add(vsf); eventsWorkEnded.Add(vsf.eventWorkEnded); } if (0 == streams.Count) { return; } bool timeoutException = false; try { VideoStreamForm vsfFailed = null; foreach (VideoStreamForm vsf in streams) { ((ManualResetEvent)vsf.eventWorkEnded).Reset(); vsf.thread.Start(vsf); if (0 == WaitHandle.WaitAny(new WaitHandle[] { stopEvent, vsf.eventOpened, vsf.eventWorkEnded })) { throw new StopEventException(); } if (vsf.exception != null) { stepFailed(vsf.exception); vsfFailed = vsf; break; } } foreach (VideoStreamForm vsf in streams) { if (vsf.thread.ThreadState != ThreadState.Unstarted && vsf != vsfFailed) { vsf.skipLog = true; } } ((AutoResetEvent)signalCloseWindow).Set(); runStep(() => { if (!WaitHandle.WaitAll(eventsWorkEnded.ToArray(), timeout)) { ((AutoResetEvent)signalCloseWindow).Reset(); timeoutException = true; throw new VideoException("Waiting timeout exceeded"); } }, "Closing streams", false); if (timeoutException) { throw new VideoException("Waiting timeout exceeded"); } } // handle halt catch (Exception ex) { runStep(() => { foreach (VideoStreamForm vsf in streams) { if (vsf.thread.ThreadState != ThreadState.Unstarted) { vsf.thread.Abort(); vsf.thread.Join(); } } }, "Cleanup", true); if (!timeoutException) { throw ex; } } runStep(() => { // check for exceptions if (timeoutException) { throw new VideoException("Closing streams failed!"); } foreach (VideoStreamForm vsf in streams) { vsf.thread.Join(); if (vsf.exception != null) { throw new VideoException("Profile " + vsf.profile.Name + " failed!"); } } }, "Check for test results", true); }