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 #ifndef MEDIA_DATA_H
26 #define MEDIA_DATA_H
27 
28 #include <string>
29 #include <stdint.h>
30 
31 #include "base/ser.h"
32 #include "base/msg.h"
33 
34 
35 class device_request : public serializable
36 {
37 public:
38     typedef enum
39     {
40         no_device,      // No device request.
41         sys_default,    // Request for system default video device type.
42         firewire,       // Request for a firefire video device.
43         x11,            // Request for an X11 grabber.
44     } device_t;
45 
46     device_t device;    // The device type.
47     int width;          // Request frames of the given width (0 means default).
48     int height;         // Request frames of the given height (0 means default).
49     int frame_rate_num; // Request a specific frame rate (0/0 means default).
50     int frame_rate_den; // For example 1/25, 1/30, ...
51     bool request_mjpeg; // Request MJPEG format from device
52 
53     // Constructor
54     device_request();
55 
56     // Is this a request for a device?
is_device()57     bool is_device() const
58     {
59         return device != no_device;
60     }
61 
62     // Serialization
63     void save(std::ostream &os) const;
64     void load(std::istream &is);
65 };
66 
67 class parameters : public serializable
68 {
69 public:
70 
71     // Stereo layout: describes how left and right view are stored
72     typedef enum {
73         layout_mono,           // 1 video source: center view
74         layout_separate,       // 2 video sources: left and right view independent
75         layout_alternating,    // 2 video sources: left and right view consecutively
76         layout_top_bottom,     // 1 video source: left view top, right view bottom, both with full size
77         layout_top_bottom_half,// 1 video source: left view top, right view bottom, both with half size
78         layout_left_right,     // 1 video source: left view left, right view right, both with full size
79         layout_left_right_half,// 1 video source: left view left, right view right, both with half size
80         layout_even_odd_rows   // 1 video source: left view even lines, right view odd lines
81     } stereo_layout_t;
82 
83     // Convert the stereo layout to and from a string representation
84     static std::string stereo_layout_to_string(stereo_layout_t stereo_layout, bool stereo_layout_swap);
85     static void stereo_layout_from_string(const std::string &s, stereo_layout_t &stereo_layout, bool &stereo_layout_swap);
86     static bool parse_stereo_layout(const std::string& s, stereo_layout_t* stereo_layout);
87 
88     // Stereo mode: the output mode for left and right view
89     typedef enum {
90         mode_stereo,                   // OpenGL quad buffered stereo
91         mode_alternating,              // Left and right view alternating
92         mode_mono_left,                // Left view only
93         mode_mono_right,               // Right view only
94         mode_top_bottom,               // Left view top, right view bottom
95         mode_top_bottom_half,          // Left view top, right view bottom, half height
96         mode_left_right,               // Left view left, right view right
97         mode_left_right_half,          // Left view left, right view right, half width
98         mode_even_odd_rows,            // Left view even rows, right view odd rows
99         mode_even_odd_columns,         // Left view even columns, right view odd columns
100         mode_checkerboard,             // Checkerboard pattern
101         mode_hdmi_frame_pack,          // HDMI Frame packing (top-bottom separated by 1/49 height)
102         mode_red_cyan_monochrome,      // Red/cyan anaglyph, monochrome method
103         mode_red_cyan_half_color,      // Red/cyan anaglyph, half color method
104         mode_red_cyan_full_color,      // Red/cyan anaglyph, full color method
105         mode_red_cyan_dubois,          // Red/cyan anaglyph, high quality Dubois method
106         mode_green_magenta_monochrome, // Green/magenta anaglyph, monochrome method
107         mode_green_magenta_half_color, // Green/magenta anaglyph, half color method
108         mode_green_magenta_full_color, // Green/magenta anaglyph, full color method
109         mode_green_magenta_dubois,     // Green/magenta anaglyph, high quality Dubois method
110         mode_amber_blue_monochrome,    // Amber/blue anaglyph, monochrome method
111         mode_amber_blue_half_color,    // Amber/blue anaglyph, half color method
112         mode_amber_blue_full_color,    // Amber/blue anaglyph, full color method
113         mode_amber_blue_dubois,        // Amber/blue anaglyph, high quality Dubois method
114         mode_red_green_monochrome,     // Red/green anaglyph, monochrome method
115         mode_red_blue_monochrome,      // Red/blue anaglyph, monochrome method
116     } stereo_mode_t;
117 
118     // Convert the stereo mode to and from a string representation
119     static std::string stereo_mode_to_string(stereo_mode_t stereo_mode, bool stereo_mode_swap);
120     static void stereo_mode_from_string(const std::string &s, stereo_mode_t &stereo_mode, bool &stereo_mode_swap);
121     static bool parse_stereo_mode(const std::string& s, stereo_mode_t* stereo_mode);
122 
123     typedef enum {
124         no_loop,                        // Do not loop.
125         loop_current,                   // Loop the current media input.
126     } loop_mode_t;
127 
128     // Convert the loop mode to and from a string representation
129     static std::string loop_mode_to_string(loop_mode_t loop_mode);
130     static loop_mode_t loop_mode_from_string(const std::string &s);
131 
132 #define PARAMETER(TYPE, NAME) \
133     private: \
134     TYPE _ ## NAME; \
135     bool _ ## NAME ## _set; \
136     static const TYPE _ ## NAME ## _default; \
137     public: \
138     TYPE NAME() const \
139     { \
140         return _ ## NAME ## _set ? _ ## NAME : _ ## NAME ## _default; \
141     } \
142     void set_ ## NAME(TYPE val) \
143     { \
144         _ ## NAME = val; \
145         _ ## NAME ## _set = true; \
146     } \
147     void unset_ ## NAME() \
148     { \
149         _ ## NAME ## _set = false; \
150     } \
151     bool NAME ## _is_set() const \
152     { \
153         return _ ## NAME ## _set; \
154     } \
155     bool NAME ## _is_default() const \
156     { \
157         return (NAME() >= _ ## NAME ## _default && NAME() <= _ ## NAME ## _default); \
158     }
159 
160     // Invariant parameters
161     PARAMETER(msg::level_t, log_level)        // Global log level
162     PARAMETER(bool, benchmark)                // Benchmark mode
163     PARAMETER(int, swap_interval)             // Swap interval
164     // Per-Session parameters
165     PARAMETER(int, audio_device)              // Audio output device index, -1 = default
166     PARAMETER(int, quality)                   // Rendering quality, 0=fastest .. 4=best
167     PARAMETER(stereo_mode_t, stereo_mode)     // Stereo mode
168     PARAMETER(bool, stereo_mode_swap)         // Swap left and right view
169     PARAMETER(float, crosstalk_r)             // Crosstalk level for red, 0 .. 1
170     PARAMETER(float, crosstalk_g)             // Crosstalk level for green, 0 .. 1
171     PARAMETER(float, crosstalk_b)             // Crosstalk level for blue, 0 .. 1
172     PARAMETER(int, fullscreen_screens)        // Screens to use in fullscreen mode (bit set), 0=primary screen
173     PARAMETER(bool, fullscreen_flip_left)     // Flip left view vertically in fullscreen mode
174     PARAMETER(bool, fullscreen_flop_left)     // Flop left view horizontally in fullscreen mode
175     PARAMETER(bool, fullscreen_flip_right)    // Flip right view vertically in fullscreen mode
176     PARAMETER(bool, fullscreen_flop_right)    // Flop right view horizontally in fullscreen mode
177     PARAMETER(bool, fullscreen_inhibit_screensaver)     // Inhibit screensaver when in fullscreen mode
178     PARAMETER(bool, fullscreen_3d_ready_sync) // Use DLP 3-D Ready Sync in fullscreen mode
179     PARAMETER(float, contrast)                // Contrast adjustment, -1 .. +1
180     PARAMETER(float, brightness)              // Brightness adjustment, -1 .. +1
181     PARAMETER(float, hue)                     // Hue adjustment, -1 .. +1
182     PARAMETER(float, saturation)              // Saturation adjustment, -1 .. +1
183     PARAMETER(float, zoom)                    // Zoom, 0 = off (show full video width) .. 1 = full (use full screen height)
184     PARAMETER(loop_mode_t, loop_mode)         // Current loop behaviour.
185     PARAMETER(int64_t, audio_delay)           // Audio delay in microseconds
186     PARAMETER(std::string, subtitle_encoding) // Subtitle encoding, empty means keep default
187     PARAMETER(std::string, subtitle_font)     // Subtitle font name, empty means keep default
188     PARAMETER(int, subtitle_size)             // Subtitle point size, -1 means keep default
189     PARAMETER(float, subtitle_scale)          // Scale factor
190     PARAMETER(uint64_t, subtitle_color)       // Subtitle color in uint32_t bgra32 format, > UINT32_MAX means keep default
191     PARAMETER(int, subtitle_shadow)           // Subtitle shadow, -1 = default, 0 = force off, 1 = force on
192 #if HAVE_LIBXNVCTRL
193     PARAMETER(int, sdi_output_format)         // SDI output format
194     PARAMETER(stereo_mode_t, sdi_output_left_stereo_mode)  // SDI output left stereo mode
195     PARAMETER(stereo_mode_t, sdi_output_right_stereo_mode) // SDI output right stereo mode
196 #endif // HAVE_LIBXNVCTRL
197     // Per-Video parameters
198     PARAMETER(int, video_stream)              // Video stream index
199     PARAMETER(int, audio_stream)              // Audio stream index, or -1 if there is no audio stream
200     PARAMETER(int, subtitle_stream)           // Subtitle stream index, or -1 to disable subtitles
201     PARAMETER(stereo_layout_t, stereo_layout) // Assume this stereo layout
202     PARAMETER(bool, stereo_layout_swap)       // Assume this stereo layout
203     PARAMETER(float, crop_aspect_ratio)       // Crop the video to this aspect ratio, 0 = don't crop.
204     PARAMETER(float, source_aspect_ratio)     // Force video source to this aspect ratio, 0 = don't force.
205     PARAMETER(float, parallax)                // Parallax adjustment, -1 .. +1
206     PARAMETER(float, ghostbust)               // Amount of crosstalk ghostbusting, 0 .. 1
207     PARAMETER(float, subtitle_parallax)       // Subtitle parallax adjustment, -1 .. +1
208     // Volatile parameters
209     PARAMETER(bool, fullscreen)               // Fullscreen mode
210     PARAMETER(bool, center)                   // Should the video be centered?
211     PARAMETER(float, audio_volume)            // Audio volume, 0 .. 1
212     PARAMETER(bool, audio_mute)               // Audio mute: -1 = unknown, 0 = off, 1 = on
213 
214 public:
215     // Constructor
216     parameters();
217 
218     // Serialization
219     void save(std::ostream &os) const;
220     void load(std::istream &is);
221 
222     // Serialize per-session parameters
223     std::string save_session_parameters() const;
224     void load_session_parameters(const std::string &s);
225 
226     // Serialize per-video parameters
227     void unset_video_parameters();
228     std::string save_video_parameters() const;
229     void load_video_parameters(const std::string &s);
230 };
231 
232 class video_frame
233 {
234 public:
235     // Data layout
236     typedef enum
237     {
238         bgra32,         // Single plane: BGRABGRABGRA....
239         yuv444p,        // Three planes, Y/U/V, all with the same size
240         yuv422p,        // Three planes, U and V with half width: one U/V pair for 2x1 Y values
241         yuv420p,        // Three planes, U and V with half width and half height: one U/V pair for 2x2 Y values
242     } layout_t;
243 
244     // Color space
245     typedef enum
246     {
247         srgb,           // SRGB color space
248         yuv601,         // YUV according to ITU.BT-601
249         yuv709,         // YUV according to ITU.BT-709
250     } color_space_t;
251 
252     // Value range
253     typedef enum
254     {
255         u8_full,        // 0-255 for all components
256         u8_mpeg,        // 16-235 for Y, 16-240 for U and V
257         u10_full,       // 0-1023 for all components (stored in 16 bits)
258         u10_mpeg,       // 64-940 for Y, 64-960 for U and V (stored in 16 bits)
259     } value_range_t;
260 
261     // Location of chroma samples (only relevant for chroma subsampling layouts)
262     typedef enum
263     {
264         center,         // U/V at center of the corresponding Y locations
265         left,           // U/V vertically at the center, horizontally at the left Y locations
266         topleft         // U/V at the corresponding top left Y location
267     } chroma_location_t;
268 
269     int raw_width;                      // Width of the data in pixels
270     int raw_height;                     // Height of the data in pixels
271     float raw_aspect_ratio;             // Aspect ratio of the data
272     int width;                          // Width of one view in pixels
273     int height;                         // Height of one view in pixels
274     float aspect_ratio;                 // Aspect ratio of one view when displayed
275     layout_t layout;                    // Data layout
276     color_space_t color_space;          // Color space
277     value_range_t value_range;          // Value range
278     chroma_location_t chroma_location;  // Chroma sample location
279     parameters::stereo_layout_t stereo_layout; // Stereo layout
280     bool stereo_layout_swap;            // Whether the stereo layout needs to swap left and right view
281     // The data. Note that a frame does not own the data stored in these pointers,
282     // so it does not free them on destruction.
283     void *data[2][3];                   // Data pointer for 1-3 planes in 1-2 views. NULL if unused.
284     size_t line_size[2][3];             // Line size for 1-3 planes in 1-2 views. 0 if unused.
285 
286     int64_t presentation_time;          // Presentation timestamp
287 
288     // Constructor
289     video_frame();
290 
291     // Set width/height/ar from raw width/height/ar according to stereo layout
292     void set_view_dimensions();
293 
294     // Does this frame contain valid data?
is_valid()295     bool is_valid() const
296     {
297         return (raw_width > 0 && raw_height > 0);
298     }
299 
300     // Copy the data of the given view (0=left, 1=right) and the given plane (see layout)
301     // to the given destination.
302     void copy_plane(int view, int plane, void *dst) const;
303 
304     // Return a string describing the format (layout, color space, value range, chroma location)
305     std::string format_info() const;    // Human readable information
306     std::string format_name() const;    // Short code
307 };
308 
309 class audio_blob
310 {
311 public:
312     // Sample format
313     typedef enum
314     {
315         u8,             // uint8_t
316         s16,            // int16_t
317         f32,            // float
318         d64             // double
319     } sample_format_t;
320 
321     // Description of the content
322     std::string language;               // Language information (empty if unknown)
323     int channels;                       // 1 (mono), 2 (stereo), 4 (quad), 6 (5:1), 7 (6:1), or 8 (7:1)
324     int rate;                           // Samples per second
325     sample_format_t sample_format;      // Sample format
326 
327     // The data. Note that an audio blob does not own the data stored in these pointers,
328     // so it does not free them on destruction.
329     void *data;                         // Pointer to the data
330     size_t size;                        // Data size in bytes
331 
332     int64_t presentation_time;          // Presentation timestamp
333 
334     // Constructor
335     audio_blob();
336 
337     // Does this blob contain valid data?
is_valid()338     bool is_valid() const
339     {
340         return (channels > 0 && rate > 0);
341     }
342 
343     // Return a string describing the format
344     std::string format_info() const;    // Human readable information
345     std::string format_name() const;    // Short code
346 
347     // Return the number of bits the sample format
348     int sample_bits() const;
349 };
350 
351 class subtitle_box : public serializable
352 {
353 public:
354     // Format
355     typedef enum
356     {
357         ass,            // Advanced SubStation Alpha (ASS) format
358         text,           // UTF-8 text
359         image           // Image in BGRA32 format, with box coordinates
360     } format_t;
361 
362     // Image data
363     class image_t : public serializable
364     {
365     public:
366         int w, h;                       // Dimensions
367         int x, y;                       // Position w.r.t. the video frame
368         std::vector<uint8_t> palette;   // Palette, with R,G,B,A components for each palette entry.
369         std::vector<uint8_t> data;      // Bitmap using the palette
370         size_t linesize;                // Size of one bitmap line (may differ from width)
371 
372         void save(std::ostream &os) const;
373         void load(std::istream &is);
374     };
375 
376     // Description of the content
377     std::string language;               // Language information (empty if unknown)
378 
379     // Data
380     format_t format;                    // Subtitle data format
381     std::string style;                  // Style info (only if format is ass)
382     std::string str;                    // Event text (only if format ass or text)
383     std::vector<image_t> images;        // Images. These need to be alpha-blended.
384 
385     // Presentation time information
386     int64_t presentation_start_time;    // Presentation timestamp
387     int64_t presentation_stop_time;     // End of presentation timestamp
388 
389     // Constructor, Destructor
390     subtitle_box();
391 
392     // Comparison.
393     bool operator==(const subtitle_box &box) const
394     {
395         if (!is_valid() && !box.is_valid()) {
396             return true;
397         } else if (format == image) {
398             return (presentation_start_time == box.presentation_start_time
399                     && presentation_stop_time == box.presentation_stop_time);
400         } else {
401             return style == box.style && str == box.str;
402         }
403     }
404     bool operator!=(const subtitle_box &box) const
405     {
406         return !operator==(box);
407     }
408 
409     // Does this box contain valid data?
is_valid()410     bool is_valid() const
411     {
412         return (((format == ass || format == text) && !str.empty())
413                 || (format == image && !images.empty()));
414     }
415 
416     // Does this box stay constant during its complete presentation time?
417     // (ASS subtitles may be animated and thus need to be rerendered when the clock changes)
is_constant()418     bool is_constant() const
419     {
420         return (format != ass);
421     }
422 
423     // Return a string describing the format
424     std::string format_info() const;    // Human readable information
425     std::string format_name() const;    // Short code
426 
427     // Serialization
428     void save(std::ostream &os) const;
429     void load(std::istream &is);
430 };
431 
432 #endif
433