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