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 <joe@wpj.cz>
7 * D. Matz <bandregent@yahoo.de>
8 * Binocle <http://binocle.com> (author: Olivier Letz <oletz@binocle.com>)
9 * Frédéric Bour <frederic.bour@lakaban.net>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "config.h"
26
27 #include <limits>
28 #include <cstring>
29 #include <cmath>
30
31 #include "media_data.h"
32
33 #include "base/str.h"
34 #include "base/msg.h"
35 #include "base/dbg.h"
36
37 #include "base/gettext.h"
38 #define _(string) gettext(string)
39
40 #if HAVE_LIBXNVCTRL
41 # include <NVCtrl/NVCtrl.h>
42 #endif // HAVE_LIBXNVCTRL
43
44
device_request()45 device_request::device_request() :
46 device(no_device),
47 width(0),
48 height(0),
49 frame_rate_num(0),
50 frame_rate_den(0),
51 request_mjpeg(false)
52 {
53 }
54
save(std::ostream & os) const55 void device_request::save(std::ostream &os) const
56 {
57 s11n::save(os, static_cast<int>(device));
58 s11n::save(os, width);
59 s11n::save(os, height);
60 s11n::save(os, frame_rate_num);
61 s11n::save(os, frame_rate_den);
62 s11n::save(os, request_mjpeg);
63 }
64
load(std::istream & is)65 void device_request::load(std::istream &is)
66 {
67 int x;
68 s11n::load(is, x);
69 device = static_cast<device_t>(x);
70 s11n::load(is, width);
71 s11n::load(is, height);
72 s11n::load(is, frame_rate_num);
73 s11n::load(is, frame_rate_den);
74 s11n::load(is, request_mjpeg);
75 }
76
77
parameters()78 parameters::parameters()
79 {
80 // Invariant parameters
81 unset_log_level();
82 unset_benchmark();
83 unset_swap_interval();
84 // Per-Session parameters
85 unset_audio_device();
86 unset_quality();
87 unset_stereo_mode();
88 unset_stereo_mode_swap();
89 unset_crosstalk_r();
90 unset_crosstalk_g();
91 unset_crosstalk_b();
92 unset_fullscreen_screens();
93 unset_fullscreen_flip_left();
94 unset_fullscreen_flop_left();
95 unset_fullscreen_flip_right();
96 unset_fullscreen_flop_right();
97 unset_fullscreen_inhibit_screensaver();
98 unset_fullscreen_3d_ready_sync();
99 unset_contrast();
100 unset_brightness();
101 unset_hue();
102 unset_saturation();
103 unset_zoom();
104 unset_loop_mode();
105 unset_audio_delay();
106 unset_subtitle_encoding();
107 unset_subtitle_font();
108 unset_subtitle_size();
109 unset_subtitle_scale();
110 unset_subtitle_color();
111 unset_subtitle_shadow();
112 #if HAVE_LIBXNVCTRL
113 unset_sdi_output_format();
114 unset_sdi_output_left_stereo_mode();
115 unset_sdi_output_right_stereo_mode();
116 #endif // HAVE_LIBXNVCTRL
117 // Per-Video parameters
118 unset_video_stream();
119 unset_audio_stream();
120 unset_subtitle_stream();
121 unset_stereo_layout();
122 unset_stereo_layout_swap();
123 unset_crop_aspect_ratio();
124 unset_source_aspect_ratio();
125 unset_parallax();
126 unset_ghostbust();
127 unset_subtitle_parallax();
128 // Volatile parameters
129 unset_fullscreen();
130 unset_center();
131 unset_audio_volume();
132 unset_audio_mute();
133 }
134
135 // Invariant parameters
136 const msg::level_t parameters::_log_level_default = msg::INF;
137 const bool parameters::_benchmark_default = false;
138 const int parameters::_swap_interval_default = 1;
139 // Per-Session parameter defaults
140 const int parameters::_audio_device_default = -1;
141 const int parameters::_quality_default = 4;
142 const parameters::stereo_mode_t parameters::_stereo_mode_default = mode_mono_left;
143 const bool parameters::_stereo_mode_swap_default = false;
144 const float parameters::_crosstalk_r_default = 0.0f;
145 const float parameters::_crosstalk_g_default = 0.0f;
146 const float parameters::_crosstalk_b_default = 0.0f;
147 const int parameters::_fullscreen_screens_default = 0;
148 const bool parameters::_fullscreen_flip_left_default = false;
149 const bool parameters::_fullscreen_flop_left_default = false;
150 const bool parameters::_fullscreen_flip_right_default = false;
151 const bool parameters::_fullscreen_flop_right_default = false;
152 const bool parameters::_fullscreen_inhibit_screensaver_default = true;
153 const bool parameters::_fullscreen_3d_ready_sync_default = false;
154 const float parameters::_contrast_default = 0.0f;
155 const float parameters::_brightness_default = 0.0f;
156 const float parameters::_hue_default = 0.0f;
157 const float parameters::_saturation_default = 0.0f;
158 const float parameters::_zoom_default = 0.0f;
159 const parameters::loop_mode_t parameters::_loop_mode_default = no_loop;
160 const int64_t parameters::_audio_delay_default = 0;
161 const std::string parameters::_subtitle_encoding_default = "";
162 const std::string parameters::_subtitle_font_default = "";
163 const int parameters::_subtitle_size_default = -1;
164 const float parameters::_subtitle_scale_default = -1.0f;
165 const uint64_t parameters::_subtitle_color_default = std::numeric_limits<uint64_t>::max();
166 const int parameters::_subtitle_shadow_default = -1;
167 #if HAVE_LIBXNVCTRL
168 const int parameters::_sdi_output_format_default = NV_CTRL_GVIO_VIDEO_FORMAT_1080P_25_00_SMPTE274;
169 const parameters::stereo_mode_t parameters::_sdi_output_left_stereo_mode_default = mode_mono_left;
170 const parameters::stereo_mode_t parameters::_sdi_output_right_stereo_mode_default = mode_mono_right;
171 #endif // HAVE_LIBXNVCTRL
172 // Per-Video parameter defaults
173 const int parameters::_video_stream_default = 0;
174 const int parameters::_audio_stream_default = 0;
175 const int parameters::_subtitle_stream_default = -1;
176 const parameters::stereo_layout_t parameters::_stereo_layout_default = layout_mono;
177 const bool parameters::_stereo_layout_swap_default = false;
178 const float parameters::_crop_aspect_ratio_default = 0.0f;
179 const float parameters::_source_aspect_ratio_default = 0.0f;
180 const float parameters::_parallax_default = 0.0f;
181 const float parameters::_ghostbust_default = 0.0f;
182 const float parameters::_subtitle_parallax_default = 0.0f;
183 // Volatile parameter defaults
184 const bool parameters::_fullscreen_default = false;
185 const bool parameters::_center_default = false;
186 const float parameters::_audio_volume_default = 1.0f;
187 const bool parameters::_audio_mute_default = false;
188
stereo_layout_to_string(stereo_layout_t stereo_layout,bool stereo_layout_swap)189 std::string parameters::stereo_layout_to_string(stereo_layout_t stereo_layout, bool stereo_layout_swap)
190 {
191 std::string s;
192 switch (stereo_layout) {
193 case layout_mono:
194 s = "mono";
195 break;
196 case layout_separate:
197 s = stereo_layout_swap ? "separate-right-left" : "separate-left-right";
198 break;
199 case layout_alternating:
200 s = stereo_layout_swap ? "alternating-right-left" : "alternating-left-right";
201 break;
202 case layout_top_bottom:
203 s = stereo_layout_swap ? "bottom-top" : "top-bottom";
204 break;
205 case layout_top_bottom_half:
206 s = stereo_layout_swap ? "bottom-top-half" : "top-bottom-half";
207 break;
208 case layout_left_right:
209 s = stereo_layout_swap ? "right-left" : "left-right";
210 break;
211 case layout_left_right_half:
212 s = stereo_layout_swap ? "right-left-half" : "left-right-half";
213 break;
214 case layout_even_odd_rows:
215 s = stereo_layout_swap ? "odd-even-rows" : "even-odd-rows";
216 break;
217 }
218 return s;
219 }
220
stereo_layout_from_string(const std::string & s,stereo_layout_t & stereo_layout,bool & stereo_layout_swap)221 void parameters::stereo_layout_from_string(const std::string &s, stereo_layout_t &stereo_layout, bool &stereo_layout_swap)
222 {
223 if (s == "mono") {
224 stereo_layout = layout_mono;
225 stereo_layout_swap = false;
226 } else if (s == "separate-right-left") {
227 stereo_layout = layout_separate;
228 stereo_layout_swap = true;
229 } else if (s == "separate-left-right") {
230 stereo_layout = layout_separate;
231 stereo_layout_swap = false;
232 } else if (s == "alternating-right-left") {
233 stereo_layout = layout_alternating;
234 stereo_layout_swap = true;
235 } else if (s == "alternating-left-right") {
236 stereo_layout = layout_alternating;
237 stereo_layout_swap = false;
238 } else if (s == "bottom-top") {
239 stereo_layout = layout_top_bottom;
240 stereo_layout_swap = true;
241 } else if (s == "top-bottom") {
242 stereo_layout = layout_top_bottom;
243 stereo_layout_swap = false;
244 } else if (s == "bottom-top-half") {
245 stereo_layout = layout_top_bottom_half;
246 stereo_layout_swap = true;
247 } else if (s == "top-bottom-half") {
248 stereo_layout = layout_top_bottom_half;
249 stereo_layout_swap = false;
250 } else if (s == "right-left") {
251 stereo_layout = layout_left_right;
252 stereo_layout_swap = true;
253 } else if (s == "left-right") {
254 stereo_layout = layout_left_right;
255 stereo_layout_swap = false;
256 } else if (s == "right-left-half") {
257 stereo_layout = layout_left_right_half;
258 stereo_layout_swap = true;
259 } else if (s == "left-right-half") {
260 stereo_layout = layout_left_right_half;
261 stereo_layout_swap = false;
262 } else if (s == "odd-even-rows") {
263 stereo_layout = layout_even_odd_rows;
264 stereo_layout_swap = true;
265 } else if (s == "even-odd-rows") {
266 stereo_layout = layout_even_odd_rows;
267 stereo_layout_swap = false;
268 } else {
269 // safe fallback
270 stereo_layout = layout_mono;
271 stereo_layout_swap = false;
272 }
273 }
274
parse_stereo_layout(const std::string & s,stereo_layout_t * stereo_layout)275 bool parameters::parse_stereo_layout(const std::string& s, stereo_layout_t* stereo_layout)
276 {
277 bool ok = true;
278 if (s == "mono") {
279 *stereo_layout = layout_mono;
280 } else if (s == "separate-left-right") {
281 *stereo_layout = layout_separate;
282 } else if (s == "alternating-left-right") {
283 *stereo_layout = layout_alternating;
284 } else if (s == "top-bottom") {
285 *stereo_layout = layout_top_bottom;
286 } else if (s == "top-bottom-half") {
287 *stereo_layout = layout_top_bottom_half;
288 } else if (s == "left-right") {
289 *stereo_layout = layout_left_right;
290 } else if (s == "left-right-half") {
291 *stereo_layout = layout_left_right_half;
292 } else if (s == "even-odd-rows") {
293 *stereo_layout = layout_even_odd_rows;
294 } else {
295 ok = false;
296 }
297 return ok;
298 }
299
stereo_mode_to_string(stereo_mode_t stereo_mode,bool stereo_mode_swap)300 std::string parameters::stereo_mode_to_string(stereo_mode_t stereo_mode, bool stereo_mode_swap)
301 {
302 std::string s;
303 switch (stereo_mode) {
304 case mode_stereo:
305 s = "stereo";
306 break;
307 case mode_alternating:
308 s = "alternating";
309 break;
310 case mode_mono_left:
311 s = "mono-left";
312 break;
313 case mode_mono_right:
314 s = "mono-right";
315 break;
316 case mode_top_bottom:
317 s = "top-bottom";
318 break;
319 case mode_top_bottom_half:
320 s = "top-bottom-half";
321 break;
322 case mode_left_right:
323 s = "left-right";
324 break;
325 case mode_left_right_half:
326 s = "left-right-half";
327 break;
328 case mode_even_odd_rows:
329 s = "even-odd-rows";
330 break;
331 case mode_even_odd_columns:
332 s = "even-odd-columns";
333 break;
334 case mode_checkerboard:
335 s = "checkerboard";
336 break;
337 case mode_hdmi_frame_pack:
338 s = "hdmi-frame-pack";
339 break;
340 case mode_red_cyan_monochrome:
341 s = "red-cyan-monochrome";
342 break;
343 case mode_red_cyan_half_color:
344 s = "red-cyan-half-color";
345 break;
346 case mode_red_cyan_full_color:
347 s = "red-cyan-full-color";
348 break;
349 case mode_red_cyan_dubois:
350 s = "red-cyan-dubois";
351 break;
352 case mode_green_magenta_monochrome:
353 s = "green-magenta-monochrome";
354 break;
355 case mode_green_magenta_half_color:
356 s = "green-magenta-half-color";
357 break;
358 case mode_green_magenta_full_color:
359 s = "green-magenta-full-color";
360 break;
361 case mode_green_magenta_dubois:
362 s = "green-magenta-dubois";
363 break;
364 case mode_amber_blue_monochrome:
365 s = "amber-blue-monochrome";
366 break;
367 case mode_amber_blue_half_color:
368 s = "amber-blue-half-color";
369 break;
370 case mode_amber_blue_dubois:
371 s = "amber-blue-dubois";
372 break;
373 case mode_amber_blue_full_color:
374 s = "amber-blue-full-color";
375 break;
376 case mode_red_green_monochrome:
377 s = "red-green-monochrome";
378 break;
379 case mode_red_blue_monochrome:
380 s = "red-blue-monochrome";
381 break;
382 }
383 if (stereo_mode_swap) {
384 s += "-swap";
385 }
386 return s;
387 }
388
stereo_mode_from_string(const std::string & s,stereo_mode_t & stereo_mode,bool & stereo_mode_swap)389 void parameters::stereo_mode_from_string(const std::string &s, stereo_mode_t &stereo_mode, bool &stereo_mode_swap)
390 {
391 size_t x = s.find_last_of("-");
392 std::string t;
393 if (x != std::string::npos && s.substr(x) == "-swap") {
394 t = s.substr(0, x);
395 stereo_mode_swap = true;
396 } else {
397 t = s;
398 stereo_mode_swap = false;
399 }
400 if (!parse_stereo_mode(t, &stereo_mode)) {
401 // safe fallback
402 stereo_mode = mode_mono_left;
403 }
404 }
405
parse_stereo_mode(const std::string & s,stereo_mode_t * stereo_mode)406 bool parameters::parse_stereo_mode(const std::string& s, stereo_mode_t* stereo_mode)
407 {
408 bool ok = true;
409 if (s == "stereo") {
410 *stereo_mode = mode_stereo;
411 } else if (s == "alternating") {
412 *stereo_mode = mode_alternating;
413 } else if (s == "mono-left") {
414 *stereo_mode = mode_mono_left;
415 } else if (s == "mono-right") {
416 *stereo_mode = mode_mono_right;
417 } else if (s == "top-bottom") {
418 *stereo_mode = mode_top_bottom;
419 } else if (s == "top-bottom-half") {
420 *stereo_mode = mode_top_bottom_half;
421 } else if (s == "left-right") {
422 *stereo_mode = mode_left_right;
423 } else if (s == "left-right-half") {
424 *stereo_mode = mode_left_right_half;
425 } else if (s == "even-odd-rows") {
426 *stereo_mode = mode_even_odd_rows;
427 } else if (s == "even-odd-columns") {
428 *stereo_mode = mode_even_odd_columns;
429 } else if (s == "checkerboard") {
430 *stereo_mode = mode_checkerboard;
431 } else if (s == "hdmi-frame-pack") {
432 *stereo_mode = mode_hdmi_frame_pack;
433 } else if (s == "red-cyan-monochrome") {
434 *stereo_mode = mode_red_cyan_monochrome;
435 } else if (s == "red-cyan-half-color") {
436 *stereo_mode = mode_red_cyan_half_color;
437 } else if (s == "red-cyan-full-color") {
438 *stereo_mode = mode_red_cyan_full_color;
439 } else if (s == "red-cyan-dubois") {
440 *stereo_mode = mode_red_cyan_dubois;
441 } else if (s == "green-magenta-monochrome") {
442 *stereo_mode = mode_green_magenta_monochrome;
443 } else if (s == "green-magenta-half-color") {
444 *stereo_mode = mode_green_magenta_half_color;
445 } else if (s == "green-magenta-full-color") {
446 *stereo_mode = mode_green_magenta_full_color;
447 } else if (s == "green-magenta-dubois") {
448 *stereo_mode = mode_green_magenta_dubois;
449 } else if (s == "amber-blue-monochrome") {
450 *stereo_mode = mode_amber_blue_monochrome;
451 } else if (s == "amber-blue-half-color") {
452 *stereo_mode = mode_amber_blue_half_color;
453 } else if (s == "amber-blue-full-color") {
454 *stereo_mode = mode_amber_blue_full_color;
455 } else if (s == "amber-blue-dubois") {
456 *stereo_mode = mode_amber_blue_dubois;
457 } else if (s == "red-green-monochrome") {
458 *stereo_mode = mode_red_green_monochrome;
459 } else if (s == "red-blue-monochrome") {
460 *stereo_mode = mode_red_blue_monochrome;
461 } else {
462 ok = false;
463 }
464 return ok;
465 }
466
loop_mode_to_string(loop_mode_t loop_mode)467 std::string parameters::loop_mode_to_string(loop_mode_t loop_mode)
468 {
469 if (loop_mode == loop_current) {
470 return "loop-current";
471 } else {
472 return "no-loop";
473 }
474 }
475
loop_mode_from_string(const std::string & s)476 parameters::loop_mode_t parameters::loop_mode_from_string(const std::string &s)
477 {
478 if (s == "loop-current") {
479 return loop_current;
480 } else {
481 return no_loop;
482 }
483 }
484
save(std::ostream & os) const485 void parameters::save(std::ostream &os) const
486 {
487 // Invariant parameters
488 s11n::save(os, static_cast<int>(_log_level));
489 s11n::save(os, _log_level_set);
490 s11n::save(os, _benchmark);
491 s11n::save(os, _benchmark_set);
492 s11n::save(os, _swap_interval);
493 s11n::save(os, _swap_interval_set);
494 // Per-Session parameters
495 s11n::save(os, _audio_device);
496 s11n::save(os, _audio_device_set);
497 s11n::save(os, _quality);
498 s11n::save(os, _quality_set);
499 s11n::save(os, static_cast<int>(_stereo_mode));
500 s11n::save(os, _stereo_mode_set);
501 s11n::save(os, _stereo_mode_swap);
502 s11n::save(os, _stereo_mode_swap_set);
503 s11n::save(os, _crosstalk_r);
504 s11n::save(os, _crosstalk_r_set);
505 s11n::save(os, _crosstalk_g);
506 s11n::save(os, _crosstalk_g_set);
507 s11n::save(os, _crosstalk_b);
508 s11n::save(os, _crosstalk_b_set);
509 s11n::save(os, _fullscreen_screens);
510 s11n::save(os, _fullscreen_screens_set);
511 s11n::save(os, _fullscreen_flip_left);
512 s11n::save(os, _fullscreen_flip_left_set);
513 s11n::save(os, _fullscreen_flop_left);
514 s11n::save(os, _fullscreen_flop_left_set);
515 s11n::save(os, _fullscreen_flip_right);
516 s11n::save(os, _fullscreen_flip_right_set);
517 s11n::save(os, _fullscreen_flop_right);
518 s11n::save(os, _fullscreen_flop_right_set);
519 s11n::save(os, _fullscreen_inhibit_screensaver);
520 s11n::save(os, _fullscreen_inhibit_screensaver_set);
521 s11n::save(os, _fullscreen_3d_ready_sync);
522 s11n::save(os, _fullscreen_3d_ready_sync_set);
523 s11n::save(os, _contrast);
524 s11n::save(os, _contrast_set);
525 s11n::save(os, _brightness);
526 s11n::save(os, _brightness_set);
527 s11n::save(os, _hue);
528 s11n::save(os, _hue_set);
529 s11n::save(os, _saturation);
530 s11n::save(os, _saturation_set);
531 s11n::save(os, _zoom);
532 s11n::save(os, _zoom_set);
533 s11n::save(os, static_cast<int>(_loop_mode));
534 s11n::save(os, _loop_mode_set);
535 s11n::save(os, _audio_delay);
536 s11n::save(os, _audio_delay_set);
537 s11n::save(os, _subtitle_encoding);
538 s11n::save(os, _subtitle_encoding_set);
539 s11n::save(os, _subtitle_font);
540 s11n::save(os, _subtitle_font_set);
541 s11n::save(os, _subtitle_size);
542 s11n::save(os, _subtitle_size_set);
543 s11n::save(os, _subtitle_scale);
544 s11n::save(os, _subtitle_scale_set);
545 s11n::save(os, _subtitle_color);
546 s11n::save(os, _subtitle_color_set);
547 s11n::save(os, _subtitle_shadow);
548 s11n::save(os, _subtitle_shadow_set);
549 #if HAVE_LIBXNVCTRL
550 s11n::save(os, _sdi_output_format);
551 s11n::save(os, _sdi_output_format_set);
552 s11n::save(os, static_cast<int>(_sdi_output_left_stereo_mode));
553 s11n::save(os, _sdi_output_left_stereo_mode_set);
554 s11n::save(os, static_cast<int>(_sdi_output_right_stereo_mode));
555 s11n::save(os, _sdi_output_right_stereo_mode_set);
556 #endif // HAVE_LIBXNVCTRL
557 // Per-Video parameters
558 s11n::save(os, _video_stream);
559 s11n::save(os, _video_stream_set);
560 s11n::save(os, _audio_stream);
561 s11n::save(os, _audio_stream_set);
562 s11n::save(os, _subtitle_stream);
563 s11n::save(os, _subtitle_stream_set);
564 s11n::save(os, static_cast<int>(_stereo_layout));
565 s11n::save(os, _stereo_layout_set);
566 s11n::save(os, _stereo_layout_swap);
567 s11n::save(os, _stereo_layout_swap_set);
568 s11n::save(os, _crop_aspect_ratio);
569 s11n::save(os, _crop_aspect_ratio_set);
570 s11n::save(os, _source_aspect_ratio);
571 s11n::save(os, _source_aspect_ratio_set);
572 s11n::save(os, _parallax);
573 s11n::save(os, _parallax_set);
574 s11n::save(os, _ghostbust);
575 s11n::save(os, _ghostbust_set);
576 s11n::save(os, _subtitle_parallax);
577 s11n::save(os, _subtitle_parallax_set);
578 // Volatile parameters
579 s11n::save(os, _fullscreen);
580 s11n::save(os, _fullscreen_set);
581 s11n::save(os, _center);
582 s11n::save(os, _center_set);
583 s11n::save(os, _audio_volume);
584 s11n::save(os, _audio_volume_set);
585 s11n::save(os, _audio_mute);
586 s11n::save(os, _audio_mute_set);
587 }
588
load(std::istream & is)589 void parameters::load(std::istream &is)
590 {
591 int x;
592 // Invariant parameters
593 s11n::load(is, x); _log_level = static_cast<msg::level_t>(x);
594 s11n::load(is, _log_level_set);
595 s11n::load(is, _benchmark);
596 s11n::load(is, _benchmark_set);
597 s11n::load(is, _swap_interval);
598 s11n::load(is, _swap_interval_set);
599 // Per-Session parameters
600 s11n::load(is, _audio_device);
601 s11n::load(is, _audio_device_set);
602 s11n::load(is, _quality);
603 s11n::load(is, _quality_set);
604 s11n::load(is, x); _stereo_mode = static_cast<stereo_mode_t>(x);
605 s11n::load(is, _stereo_mode_set);
606 s11n::load(is, _stereo_mode_swap);
607 s11n::load(is, _stereo_mode_swap_set);
608 s11n::load(is, _crosstalk_r);
609 s11n::load(is, _crosstalk_r_set);
610 s11n::load(is, _crosstalk_g);
611 s11n::load(is, _crosstalk_g_set);
612 s11n::load(is, _crosstalk_b);
613 s11n::load(is, _crosstalk_b_set);
614 s11n::load(is, _fullscreen_screens);
615 s11n::load(is, _fullscreen_screens_set);
616 s11n::load(is, _fullscreen_flip_left);
617 s11n::load(is, _fullscreen_flip_left_set);
618 s11n::load(is, _fullscreen_flop_left);
619 s11n::load(is, _fullscreen_flop_left_set);
620 s11n::load(is, _fullscreen_flip_right);
621 s11n::load(is, _fullscreen_flip_right_set);
622 s11n::load(is, _fullscreen_flop_right);
623 s11n::load(is, _fullscreen_flop_right_set);
624 s11n::load(is, _fullscreen_inhibit_screensaver);
625 s11n::load(is, _fullscreen_inhibit_screensaver_set);
626 s11n::load(is, _fullscreen_3d_ready_sync);
627 s11n::load(is, _fullscreen_3d_ready_sync_set);
628 s11n::load(is, _contrast);
629 s11n::load(is, _contrast_set);
630 s11n::load(is, _brightness);
631 s11n::load(is, _brightness_set);
632 s11n::load(is, _hue);
633 s11n::load(is, _hue_set);
634 s11n::load(is, _saturation);
635 s11n::load(is, _saturation_set);
636 s11n::load(is, _zoom);
637 s11n::load(is, _zoom_set);
638 s11n::load(is, x); _loop_mode = static_cast<loop_mode_t>(x);
639 s11n::load(is, _loop_mode_set);
640 s11n::load(is, _audio_delay);
641 s11n::load(is, _audio_delay_set);
642 s11n::load(is, _subtitle_encoding);
643 s11n::load(is, _subtitle_encoding_set);
644 s11n::load(is, _subtitle_font);
645 s11n::load(is, _subtitle_font_set);
646 s11n::load(is, _subtitle_size);
647 s11n::load(is, _subtitle_size_set);
648 s11n::load(is, _subtitle_scale);
649 s11n::load(is, _subtitle_scale_set);
650 s11n::load(is, _subtitle_color);
651 s11n::load(is, _subtitle_color_set);
652 s11n::load(is, _subtitle_shadow);
653 s11n::load(is, _subtitle_shadow_set);
654 #if HAVE_LIBXNVCTRL
655 s11n::load(is, _sdi_output_format);
656 s11n::load(is, _sdi_output_format_set);
657 s11n::load(is, x); _sdi_output_left_stereo_mode = static_cast<stereo_mode_t>(x);
658 s11n::load(is, _sdi_output_left_stereo_mode_set);
659 s11n::load(is, x); _sdi_output_right_stereo_mode = static_cast<stereo_mode_t>(x);
660 s11n::load(is, _sdi_output_right_stereo_mode_set);
661 #endif // HAVE_LIBXNVCTRL
662 // Per-Video parameters
663 s11n::load(is, _video_stream);
664 s11n::load(is, _video_stream_set);
665 s11n::load(is, _audio_stream);
666 s11n::load(is, _audio_stream_set);
667 s11n::load(is, _subtitle_stream);
668 s11n::load(is, _subtitle_stream_set);
669 s11n::load(is, x); _stereo_layout = static_cast<stereo_layout_t>(x);
670 s11n::load(is, _stereo_layout_set);
671 s11n::load(is, _stereo_layout_swap);
672 s11n::load(is, _stereo_layout_swap_set);
673 s11n::load(is, _crop_aspect_ratio);
674 s11n::load(is, _crop_aspect_ratio_set);
675 s11n::load(is, _source_aspect_ratio);
676 s11n::load(is, _source_aspect_ratio_set);
677 s11n::load(is, _parallax);
678 s11n::load(is, _parallax_set);
679 s11n::load(is, _ghostbust);
680 s11n::load(is, _ghostbust_set);
681 s11n::load(is, _subtitle_parallax);
682 s11n::load(is, _subtitle_parallax_set);
683 // Volatile parameters
684 s11n::load(is, _fullscreen);
685 s11n::load(is, _fullscreen_set);
686 s11n::load(is, _center);
687 s11n::load(is, _center_set);
688 s11n::load(is, _audio_volume);
689 s11n::load(is, _audio_volume_set);
690 s11n::load(is, _audio_mute);
691 s11n::load(is, _audio_mute_set);
692 }
693
save_session_parameters() const694 std::string parameters::save_session_parameters() const
695 {
696 std::stringstream oss;
697 if (!audio_device_is_default())
698 s11n::save(oss, "audio_device", audio_device());
699 if (!quality_is_default())
700 s11n::save(oss, "quality", quality());
701 if (!stereo_mode_is_default() || !stereo_mode_swap_is_default())
702 s11n::save(oss, "stereo_mode", stereo_mode_to_string(stereo_mode(), stereo_mode_swap()));
703 if (!crosstalk_r_is_default())
704 s11n::save(oss, "crosstalk_r", crosstalk_r());
705 if (!crosstalk_g_is_default())
706 s11n::save(oss, "crosstalk_g", crosstalk_g());
707 if (!crosstalk_b_is_default())
708 s11n::save(oss, "crosstalk_b", crosstalk_b());
709 if (!fullscreen_screens_is_default())
710 s11n::save(oss, "fullscreen_screens", fullscreen_screens());
711 if (!fullscreen_flip_left_is_default())
712 s11n::save(oss, "fullscreen_flip_left", fullscreen_flip_left());
713 if (!fullscreen_flop_left_is_default())
714 s11n::save(oss, "fullscreen_flop_left", fullscreen_flop_left());
715 if (!fullscreen_flip_right_is_default())
716 s11n::save(oss, "fullscreen_flip_right", fullscreen_flip_right());
717 if (!fullscreen_flop_right_is_default())
718 s11n::save(oss, "fullscreen_flop_right", fullscreen_flop_right());
719 if (!fullscreen_inhibit_screensaver_is_default())
720 s11n::save(oss, "fullscreen_inhibit_screensaver", fullscreen_inhibit_screensaver());
721 if (!fullscreen_3d_ready_sync_is_default())
722 s11n::save(oss, "fullscreen_3d_ready_sync", fullscreen_3d_ready_sync());
723 if (!contrast_is_default())
724 s11n::save(oss, "contrast", contrast());
725 if (!brightness_is_default())
726 s11n::save(oss, "brightness", brightness());
727 if (!hue_is_default())
728 s11n::save(oss, "hue", hue());
729 if (!saturation_is_default())
730 s11n::save(oss, "saturation", saturation());
731 if (!zoom_is_default())
732 s11n::save(oss, "zoom", zoom());
733 if (!loop_mode_is_default())
734 s11n::save(oss, "loop_mode", loop_mode_to_string(loop_mode()));
735 if (!audio_delay_is_default())
736 s11n::save(oss, "audio_delay", audio_delay());
737 if (!subtitle_encoding_is_default())
738 s11n::save(oss, "subtitle_encoding", _subtitle_encoding);
739 if (!subtitle_font_is_default())
740 s11n::save(oss, "subtitle_font", _subtitle_font);
741 if (!subtitle_size_is_default())
742 s11n::save(oss, "subtitle_size", _subtitle_size);
743 if (!subtitle_scale_is_default())
744 s11n::save(oss, "subtitle_scale", _subtitle_scale);
745 if (!subtitle_color_is_default())
746 s11n::save(oss, "subtitle_color", _subtitle_color);
747 if (!subtitle_shadow_is_default())
748 s11n::save(oss, "subtitle_shadow", _subtitle_shadow);
749 #if HAVE_LIBXNVCTRL
750 if (!sdi_output_format_is_default())
751 s11n::save(oss, "sdi_output_format", sdi_output_format());
752 if (!sdi_output_left_stereo_mode_is_default())
753 s11n::save(oss, "sdi_output_left_stereo_mode", stereo_mode_to_string(sdi_output_left_stereo_mode(), false));
754 if (!sdi_output_right_stereo_mode_is_default())
755 s11n::save(oss, "sdi_output_right_stereo_mode", stereo_mode_to_string(sdi_output_right_stereo_mode(), false));
756 #endif // HAVE_LIBXNVCTRL
757 return oss.str();
758 }
759
load_session_parameters(const std::string & s)760 void parameters::load_session_parameters(const std::string &s)
761 {
762 std::istringstream iss(s);
763 std::string name, value;
764 while (iss.good()) {
765 s11n::load(iss, name, value);
766 if (name == "audio_device") {
767 s11n::load(value, _audio_device);
768 _audio_device_set = true;
769 } else if (name == "quality") {
770 s11n::load(value, _quality);
771 _quality_set = true;
772 } else if (name == "stereo_mode") {
773 std::string s;
774 s11n::load(value, s);
775 stereo_mode_from_string(s, _stereo_mode, _stereo_mode_swap);
776 _stereo_mode_set = true;
777 _stereo_mode_swap_set = true;
778 } else if (name == "crosstalk_r") {
779 s11n::load(value, _crosstalk_r);
780 _crosstalk_r_set = true;
781 } else if (name == "crosstalk_g") {
782 s11n::load(value, _crosstalk_g);
783 _crosstalk_g_set = true;
784 } else if (name == "crosstalk_b") {
785 s11n::load(value, _crosstalk_b);
786 _crosstalk_b_set = true;
787 } else if (name == "fullscreen_screens") {
788 s11n::load(value, _fullscreen_screens);
789 _fullscreen_screens_set = true;
790 } else if (name == "fullscreen_flip_left") {
791 s11n::load(value, _fullscreen_flip_left);
792 _fullscreen_flip_left_set = true;
793 } else if (name == "fullscreen_flop_left") {
794 s11n::load(value, _fullscreen_flop_left);
795 _fullscreen_flop_left_set = true;
796 } else if (name == "fullscreen_flip_right") {
797 s11n::load(value, _fullscreen_flip_right);
798 _fullscreen_flip_right_set = true;
799 } else if (name == "fullscreen_flop_right") {
800 s11n::load(value, _fullscreen_flop_right);
801 _fullscreen_flop_right_set = true;
802 } else if (name == "fullscreen_inhibit_screensaver") {
803 s11n::load(value, _fullscreen_inhibit_screensaver);
804 _fullscreen_inhibit_screensaver_set = true;
805 } else if (name == "fullscreen_3d_ready_sync") {
806 s11n::load(value, _fullscreen_3d_ready_sync);
807 _fullscreen_3d_ready_sync_set = true;
808 } else if (name == "contrast") {
809 s11n::load(value, _contrast);
810 _contrast_set = true;
811 } else if (name == "brightness") {
812 s11n::load(value, _brightness);
813 _brightness_set = true;
814 } else if (name == "hue") {
815 s11n::load(value, _hue);
816 _hue_set = true;
817 } else if (name == "saturation") {
818 s11n::load(value, _saturation);
819 _saturation_set = true;
820 } else if (name == "zoom") {
821 s11n::load(value, _zoom);
822 _zoom_set = true;
823 } else if (name == "loop_mode") {
824 std::string s;
825 s11n::load(value, s);
826 _loop_mode = loop_mode_from_string(s);
827 _loop_mode_set = true;
828 } else if (name == "audio_delay") {
829 s11n::load(value, _audio_delay);
830 _audio_delay_set = true;
831 } else if (name == "subtitle_encoding") {
832 s11n::load(value, _subtitle_encoding);
833 _subtitle_encoding_set = true;
834 } else if (name == "subtitle_font") {
835 s11n::load(value, _subtitle_font);
836 _subtitle_font_set = true;
837 } else if (name == "subtitle_size") {
838 s11n::load(value, _subtitle_size);
839 _subtitle_size_set = true;
840 } else if (name == "subtitle_scale") {
841 s11n::load(value, _subtitle_scale);
842 _subtitle_scale_set = true;
843 } else if (name == "subtitle_color") {
844 s11n::load(value, _subtitle_color);
845 _subtitle_color_set = true;
846 } else if (name == "subtitle_shadow") {
847 s11n::load(value, _subtitle_shadow);
848 _subtitle_shadow_set = true;
849 #if HAVE_LIBXNVCTRL
850 } else if (name == "sdi_output_format") {
851 s11n::load(value, _sdi_output_format);
852 _sdi_output_format_set = true;
853 } else if (name == "sdi_output_left_stereo_mode") {
854 std::string s;
855 bool swap_value;
856 s11n::load(value, s);
857 stereo_mode_from_string(s, _sdi_output_left_stereo_mode, swap_value);
858 _sdi_output_left_stereo_mode_set = true;
859 } else if (name == "sdi_output_right_stereo_mode") {
860 std::string s;
861 bool swap_value;
862 s11n::load(value, s);
863 stereo_mode_from_string(s, _sdi_output_right_stereo_mode, swap_value);
864 _sdi_output_right_stereo_mode_set = true;
865 #endif // HAVE_LIBXNVCTRL
866 }
867 }
868 }
869
unset_video_parameters()870 void parameters::unset_video_parameters()
871 {
872 unset_video_stream();
873 unset_audio_stream();
874 unset_subtitle_stream();
875 unset_stereo_layout();
876 unset_stereo_layout_swap();
877 unset_crop_aspect_ratio();
878 unset_source_aspect_ratio();
879 unset_parallax();
880 unset_ghostbust();
881 unset_subtitle_parallax();
882 }
883
save_video_parameters() const884 std::string parameters::save_video_parameters() const
885 {
886 std::stringstream oss;
887 if (!video_stream_is_default())
888 s11n::save(oss, "video_stream", _video_stream);
889 if (!audio_stream_is_default())
890 s11n::save(oss, "audio_stream", _audio_stream);
891 if (!subtitle_stream_is_default())
892 s11n::save(oss, "subtitle_stream", _subtitle_stream);
893 if (!stereo_layout_is_default() || !stereo_layout_swap_is_default())
894 s11n::save(oss, "stereo_layout", stereo_layout_to_string(stereo_layout(), stereo_layout_swap()));
895 if (!crop_aspect_ratio_is_default())
896 s11n::save(oss, "crop_aspect_ratio", _crop_aspect_ratio);
897 if (!source_aspect_ratio_is_default())
898 s11n::save(oss, "source_aspect_ratio", _source_aspect_ratio);
899 if (!parallax_is_default())
900 s11n::save(oss, "parallax", _parallax);
901 if (!ghostbust_is_default())
902 s11n::save(oss, "ghostbust", _ghostbust);
903 if (!subtitle_parallax_is_default())
904 s11n::save(oss, "subtitle_parallax", _subtitle_parallax);
905 return oss.str();
906 }
907
load_video_parameters(const std::string & s)908 void parameters::load_video_parameters(const std::string &s)
909 {
910 std::istringstream iss(s);
911 std::string name, value;
912 while (iss.good()) {
913 s11n::load(iss, name, value);
914 if (name == "video_stream") {
915 s11n::load(value, _video_stream);
916 _video_stream_set = true;
917 } else if (name == "audio_stream") {
918 s11n::load(value, _audio_stream);
919 _audio_stream_set = true;
920 } else if (name == "subtitle_stream") {
921 s11n::load(value, _subtitle_stream);
922 _subtitle_stream_set = true;
923 } else if (name == "stereo_layout") {
924 std::string s;
925 s11n::load(value, s);
926 stereo_layout_from_string(s, _stereo_layout, _stereo_layout_swap);
927 _stereo_layout_set = true;
928 _stereo_layout_swap_set = true;
929 } else if (name == "crop_aspect_ratio") {
930 s11n::load(value, _crop_aspect_ratio);
931 _crop_aspect_ratio_set = true;
932 } else if (name == "source_aspect_ratio") {
933 s11n::load(value, _source_aspect_ratio);
934 _source_aspect_ratio_set = true;
935 } else if (name == "parallax") {
936 s11n::load(value, _parallax);
937 _parallax_set = true;
938 } else if (name == "ghostbust") {
939 s11n::load(value, _ghostbust);
940 _ghostbust_set = true;
941 } else if (name == "subtitle_parallax") {
942 s11n::load(value, _subtitle_parallax);
943 _subtitle_parallax_set = true;
944 }
945 }
946 }
947
948
video_frame()949 video_frame::video_frame() :
950 raw_width(-1),
951 raw_height(-1),
952 raw_aspect_ratio(0.0f),
953 width(-1),
954 height(-1),
955 aspect_ratio(0.0f),
956 layout(bgra32),
957 color_space(srgb),
958 value_range(u8_full),
959 chroma_location(center),
960 stereo_layout(parameters::layout_mono),
961 stereo_layout_swap(false),
962 presentation_time(std::numeric_limits<int64_t>::min())
963 {
964 for (int i = 0; i < 2; i++)
965 {
966 for (int p = 0; p < 3; p++)
967 {
968 data[i][p] = NULL;
969 line_size[i][p] = 0;
970 }
971 }
972 }
973
set_view_dimensions()974 void video_frame::set_view_dimensions()
975 {
976 width = raw_width;
977 height = raw_height;
978 aspect_ratio = raw_aspect_ratio;
979 if (stereo_layout == parameters::layout_left_right)
980 {
981 width /= 2;
982 aspect_ratio /= 2.0f;
983 }
984 else if (stereo_layout == parameters::layout_left_right_half)
985 {
986 width /= 2;
987 }
988 else if (stereo_layout == parameters::layout_top_bottom)
989 {
990 height /= 2;
991 aspect_ratio *= 2.0f;
992 }
993 else if (stereo_layout == parameters::layout_top_bottom_half)
994 {
995 height /= 2;
996 }
997 else if (stereo_layout == parameters::layout_even_odd_rows)
998 {
999 height /= 2;
1000 //aspect_ratio *= 2.0f;
1001 // The only video files I know of which use row-alternating format (those from stereopia.com)
1002 // do not want this adjustment of aspect ratio.
1003 }
1004 }
1005
format_name() const1006 std::string video_frame::format_name() const
1007 {
1008 std::string name = str::asprintf("%dx%d-%.3g:1-", raw_width, raw_height, raw_aspect_ratio);
1009 switch (layout)
1010 {
1011 case bgra32:
1012 name += "bgra32";
1013 break;
1014 case yuv444p:
1015 name += "yuv444p";
1016 break;
1017 case yuv422p:
1018 name += "yuv422p";
1019 break;
1020 case yuv420p:
1021 name += "yuv420p";
1022 break;
1023 }
1024 switch (color_space)
1025 {
1026 case srgb:
1027 name += "-srgb";
1028 break;
1029 case yuv601:
1030 name += "-601";
1031 break;
1032 case yuv709:
1033 name += "-709";
1034 break;
1035 }
1036 if (layout != bgra32)
1037 {
1038 switch (value_range)
1039 {
1040 case u8_full:
1041 name += "-jpeg";
1042 break;
1043 case u8_mpeg:
1044 name += "-mpeg";
1045 break;
1046 case u10_full:
1047 name += "-jpeg10";
1048 break;
1049 case u10_mpeg:
1050 name += "-mpeg10";
1051 break;
1052 }
1053 }
1054 if (layout == yuv422p || layout == yuv420p)
1055 {
1056 switch (chroma_location)
1057 {
1058 case center:
1059 name += "-c";
1060 break;
1061 case left:
1062 name += "-l";
1063 break;
1064 case topleft:
1065 name += "-tl";
1066 break;
1067 }
1068 }
1069 return name;
1070 }
1071
format_info() const1072 std::string video_frame::format_info() const
1073 {
1074 /* TRANSLATORS: This is a very short string describing the video size and aspect ratio. */
1075 return str::asprintf(_("%dx%d, %.3g:1"), raw_width, raw_height, aspect_ratio);
1076 }
1077
next_multiple_of_4(int x)1078 static int next_multiple_of_4(int x)
1079 {
1080 return (x / 4 + (x % 4 == 0 ? 0 : 1)) * 4;
1081 }
1082
copy_plane(int view,int plane,void * buf) const1083 void video_frame::copy_plane(int view, int plane, void *buf) const
1084 {
1085 char *dst = reinterpret_cast<char *>(buf);
1086 const char *src = NULL;
1087 size_t src_offset = 0;
1088 size_t src_row_size = 0;
1089 size_t dst_row_width = 0;
1090 size_t dst_row_size = 0;
1091 size_t lines = 0;
1092 size_t type_size = (value_range == u8_full || value_range == u8_mpeg) ? 1 : 2;
1093
1094 switch (layout)
1095 {
1096 case bgra32:
1097 dst_row_width = width * 4;
1098 dst_row_size = dst_row_width * type_size;
1099 lines = height;
1100 break;
1101
1102 case yuv444p:
1103 dst_row_width = width;
1104 dst_row_size = next_multiple_of_4(dst_row_width * type_size);
1105 lines = height;
1106 break;
1107
1108 case yuv422p:
1109 if (plane == 0)
1110 {
1111 dst_row_width = width;
1112 dst_row_size = next_multiple_of_4(dst_row_width * type_size);
1113 lines = height;
1114 }
1115 else
1116 {
1117 dst_row_width = width / 2;
1118 dst_row_size = next_multiple_of_4(dst_row_width * type_size);
1119 lines = height;
1120 }
1121 break;
1122
1123 case yuv420p:
1124 if (plane == 0)
1125 {
1126 dst_row_width = width;
1127 dst_row_size = next_multiple_of_4(dst_row_width * type_size);
1128 lines = height;
1129 }
1130 else
1131 {
1132 dst_row_width = width / 2;
1133 dst_row_size = next_multiple_of_4(dst_row_width * type_size);
1134 lines = height / 2;
1135 }
1136 break;
1137 }
1138
1139 if (stereo_layout_swap)
1140 {
1141 view = (view == 0 ? 1 : 0);
1142 }
1143 switch (stereo_layout)
1144 {
1145 case parameters::layout_mono:
1146 src = static_cast<const char *>(data[0][plane]);
1147 src_row_size = line_size[0][plane];
1148 src_offset = 0;
1149 break;
1150 case parameters::layout_separate:
1151 case parameters::layout_alternating:
1152 src = static_cast<const char *>(data[view][plane]);
1153 src_row_size = line_size[view][plane];
1154 src_offset = 0;
1155 break;
1156 case parameters::layout_top_bottom:
1157 case parameters::layout_top_bottom_half:
1158 src = static_cast<const char *>(data[0][plane]);
1159 src_row_size = line_size[0][plane];
1160 src_offset = view * lines * src_row_size;
1161 break;
1162 case parameters::layout_left_right:
1163 case parameters::layout_left_right_half:
1164 src = static_cast<const char *>(data[0][plane]);
1165 src_row_size = line_size[0][plane];
1166 src_offset = view * dst_row_width;
1167 break;
1168 case parameters::layout_even_odd_rows:
1169 src = static_cast<const char *>(data[0][plane]);
1170 src_row_size = 2 * line_size[0][plane];
1171 src_offset = view * line_size[0][plane];
1172 break;
1173 }
1174
1175 assert(src);
1176 if (src_row_size == dst_row_size)
1177 {
1178 std::memcpy(dst, src + src_offset, lines * src_row_size);
1179 }
1180 else
1181 {
1182 size_t dst_offset = 0;
1183 for (size_t y = 0; y < lines; y++)
1184 {
1185 std::memcpy(dst + dst_offset, src + src_offset, dst_row_width * type_size);
1186 dst_offset += dst_row_size;
1187 src_offset += src_row_size;
1188 }
1189 }
1190 }
1191
audio_blob()1192 audio_blob::audio_blob() :
1193 language(),
1194 channels(-1),
1195 rate(-1),
1196 sample_format(u8),
1197 data(NULL),
1198 size(0),
1199 presentation_time(std::numeric_limits<int64_t>::min())
1200 {
1201 }
1202
format_info() const1203 std::string audio_blob::format_info() const
1204 {
1205 /* TRANSLATORS: This is a very short string describing the audio language, channels, frequency, and bits. */
1206 return str::asprintf(_("%s, %d ch., %g kHz, %d bit"),
1207 language.empty() ? _("unknown") : language.c_str(),
1208 channels, rate / 1e3f, sample_bits());
1209 }
1210
format_name() const1211 std::string audio_blob::format_name() const
1212 {
1213 const char *sample_format_name = "";
1214 switch (sample_format)
1215 {
1216 case u8:
1217 sample_format_name = "u8";
1218 break;
1219 case s16:
1220 sample_format_name = "s16";
1221 break;
1222 case f32:
1223 sample_format_name = "f32";
1224 break;
1225 case d64:
1226 sample_format_name = "d64";
1227 break;
1228 }
1229 return str::asprintf("%s-%d-%d-%s",
1230 language.empty() ? _("unknown") : language.c_str(),
1231 channels, rate, sample_format_name);
1232 }
1233
sample_bits() const1234 int audio_blob::sample_bits() const
1235 {
1236 int bits = 0;
1237 switch (sample_format)
1238 {
1239 case u8:
1240 bits = 8;
1241 break;
1242 case s16:
1243 bits = 16;
1244 break;
1245 case f32:
1246 bits = 32;
1247 break;
1248 case d64:
1249 bits = 64;
1250 break;
1251 }
1252 return bits;
1253 }
1254
subtitle_box()1255 subtitle_box::subtitle_box() :
1256 language(),
1257 format(text),
1258 style(),
1259 str(),
1260 images(),
1261 presentation_start_time(std::numeric_limits<int64_t>::min()),
1262 presentation_stop_time(std::numeric_limits<int64_t>::min())
1263 {
1264 }
1265
format_info() const1266 std::string subtitle_box::format_info() const
1267 {
1268 return (language.empty() ? _("unknown") : language);
1269 }
1270
format_name() const1271 std::string subtitle_box::format_name() const
1272 {
1273 return (language.empty() ? _("unknown") : language);
1274 }
1275
save(std::ostream & os) const1276 void subtitle_box::image_t::save(std::ostream &os) const
1277 {
1278 s11n::save(os, w);
1279 s11n::save(os, h);
1280 s11n::save(os, x);
1281 s11n::save(os, y);
1282 s11n::save(os, palette.size());
1283 if (palette.size() > 0)
1284 {
1285 s11n::save(os, static_cast<const void *>(&(palette[0])), palette.size() * sizeof(uint8_t));
1286 }
1287 s11n::save(os, data.size());
1288 if (data.size() > 0)
1289 {
1290 s11n::save(os, static_cast<const void *>(&(data[0])), data.size() * sizeof(uint8_t));
1291 }
1292 s11n::save(os, linesize);
1293 }
1294
load(std::istream & is)1295 void subtitle_box::image_t::load(std::istream &is)
1296 {
1297 size_t s;
1298 s11n::load(is, w);
1299 s11n::load(is, h);
1300 s11n::load(is, x);
1301 s11n::load(is, y);
1302 s11n::load(is, s);
1303 palette.resize(s);
1304 if (palette.size() > 0)
1305 {
1306 s11n::load(is, static_cast<void *>(&(palette[0])), palette.size() * sizeof(uint8_t));
1307 }
1308 s11n::load(is, s);
1309 data.resize(s);
1310 if (data.size() > 0)
1311 {
1312 s11n::load(is, static_cast<void *>(&(data[0])), data.size() * sizeof(uint8_t));
1313 }
1314 s11n::load(is, linesize);
1315 }
1316
save(std::ostream & os) const1317 void subtitle_box::save(std::ostream &os) const
1318 {
1319 s11n::save(os, language);
1320 s11n::save(os, static_cast<int>(format));
1321 s11n::save(os, style);
1322 s11n::save(os, str);
1323 s11n::save(os, images);
1324 s11n::save(os, presentation_start_time);
1325 s11n::save(os, presentation_stop_time);
1326 }
1327
load(std::istream & is)1328 void subtitle_box::load(std::istream &is)
1329 {
1330 s11n::load(is, language);
1331 int x;
1332 s11n::load(is, x);
1333 format = static_cast<format_t>(x);
1334 s11n::load(is, style);
1335 s11n::load(is, str);
1336 s11n::load(is, images);
1337 s11n::load(is, presentation_start_time);
1338 s11n::load(is, presentation_stop_time);
1339 }
1340