VideoRenderer.hpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: VideoRenderer.hpp * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * $Id: VideoRenderer.hpp,v 1.15 2006/01/26 11:42:00 mkropfbe Exp $ 00041 * * 00042 ***********************************************************************/ 00043 00044 #ifndef _VIDEORENDERER_HPP 00045 #define _VIDEORENDERER_HPP 00046 00047 #include "IO.hpp" 00048 #include "VideoESInfo.hpp" 00049 #include "adaptors/MP4Decoder.hpp" 00050 #include "VideoFrameBuffer.hpp" 00051 00052 class VideoFrameBuffer; 00053 00054 00078 class VideoRenderer : public IO 00079 { 00080 public: 00081 /* struct used for various video rectangles */ 00082 typedef struct { 00083 int width; 00084 int height; 00085 int size; // in bytes 00086 int ySize; // if ColorSpace == YUV, then size of Y-part 00087 int uvSize; // if ColorSpace == YUV, then size of UV-parts 00088 int top; 00089 int bottom; 00090 int left; 00091 int right; 00092 u32 scaleX; 00093 u32 scaleY; 00094 bool isLabelResizable; 00095 bool allowUpscaleX; 00096 bool fixAspectRatio; 00097 } VideoRect; 00098 00099 00100 00123 VideoRenderer(const VideoESInfo *es, UncompressedVideoFrame::ColorSpace colorSpace, 00124 int width, int height, bool isLabelResizable = true, bool fixAspectRatio = true, 00125 bool allowUpscaleX = false); 00126 00128 virtual ~VideoRenderer(); 00129 00131 virtual Frame *getFrame() { 00132 #ifdef _POSIX_PRIORITY_SCHEDULING 00133 sched_yield(); //this is necessary to give parallel getFrames a chance 00134 #endif 00135 return NULL; 00136 }; 00137 00138 /* necessary for eg. X11, where the output may be 16bit, but the decoded video is RGB24/RGB32 00139 * @param outputDepth may be either 8, 16, 24, which means the output RGB coding (defaults to 24) 00140 */ 00141 void setOutputDepth(int depth); 00142 00143 /* if <code>direct</code> is set, calls the overwritten and optimized @bitBlt method 00144 * of the subclass, else the slow pixel-per-pixel painting is used 00145 */ 00146 void setDirectBitBlt(bool direct); 00147 00148 /* sets the VideoFrameBuffer, where the pixels are drawn to */ 00149 void setVideoFrameBuffer( VideoFrameBuffer *vfb ); 00150 00154 virtual int writeFrame(Frame * frm, ESInfo *out_es=NULL); 00155 00156 00162 virtual bool open(); 00163 00169 virtual bool close(bool immediate=false) { 00170 state=CLOSED; 00171 return true; 00172 }; 00173 00178 virtual bool destroy() { 00179 return true; 00180 }; 00181 00186 virtual int getBufferFillLevel() const { 00187 return 50; 00188 }; 00189 00191 virtual const char *getURL() const { 00192 return url; 00193 }; 00194 00196 virtual void setESInfo(ESInfo * es) {}; 00197 00201 virtual ESInfo* getESInfo() { return NULL;}; 00202 00203 00204 protected: 00210 bool updateDisplayRegion(); 00211 00212 //private: 00213 char url[MAX_STR_LEN]; 00214 00216 const VideoESInfo *es; 00217 00219 VideoFrameBuffer *frameBuffer; 00220 00222 UncompressedVideoFrame::ColorSpace colorSpace; 00223 00240 VideoRect frame_info; 00241 /* exact size of output label (this might be larger than frame or display) */ 00242 VideoRect out_label_info; 00243 00247 VideoRect display_region; 00248 00249 int outputDepth; 00250 00251 bool directBitBlt; 00252 00253 00254 00255 }; 00256 00257 00258 00259 00260 00261 00262 00263 /* The number of binary precision digits for fixed point arithmetic. 00264 * As the product of a pixel coordinate x and frame_info.scaleX 00265 * must fit into an u32 data type, the condition 00266 * log2(MAX(frame_info.width, frame_info.height)) + FIXED_DIGITS <= 32 00267 * must hold. So a value of 20 for FIXED_DIGITS seems to be reasonable. 00268 */ 00269 #define FIXED_DIGITS 20 00270 00271 /* Convert an unsigned integer to a fixed point number of type u32. 00272 * The integer must be less than 2^(32 - FIXED_DIGITS). 00273 */ 00274 #define INT2FIXED(i) ( (u32) ( (u32)(i) << FIXED_DIGITS ) ) 00275 00276 /* Convert a fixed point number of type u32 to floating point. */ 00277 #define FIXED2DOUBLE(f) ( (double)(f) / pow(2.0, (double)FIXED_DIGITS) ) 00278 00279 /* Multiply an integer by a fixed point number, resulting in an integer 00280 * of type u32. 00281 */ 00282 #define MULT_INT_FIXED(i, f) ( (u32) ( ( (u32)(i)*(u32)(f) ) >> FIXED_DIGITS ) ) 00283 00284 /* Divide two integers, resulting in a fixed point number of type u32. */ 00285 #define DIV_FIXED(i, k) ( (u32) ( ( (u32)(i) << FIXED_DIGITS ) / (u32)(k) ) ) 00286 00287 00288 00289 00290 00291 00292 /* Macro used in writeFrame() to compute a scaled frame in frameBuffer. 00293 * Parameters: depth - pixel depth in bytes. 00294 * rgb - expression computing an RGB value from the pointer pix 00295 * to a pixel in the decoded frame. 00296 */ 00297 #define SCALE_FRAME(depth, rgb) \ 00298 for (y = display_region.top, y0 = 0; y < display_region.bottom; y++, y0++) { \ 00299 yframe = (frame_info.scaleY == one) ? y0 : MULT_INT_FIXED(y0, frame_info.scaleY); \ 00300 pixline = au->payload + yframe * frame_info.width * (depth); \ 00301 for (x = display_region.left, x0 = 0; x < display_region.right; x++, x0++) { \ 00302 pix = pixline + MULT_INT_FIXED(x0, frame_info.scaleX) * (depth); \ 00303 frameBuffer->setPixel(x, y, (uint)(rgb)); \ 00304 } \ 00305 } 00306 00307 /* Macro used in writeFrame() to compute a scaled frame in frameBuffer. 00308 * Optimized version for scaling in y-direction only. 00309 * Parameters: depth - pixel depth in bytes. 00310 * rgb - expression computing an RGB value from the pointer pix 00311 * to a pixel in the decoded frame. 00312 */ 00313 #define SCALE_FRAME_Y(depth, rgb) \ 00314 for (y = display_region.top, y0 = 0; y < display_region.bottom; y++, y0++) { \ 00315 yframe = (frame_info.scaleY == one) ? y0 : MULT_INT_FIXED(y0, frame_info.scaleY); \ 00316 pix = au->payload + yframe * frame_info.width * (depth); \ 00317 for (x = display_region.left; x < display_region.right; x++) { \ 00318 frameBuffer->setPixel(x, y, (uint)(rgb)); \ 00319 pix += (depth); \ 00320 } \ 00321 } 00322 00323 /* Macro used in writeFrame() to copy a frame to frameBuffer. 00324 * Optimized version for no scaling. 00325 * if directBitBlt is set, a even more sophisticated subclass method is calledmuh 00326 * Parameters: depth - pixel depth in bytes. 00327 * rgb - expression computing an RGB value from the pointer pix 00328 * to a pixel in the decoded frame. 00329 */ 00330 #define COPY_FRAME(depth, rgb) \ 00331 if (directBitBlt) { \ 00332 frameBuffer->bitBlt(au); \ 00333 } else { \ 00334 dprintf_full("CHOOSE_SCALE slow COPY_FRAME depth %i\n",depth); \ 00335 pix = au->payload; \ 00336 for (y = display_region.top; y < display_region.bottom; y++) { \ 00337 for (x = display_region.left; x < display_region.right; x++) { \ 00338 frameBuffer->setPixel(x, y, (uint)(rgb)); \ 00339 pix += (depth); \ 00340 } \ 00341 } \ 00342 } 00343 00344 00345 00346 00347 /* Macro used in writeFrame() to choose an optimized scaling routine 00348 * based on the values of frame_info.scaleX and frame_info.scaleY. 00349 * Parameters: depth - pixel depth in bytes. 00350 * rgb - expression computing an RGB value from the pointer pix 00351 * to a pixel in the decoded frame. 00352 */ 00353 #define CHOOSE_SCALE_FRAME(depth, rgb) \ 00354 if (frame_info.scaleX == one && frame_info.scaleY == one) { \ 00355 COPY_FRAME(depth, rgb); \ 00356 } else if (frame_info.scaleX == one) { \ 00357 SCALE_FRAME_Y(depth, rgb) \ 00358 } else { \ 00359 SCALE_FRAME(depth, rgb) \ 00360 } 00361 00362 00363 00364 #endif /* _VIDEORENDERER_HPP */