@@ -90,109 +90,208 @@ void VideoSession::set(const VideoSourceOption& option){
9090}
9191
9292void VideoSession::reset (){
93- m_logger.log (" Resetting the video..." , COLOR_GREEN);
94- dispatch_to_main_thread ([this ]{
95- std::lock_guard<std::mutex> lg0 (m_reset_lock);
93+ {
94+ WriteSpinLock lg (m_queue_lock);
95+ // cout << "VideoSession::reset(): " << m_queued_commands.size() << endl;
96+ m_queued_commands.emplace_back (
97+ Command{
98+ CommandType::RESET,
99+ nullptr ,
100+ Resolution{}
101+ }
102+ );
103+ }
104+ dispatch_to_main_thread ([this ]{ run_commands (); });
105+ }
106+ void VideoSession::set_source (
107+ const std::shared_ptr<VideoSourceDescriptor>& device,
108+ Resolution resolution
109+ ){
110+ {
111+ WriteSpinLock lg (m_queue_lock);
112+ // cout << "VideoSession::set_source(): " << m_queued_commands.size() << endl;
113+ m_queued_commands.emplace_back (
114+ Command{
115+ CommandType::SET_SOURCE,
116+ device,
117+ resolution
118+ }
119+ );
120+ }
121+ dispatch_to_main_thread ([this ]{ run_commands (); });
122+ }
123+ void VideoSession::set_resolution (Resolution resolution){
124+ {
125+ WriteSpinLock lg (m_queue_lock);
126+ // cout << "VideoSession::set_resolution(): " << m_queued_commands.size() << endl;
127+ m_queued_commands.emplace_back (
128+ Command{
129+ CommandType::SET_RESOLUTION,
130+ nullptr ,
131+ resolution
132+ }
133+ );
134+ }
135+ dispatch_to_main_thread ([this ]{ run_commands (); });
136+ }
96137
97- m_state_listeners.run_method_unique (&StateListener::pre_shutdown);
138+ void VideoSession::internal_reset (){
139+ m_logger.log (" Resetting the video..." , COLOR_GREEN);
140+ m_state_listeners.run_method_unique (&StateListener::pre_shutdown);
98141
99- {
100- WriteSpinLock lg (m_state_lock);
101- if (m_video_source){
102- m_video_source->remove_source_frame_listener (*this );
103- m_video_source->remove_rendered_frame_listener (*this );
104- m_video_source.reset ();
105- }
142+ Resolution resolution = m_option.m_resolution ;
143+ std::unique_ptr<VideoSource> source;
144+ {
145+ WriteSpinLock lg (m_state_lock);
146+ source = std::move (m_video_source);
147+ }
148+ if (source){
149+ source->remove_source_frame_listener (*this );
150+ source->remove_rendered_frame_listener (*this );
151+ source.reset ();
152+ }
106153
107- m_video_source = m_descriptor->make_VideoSource (m_logger, m_option.m_resolution );
154+ source = m_descriptor->make_VideoSource (m_logger, resolution);
155+ if (source){
156+ resolution = source->current_resolution ();
157+ source->add_source_frame_listener (*this );
158+ source->add_rendered_frame_listener (*this );
159+ }
108160
109- if (m_video_source){
110- m_option.m_resolution = m_video_source->current_resolution ();
111- m_video_source->add_source_frame_listener (*this );
112- m_video_source->add_rendered_frame_listener (*this );
113- }
114- }
161+ {
162+ WriteSpinLock lg (m_state_lock);
163+ m_option.m_resolution = resolution;
164+ m_video_source = std::move (source);
165+ }
115166
116- m_state_listeners.run_method_unique (
117- &StateListener::post_startup,
118- m_video_source.get ()
119- );
120- });
167+ m_state_listeners.run_method_unique (
168+ &StateListener::post_startup,
169+ m_video_source.get ()
170+ );
121171}
122- void VideoSession::set_source (
172+ void VideoSession::internal_set_source (
123173 const std::shared_ptr<VideoSourceDescriptor>& device,
124174 Resolution resolution
125175){
126176 m_logger.log (" Changing video..." , COLOR_GREEN);
127- dispatch_to_main_thread ([this , device, resolution]{
128- std::lock_guard<std::mutex> lg0 (m_reset_lock);
129- if (*m_descriptor == *device && !m_descriptor->should_reload ()){
130- return ;
131- }
132-
133- m_state_listeners.run_method_unique (&StateListener::pre_shutdown);
134-
135- {
136- WriteSpinLock lg (m_state_lock);
137- if (m_video_source){
138- m_video_source->remove_source_frame_listener (*this );
139- m_video_source->remove_rendered_frame_listener (*this );
140- m_video_source.reset ();
141- }
177+ if (*m_descriptor == *device && !m_descriptor->should_reload ()){
178+ return ;
179+ }
142180
143- m_option.set_descriptor (device);
144- m_descriptor = device;
181+ m_state_listeners.run_method_unique (&StateListener::pre_shutdown);
145182
146- Resolution desired_resolution = resolution ? resolution : m_option.m_resolution ;
147- // cout << "VideoSession::set_source(): " << &m_option << " - " << desired_resolution.width << " x " << desired_resolution.height << endl;
183+ std::unique_ptr<VideoSource> source;
184+ {
185+ WriteSpinLock lg (m_state_lock);
186+ source = std::move (m_video_source);
187+ }
188+ if (source){
189+ source->remove_source_frame_listener (*this );
190+ source->remove_rendered_frame_listener (*this );
191+ source.reset ();
192+ }
193+ {
194+ WriteSpinLock lg (m_state_lock);
195+ m_option.set_descriptor (device);
196+ m_descriptor = device;
197+ }
148198
149- m_video_source = device->make_VideoSource (m_logger, desired_resolution);
199+ Resolution desired_resolution = resolution ? resolution : m_option.m_resolution ;
200+ source = device->make_VideoSource (m_logger, desired_resolution);
201+ if (source){
202+ resolution = source->current_resolution ();
203+ source->add_source_frame_listener (*this );
204+ source->add_rendered_frame_listener (*this );
205+ }
150206
151- if (m_video_source){
152- m_option.m_resolution = m_video_source->current_resolution ();
153- m_video_source->add_source_frame_listener (*this );
154- m_video_source->add_rendered_frame_listener (*this );
155- }
156- }
207+ {
208+ WriteSpinLock lg (m_state_lock);
209+ m_option.m_resolution = resolution;
210+ m_video_source = std::move (source);
211+ }
157212
158- m_state_listeners.run_method_unique (
159- &StateListener::post_startup,
160- m_video_source.get ()
161- );
162- });
213+ m_state_listeners.run_method_unique (
214+ &StateListener::post_startup,
215+ m_video_source.get ()
216+ );
163217}
164- void VideoSession::set_resolution (Resolution resolution){
218+ void VideoSession::internal_set_resolution (Resolution resolution){
165219 m_logger.log (" Changing resolution..." , COLOR_GREEN);
166- dispatch_to_main_thread ([this , resolution]{
167- std::lock_guard<std::mutex> lg0 (m_reset_lock);
168- if (m_option.m_resolution == resolution){
169- return ;
170- }
220+ if (m_option.m_resolution == resolution){
221+ return ;
222+ }
223+
224+ m_state_listeners.run_method_unique (&StateListener::pre_shutdown);
225+
226+ std::unique_ptr<VideoSource> source;
227+ {
228+ WriteSpinLock lg (m_state_lock);
229+ source = std::move (m_video_source);
230+ }
231+ if (source){
232+ source->remove_source_frame_listener (*this );
233+ source->remove_rendered_frame_listener (*this );
234+ source.reset ();
235+ }
236+
237+ source = m_descriptor->make_VideoSource (m_logger, resolution);
238+ if (source){
239+ resolution = source->current_resolution ();
240+ source->add_source_frame_listener (*this );
241+ source->add_rendered_frame_listener (*this );
242+ }
243+
244+ {
245+ WriteSpinLock lg (m_state_lock);
246+ m_option.m_resolution = resolution;
247+ m_video_source = std::move (source);
248+ }
171249
172- {
173- WriteSpinLock lg (m_state_lock);
174- m_state_listeners.run_method_unique (&StateListener::pre_shutdown);
250+ m_state_listeners.run_method_unique (
251+ &StateListener::post_startup,
252+ m_video_source.get ()
253+ );
254+ }
175255
176- if (m_video_source){
177- m_video_source->remove_source_frame_listener (*this );
178- m_video_source->remove_rendered_frame_listener (*this );
179- m_video_source.reset ();
256+ void VideoSession::run_commands (){
257+ std::lock_guard<std::recursive_mutex> lg0 (m_reset_lock);
258+ if (m_recursion_depth != 0 ){
259+ m_logger.log (" Suppressing re-entrant command..." , COLOR_RED);
260+ return ;
261+ }
262+ m_recursion_depth++;
263+ try {
264+ while (true ){
265+ Command command;
266+ {
267+ WriteSpinLock lg (m_queue_lock);
268+ // cout << "VideoSession::run_commands(): " << m_queued_commands.size() << endl;
269+ if (m_queued_commands.empty ()){
270+ break ;
271+ }
272+ command = std::move (m_queued_commands.front ());
273+ m_queued_commands.pop_front ();
180274 }
181275
182- m_video_source = m_descriptor->make_VideoSource (m_logger, resolution);
276+ switch (command.command_type ){
277+ case CommandType::RESET:
278+ internal_reset ();
279+ break ;
183280
184- if (m_video_source){
185- m_option.m_resolution = m_video_source->current_resolution ();
186- m_video_source->add_source_frame_listener (*this );
187- m_video_source->add_rendered_frame_listener (*this );
281+ case CommandType::SET_SOURCE:
282+ internal_set_source (command.device , command.resolution );
283+ break ;
284+
285+ case CommandType::SET_RESOLUTION:
286+ internal_set_resolution (command.resolution );
287+ break ;
188288 }
189289 }
190-
191- m_state_listeners.run_method_unique (
192- &StateListener::post_startup,
193- m_video_source.get ()
194- );
195- });
290+ m_recursion_depth--;
291+ }catch (...){
292+ m_recursion_depth--;
293+ throw ;
294+ }
196295}
197296
198297
0 commit comments