1 /* 2 * This file is part of bino, a 3D video player. 3 * 4 * Copyright (C) 2010, 2011, 2012, 2015, 2016 5 * Martin Lambers <marlam@marlam.de> 6 * Frédéric Devernay <Frederic.Devernay@inrialpes.fr> 7 * Joe <cuchac@email.cz> 8 * Binocle <http://binocle.com> (author: Olivier Letz <oletz@binocle.com>) 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 3 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef VIDEO_OUTPUT_H 25 #define VIDEO_OUTPUT_H 26 27 #include <vector> 28 #include <string> 29 30 #include <GL/glew.h> 31 32 #include "base/blb.h" 33 34 #include "media_data.h" 35 #include "subtitle_renderer.h" 36 #include "dispatch.h" 37 38 39 class subtitle_updater; 40 #if HAVE_LIBXNVCTRL 41 class CNvSDIout; 42 #endif // HAVE_LIBXNVCTRL 43 44 class video_output : public controller 45 { 46 private: 47 bool _initialized; 48 49 /* We manage two frames, each with its own set of properties etc. 50 * The active frame is the one that is displayed, the other frame is the one 51 * that is prepared for display. 52 * Each frame contains a left view and may contain a right view. */ 53 int _active_index; // 0 or 1 54 55 video_frame _frame[2]; // input frames (active / preparing) 56 // Step 1: input of video data 57 video_frame _input_last_frame; // last frame for this step 58 GLuint _input_pbo; // pixel-buffer object for texture uploading 59 GLuint _input_fbo; // frame-buffer object for texture clearing 60 GLuint _input_yuv_y_tex[2]; // for yuv formats: y component 61 GLuint _input_yuv_u_tex[2]; // for yuv formats: u component 62 GLuint _input_yuv_v_tex[2]; // for yuv formats: v component 63 GLuint _input_bgra32_tex[2]; // for bgra32 format 64 int _input_yuv_chroma_width_divisor; // for yuv formats: chroma subsampling 65 int _input_yuv_chroma_height_divisor; // for yuv formats: chroma subsampling 66 subtitle_box _subtitle[2]; // the current subtitle box 67 GLuint _subtitle_tex[2]; // subtitle texture 68 bool _subtitle_tex_current[2]; // whether the subtitle tex contains the current subtitle buffer 69 // Step 2: color space conversion and color correction 70 parameters _color_last_params[2]; // last params for this step; used for reinitialization check 71 video_frame _color_last_frame[2]; // last frame for this step; used for reinitialization check 72 GLuint _color_prg[2]; // color space transformation, color adjustment 73 GLuint _color_fbo; // framebuffer object to render into the sRGB texture 74 GLuint _color_tex[2][2]; // output: SRGB8 or linear RGB16 texture 75 // Step 3: rendering 76 parameters _render_params; // current parameters for display 77 parameters _render_last_params; // last params for this step; used for reinitialization check 78 video_frame _render_last_frame; // last frame for this step; used for reinitialization check 79 GLuint _render_prg; // reads sRGB texture, renders according to _params[_active_index] 80 GLuint _render_dummy_tex; // an empty subtitle texture 81 GLuint _render_mask_tex; // for the masking modes even-odd-{rows,columns}, checkerboard 82 blob _3d_ready_sync_buf; // for 3-D Ready Sync pixels 83 // OpenGL viewports and tex coordinates for drawing the two views of the video frame 84 GLint _full_viewport[4]; 85 GLint _viewport[2][4]; 86 float _tex_coords[2][4][2]; 87 88 subtitle_updater *_subtitle_updater; // the subtitle updater thread 89 #if HAVE_LIBXNVCTRL 90 CNvSDIout *_nv_sdi_output; // access the nvidia quadro sdi output card 91 int64_t _last_nv_sdi_displayed_frameno; 92 #endif // HAVE_LIBXNVCTRL 93 94 // GL Helper functions 95 bool xglCheckError(const std::string& where = std::string()) const; 96 bool xglCheckFBO(const std::string& where = std::string()) const; 97 GLuint xglCompileShader(const std::string& name, GLenum type, const std::string& src) const; 98 GLuint xglCreateProgram(GLuint vshader, GLuint fshader) const; 99 GLuint xglCreateProgram(const std::string& name, 100 const std::string& vshader_src, const std::string& fshader_src) const; 101 void xglLinkProgram(const std::string& name, const GLuint prg) const; 102 void xglDeleteProgram(GLuint prg) const; 103 104 bool srgb8_textures_are_color_renderable(); 105 106 void draw_quad(float x, float y, float w, float h, 107 const float tex_coords[2][4][2] = NULL, 108 const float more_tex_coords[4][2] = NULL) const; 109 110 // Step 1: initialize/deinitialize, and check if reinitialization is necessary 111 void input_init(const video_frame &frame); 112 void input_deinit(); 113 bool input_is_compatible(const video_frame ¤t_frame); 114 void subtitle_init(int index); 115 void subtitle_deinit(int index); 116 // Step 2: initialize/deinitialize, and check if reinitialization is necessary 117 void color_init(int index, const parameters& params, const video_frame &frame); 118 void color_deinit(int index); 119 bool color_is_compatible(int index, const parameters& params, const video_frame ¤t_frame); 120 // Step 3: initialize/deinitialize, and check if reinitialization is necessary 121 void render_init(); 122 void render_deinit(); 123 bool render_needs_subtitle(const parameters& params); 124 bool render_needs_coloradjust(const parameters& params); 125 bool render_needs_ghostbust(const parameters& params); 126 bool render_is_compatible(); 127 128 protected: 129 subtitle_renderer _subtitle_renderer; 130 131 #ifdef GLEW_MX 132 virtual GLEWContext* glewGetContext() const = 0; 133 #endif 134 135 // Get the total viewport size. 136 int full_display_width() const; 137 int full_display_height() const; 138 // Get size of the viewport area that is used for video. This is overridable for Equalizer. 139 virtual int video_display_width() const; 140 virtual int video_display_height() const; 141 142 virtual bool context_is_stereo() const = 0; // Is our current OpenGL context a stereo context? 143 virtual void recreate_context(bool stereo) = 0; // Recreate an OpenGL context and make it current 144 virtual void trigger_resize(int w, int h) = 0; // Trigger a resize the video area 145 146 void clear() const; // Clear the video area 147 void reshape(int w, int h, const parameters& params = dispatch::parameters()); // Call this when the video area was resized 148 149 /* Get screen properties (fixed) */ 150 virtual int screen_width() const = 0; // in pixels 151 virtual int screen_height() const = 0; // in pixels 152 virtual float screen_pixel_aspect_ratio() const = 0;// the aspect ratio of a pixel on screen 153 154 /* Get current video area properties */ 155 virtual int width() const = 0; // in pixels 156 virtual int height() const = 0; // in pixels 157 virtual int pos_x() const = 0; // in pixels 158 virtual int pos_y() const = 0; // in pixels 159 160 /* Display the current frame. 161 * The first version is used by Equalizer, which needs to set some special properties. 162 * The second version is used by NVIDIA SDI output. 163 * The third version is for everyone else. 164 * TODO: This function needs to handle interlaced frames! */ 165 void display_current_frame(int64_t display_frameno, bool keep_viewport, bool mono_right_instead_of_left, 166 float x, float y, float w, float h, 167 const GLint viewport[2][4], const float tex_coords[2][4][2], 168 int dst_width, int dst_height, 169 parameters::stereo_mode_t stereo_mode); display_current_frame(int64_t display_frameno,int dst_width,int dst_height,parameters::stereo_mode_t stereo_mode)170 void display_current_frame(int64_t display_frameno, int dst_width, int dst_height, parameters::stereo_mode_t stereo_mode) 171 { 172 display_current_frame(display_frameno, false, false, -1.0f, -1.0f, 2.0f, 2.0f, 173 _viewport, _tex_coords, dst_width, dst_height, stereo_mode); 174 } 175 void display_current_frame(int64_t display_frameno = 0) 176 { 177 display_current_frame(display_frameno, false, false, -1.0f, -1.0f, 2.0f, 2.0f, 178 _viewport, _tex_coords, full_display_width(), full_display_height(), 179 dispatch::parameters().stereo_mode()); 180 } 181 182 #if HAVE_LIBXNVCTRL 183 void sdi_output(int64_t display_frameno = 0); 184 #endif // HAVE_LIBXNVCTRL 185 186 public: 187 /* Constructor, Destructor */ 188 video_output(); 189 virtual ~video_output(); 190 191 /* Initialize the video output, or throw an exception */ 192 virtual void init(); 193 /* Wait for subtitle renderer initialization to finish. Has to be called 194 * if the video has subtitles. Returns the number of microseconds that the 195 * waiting took. */ 196 virtual int64_t wait_for_subtitle_renderer() = 0; 197 /* Deinitialize the video output */ 198 virtual void deinit(); 199 200 /* Set a video area size suitable for the given input/output settings */ 201 void set_suitable_size(int w, int h, float ar, parameters::stereo_mode_t stereo_mode); 202 203 /* Get capabilities */ 204 virtual bool supports_stereo() const = 0; // Is OpenGL quad buffered stereo available? 205 206 /* Center video area on screen */ 207 virtual void center() = 0; 208 209 /* Enter/exit fullscreen mode */ 210 virtual void enter_fullscreen() = 0; 211 virtual void exit_fullscreen() = 0; 212 213 /* Process window system events (if applicable) */ 214 virtual void process_events() = 0; 215 216 /* Prepare a new frame for display. */ 217 virtual void prepare_next_frame(const video_frame &frame, const subtitle_box &subtitle); 218 /* Switch to the next frame (make it the current one) */ 219 virtual void activate_next_frame(); 220 /* Get an estimation of when the next frame will appear on screen */ 221 virtual int64_t time_to_next_frame_presentation() const; 222 }; 223 224 #endif 225