1 /* 2 * This file is part of bino, a 3D video player. 3 * 4 * Copyright (C) 2010, 2011, 2012, 2013, 2015 5 * Martin Lambers <marlam@marlam.de> 6 * Joe <cuchac@email.cz> 7 * Binocle <http://binocle.com> (author: Olivier Letz <oletz@binocle.com>) 8 * Frédéric Bour <frederic.bour@lakaban.net> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 3 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef DISPATCH_H 25 #define DISPATCH_H 26 27 #include <string> 28 #include <sstream> 29 #include <stdint.h> 30 31 #include "base/ser.h" 32 #include "base/pth.h" 33 34 #include "media_data.h" 35 36 class gui; 37 class audio_output; 38 class video_output; 39 class media_input; 40 class player; 41 42 43 /* The open_init_data class contains everything that is needed to open 44 * a media input. */ 45 46 class open_input_data : public serializable 47 { 48 public: 49 device_request dev_request; // Request for input device settings 50 std::vector<std::string> urls; // Input media objects 51 parameters params; // Initial per-video output parameters 52 // (other parameter fields are ignored) 53 public: 54 open_input_data(); 55 56 // Serialization 57 void save(std::ostream &os) const; 58 void load(std::istream &is); 59 }; 60 61 62 /* A controller can send commands to the dispatch (e.g. "pause", "seek", 63 * "adjust colors", ...). The dispatch then reacts on this command, and sends 64 * a notification to all controllers afterwards. The controllers may react 65 * on the notification or ignore it. 66 * 67 * For example, the video output controller may notice that the user pressed the 68 * 'p' key to pause the video. So it sends the "pause" command to the dispatch. 69 * The dipatch updates its state accordingly, and notifies all controllers that 70 * the video is now paused. The video output could use this notification to display 71 * a pause symbol on screen, and the audio output controller may play a pause jingle 72 * (however, in the case of pause, both currently simply ignore the notification). 73 */ 74 75 // A command that can be sent to the dispatch by a controller. 76 77 class command 78 { 79 public: 80 enum type 81 { 82 noop, // no parameters 83 quit, // no parameters 84 // Play state 85 open, // open_input_data 86 close, // no parameters 87 toggle_play, // no parameters 88 toggle_pause, // no parameters 89 step, // no parameters 90 seek, // float (relative adjustment) 91 set_pos, // float (absolute position) 92 // Per-Session parameters 93 set_audio_device, // int 94 set_quality, // int 95 set_stereo_mode, // parameters::stereo_mode 96 set_stereo_mode_swap, // bool 97 toggle_stereo_mode_swap, // no parameters 98 set_crosstalk, // 3 floats (absolute values) 99 set_fullscreen_screens, // int 100 set_fullscreen_flip_left, // bool 101 set_fullscreen_flop_left, // bool 102 set_fullscreen_flip_right, // bool 103 set_fullscreen_flop_right, // bool 104 set_fullscreen_inhibit_screensaver, // bool 105 set_fullscreen_3d_ready_sync, // bool 106 set_contrast, // float (absolute value) 107 adjust_contrast, // float (relative adjustment) 108 set_brightness, // float (absolute value) 109 adjust_brightness, // float (relative adjustment) 110 set_hue, // float (absolute value) 111 adjust_hue, // float (relative adjustment) 112 set_saturation, // float (absolute value) 113 adjust_saturation, // float (relative adjustment) 114 set_zoom, // float (absolute value) 115 adjust_zoom, // float (relative adjustment) 116 set_loop_mode, // parameters::loop_mode_t 117 set_audio_delay, // int64_t (absolute value, in microseconds) 118 set_subtitle_encoding, // string (encoding name) 119 set_subtitle_font, // string (font name) 120 set_subtitle_size, // int 121 set_subtitle_scale, // float 122 set_subtitle_color, // uint64_t 123 set_subtitle_shadow, // int 124 #if HAVE_LIBXNVCTRL 125 set_sdi_output_format, // int 126 set_sdi_output_left_stereo_mode, // parameters::stereo_mode_t 127 set_sdi_output_right_stereo_mode, // parameters::stereo_mode_t 128 #endif // HAVE_LIBXNVCTRL 129 // Per-Video parameters 130 set_video_stream, // int 131 cycle_video_stream, // no parameters 132 set_audio_stream, // int 133 cycle_audio_stream, // no parameters 134 set_subtitle_stream, // int 135 cycle_subtitle_stream, // no parameters 136 set_stereo_layout, // video_frame::stereo_layout 137 set_stereo_layout_swap, // bool 138 set_crop_aspect_ratio, // float 139 set_source_aspect_ratio, // float 140 set_parallax, // float (absolute value) 141 adjust_parallax, // float (relative adjustment) 142 set_ghostbust, // float (absolute value) 143 adjust_ghostbust, // float (relative adjustment) 144 set_subtitle_parallax, // float (absolute value) 145 adjust_subtitle_parallax, // float (relative adjustment) 146 // Volatile parameters 147 toggle_fullscreen, // no parameters 148 center, // no parameters 149 set_audio_volume, // float (absolute value) 150 adjust_audio_volume, // float (relative adjustment) 151 toggle_audio_mute, // no parameters 152 update_display_pos, // no parameters 153 }; 154 155 type type; 156 std::string param; 157 command()158 command() : 159 type(noop) 160 { 161 } 162 command(enum type t)163 command(enum type t) : 164 type(t) 165 { 166 } 167 command(enum type t,int p)168 command(enum type t, int p) : 169 type(t) 170 { 171 std::ostringstream oss; 172 s11n::save(oss, p); 173 param = oss.str(); 174 } 175 command(enum type t,float p)176 command(enum type t, float p) : 177 type(t) 178 { 179 std::ostringstream oss; 180 s11n::save(oss, p); 181 param = oss.str(); 182 } 183 command(enum type t,int64_t p)184 command(enum type t, int64_t p) : 185 type(t) 186 { 187 std::ostringstream oss; 188 s11n::save(oss, p); 189 param = oss.str(); 190 } 191 command(enum type t,uint64_t p)192 command(enum type t, uint64_t p) : 193 type(t) 194 { 195 std::ostringstream oss; 196 s11n::save(oss, p); 197 param = oss.str(); 198 } 199 command(enum type t,const std::string & p)200 command(enum type t, const std::string &p) : 201 type(t), param(p) 202 { 203 } 204 }; 205 206 // A notification that can be sent to controllers by the dispatch. 207 // It signals that the corresponding value has changed. 208 209 class notification 210 { 211 public: 212 enum type 213 { 214 noop, 215 quit, 216 // Play state 217 open, 218 play, 219 pause, 220 pos, 221 // Per-Session parameters 222 audio_device, 223 quality, 224 stereo_mode, 225 stereo_mode_swap, 226 crosstalk, 227 fullscreen_screens, 228 fullscreen_flip_left, 229 fullscreen_flop_left, 230 fullscreen_flip_right, 231 fullscreen_flop_right, 232 fullscreen_inhibit_screensaver, 233 fullscreen_3d_ready_sync, 234 contrast, 235 brightness, 236 hue, 237 saturation, 238 zoom, 239 loop_mode, 240 audio_delay, 241 subtitle_encoding, 242 subtitle_font, 243 subtitle_size, 244 subtitle_scale, 245 subtitle_color, 246 subtitle_shadow, 247 #if HAVE_LIBXNVCTRL 248 sdi_output_format, 249 sdi_output_left_stereo_mode, 250 sdi_output_right_stereo_mode, 251 #endif // HAVE_LIBXNVCTRL 252 // Per-Video parameters 253 video_stream, 254 audio_stream, 255 subtitle_stream, 256 stereo_layout, 257 stereo_layout_swap, 258 crop_aspect_ratio, 259 source_aspect_ratio, 260 parallax, 261 ghostbust, 262 subtitle_parallax, 263 // Volatile parameters 264 fullscreen, 265 center, 266 audio_volume, 267 audio_mute, 268 display_pos, 269 }; 270 271 const enum type type; 272 273 public: notification(enum type t)274 notification(enum type t) : type(t) 275 { 276 } 277 }; 278 279 // The controller interface. 280 281 class controller 282 { 283 public: 284 controller() throw (); 285 virtual ~controller(); 286 287 /* The controller uses this function to send a command to the player. */ 288 static void send_cmd(const command& cmd); 289 // Convenience wrappers: send_cmd(enum command::type t)290 static void send_cmd(enum command::type t) { send_cmd(command(t)); } send_cmd(enum command::type t,int p)291 static void send_cmd(enum command::type t, int p) { send_cmd(command(t, p)); } send_cmd(enum command::type t,float p)292 static void send_cmd(enum command::type t, float p) { send_cmd(command(t, p)); } send_cmd(enum command::type t,int64_t p)293 static void send_cmd(enum command::type t, int64_t p) { send_cmd(command(t, p)); } send_cmd(enum command::type t,uint64_t p)294 static void send_cmd(enum command::type t, uint64_t p) { send_cmd(command(t, p)); } send_cmd(enum command::type t,const std::string & p)295 static void send_cmd(enum command::type t, const std::string& p) { send_cmd(command(t, p)); } 296 297 /* The controller receives notifications via this function. The default 298 * implementation simply ignores the notification. */ 299 virtual void receive_notification(const notification& note); 300 301 /* The controller is asked to process events via this function. The default 302 * implementation simply does nothing. */ 303 virtual void process_events(); 304 305 /* The controller can prevent Bino from exiting when there is no video 306 * to play. In this case, the following function should return 'false'. 307 * This is intended to be used for controllers that might send another 308 * 'open' command in the future. */ 309 virtual bool allow_early_quit(); 310 }; 311 312 // The dispatch (singleton). 313 314 class dispatch 315 { 316 private: 317 int* _argc; 318 char** _argv; 319 const bool _eq; 320 const bool _eq_3d; 321 const bool _eq_slave_node; 322 const bool _gui_mode; 323 const bool _have_display; 324 // Objects 325 class gui* _gui; 326 class audio_output* _audio_output; 327 class video_output* _video_output; 328 class media_input* _media_input; 329 class player* _player; 330 std::vector<controller*> _controllers; 331 unsigned int _controllers_version; 332 mutex _controllers_mutex; 333 // Parameters 334 open_input_data _input_data; 335 class parameters _parameters; 336 // State 337 bool _playing; 338 bool _pausing; 339 float _position; 340 341 void stop_player(); 342 void force_stop(bool reopen_media_input = true); 343 344 bool early_quit_is_allowed() const; 345 void visit_all_controllers(int action, const notification& note) const; 346 void notify_all(const notification& note); 347 348 public: 349 dispatch(int* argc, char** argv, 350 bool equalizer, bool equalizer_3d, bool equalizer_slave_node, 351 bool gui, bool have_display, msg::level_t log_level, 352 bool benchmark, int swap_interval) throw (); 353 virtual ~dispatch(); 354 355 void register_controller(controller* c); 356 void deregister_controller(controller* c); 357 358 void init(const open_input_data& input_data); 359 void deinit(); 360 361 static void step(); 362 363 /* Process events for all controllers */ 364 static void process_all_events(); 365 366 /* Access parameters and state (read-only) */ 367 static const class parameters& parameters(); 368 static const class audio_output* audio_output(); // NULL if not available 369 static const class video_output* video_output(); // NULL if not available 370 static const class media_input* media_input(); // NULL if no input is opened 371 static bool playing(); 372 static bool pausing(); 373 static float position(); 374 375 /* Receive a command from a controller. */ 376 void receive_cmd(const command& cmd); 377 378 /* Interface for the player. TODO: remove this! */ 379 class audio_output* get_audio_output(); // NULL if not available 380 class video_output* get_video_output(); // NULL if not available 381 class media_input* get_media_input(); // NULL if not available 382 void set_playing(bool p); 383 void set_pausing(bool p); 384 void set_position(float pos); 385 386 /* Interface for Equalizer. */ 387 class open_input_data* get_input_data(); 388 std::string save_state() const; 389 void load_state(const std::string& s); stop_eq_player()390 void stop_eq_player() { stop_player(); } 391 392 /* Helper function for text-based controllers: parse a command from a string. 393 * Return false if this fails, otherwise store the command in c. */ 394 static bool parse_command(const std::string& s, command* c); 395 }; 396 397 #endif 398