Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

xinevideowidget.cpp

Go to the documentation of this file.
00001 /*
00002                             This file is part of the Opie Project
00003 
00004                              Copyright (c)  2002 Max Reiss <harlekin@handhelds.org>
00005                              Copyright (c)  2002 L. Potter <ljp@llornkcor.com>
00006                              Copyright (c)  2002 Holger Freyther <zecke@handhelds.org>
00007               =.
00008             .=l.
00009            .>+-=
00010  _;:,     .>    :=|.         This program is free software; you can
00011 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00012 :`=1 )Y*s>-.--   :           the terms of the GNU General Public
00013 .="- .-=="i,     .._         License as published by the Free Software
00014  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00015      ._= =}       :          or (at your option) any later version.
00016     .%`+i>       _;_.
00017     .i_,=:_.      -<s.       This program is distributed in the hope that
00018      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00019     : ..    .:,     . . .    without even the implied warranty of
00020     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00021   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00022 ..}^=.=       =       ;      Library General Public License for more
00023 ++=   -.     .`     .:       details.
00024  :     =  ...= . :.=-
00025  -.   .:....=;==+<;          You should have received a copy of the GNU
00026   -_. . .   )=.  =           Library General Public License along with
00027     --        :-=`           this library; see the file COPYING.LIB.
00028                              If not, write to the Free Software Foundation,
00029                              Inc., 59 Temple Place - Suite 330,
00030                              Boston, MA 02111-1307, USA.
00031 
00032 */
00033 
00034 #include "xinevideowidget.h"
00035 #include <opie2/odebug.h>
00036 #include <opie2/oresource.h>
00037 
00038 #include <qimage.h>
00039 #include <qdirectpainter_qws.h>
00040 #include <qgfx_qws.h>
00041 #include <qsize.h>
00042 #include <qapplication.h>
00043 
00044 #include <pthread.h>
00045 
00046 
00047 
00048 // 0 deg rot: copy a line from src to dst (use libc memcpy)
00049 
00050 // 180 deg rot: copy a line from src to dst reversed
00051 
00052 /*
00053  * This code relies the len be a multiply of 16bit
00054  */
00055 static inline void memcpy_rev ( void *_dst, void *_src, size_t len )
00056 {
00057 
00058     /*
00059      * move the source to the end
00060      */
00061     char *src_c = static_cast<char*>(_src) + len;
00062 
00063     /*
00064      * as we copy by 16bit and not 8bit
00065      * devide the length by two
00066      */
00067     len >>= 1;
00068 
00069     short int* dst = static_cast<short int*>( _dst );
00070     short int* src = reinterpret_cast<short int*>( src_c );
00071 
00072     /*
00073      * Increment dst after assigning
00074      * Decrement src before  assigning becase we move backwards
00075      */
00076     while ( len-- )
00077         *dst++ = *--src;
00078 
00079 }
00080 
00081 // 90 deg rot: copy a column from src to dst
00082 
00083 static inline void memcpy_step ( void *_dst, void *_src, size_t len, size_t step )
00084 {
00085     short int *dst = static_cast<short int*>( _dst );
00086     short int *src = static_cast<short int*>( _src );
00087 
00088     len >>= 1;
00089 
00090     /*
00091      * Copy 16bit from src to dst and move to the next address
00092      */
00093     while ( len-- ) {
00094         *dst++ = *src;
00095         src = reinterpret_cast<short int*>(reinterpret_cast<char*>(src)+step);
00096     }
00097 }
00098 
00099 // 270 deg rot: copy a column from src to dst reversed
00100 
00101 static inline void memcpy_step_rev ( void *_dst, void *_src, size_t len, size_t step )
00102 {
00103     len >>= 1;
00104 
00105     char *src_c = static_cast<char*>( _src ) + (len*step);
00106     short int* dst = static_cast<short int*>( _dst );
00107     short int* src = reinterpret_cast<short int*>( src_c );
00108 
00109     while ( len-- ) {
00110         src_c -= step;
00111         src = reinterpret_cast<short int*>( src_c );
00112         *dst++ = *src;
00113     }
00114 }
00115 
00116 
00117 XineVideoWidget::XineVideoWidget ( QWidget* parent, const char* name )
00118     : QWidget ( parent, name, WRepaintNoErase | WResizeNoErase ),old_framerect(0,0,0,0),old_size(0,0)
00119 {
00120     setBackgroundMode ( NoBackground );
00121 
00122     m_logo              = 0;
00123     m_buff              = 0;
00124     m_bytes_per_line_fb = qt_screen-> linestep ( );
00125     m_bytes_per_pixel   = ( qt_screen->depth() + 7 ) / 8;
00126     m_rotation          = 0;
00127     m_lastsize = 0;
00128 }
00129 
00130 
00131 XineVideoWidget::~XineVideoWidget ( )
00132 {
00133 #if 0
00134     if (m_buff) {
00135         delete[]m_buff;
00136         m_lastsize=0;
00137         m_buff = 0;
00138     }
00139 #endif
00140     if (m_logo) {
00141         delete m_logo;
00142     }
00143 }
00144 
00145 void XineVideoWidget::clear ( )
00146 {
00147 #if 0
00148     ThreadUtil::AutoLock a(m_bufmutex);
00149     if (m_buff) {
00150         delete[]m_buff;
00151         m_lastsize=0;
00152         m_buff = 0;
00153     }
00154 #endif
00155     repaint ( false );
00156 }
00157 
00158 QSize XineVideoWidget::videoSize() const
00159 {
00160     QSize s = size();
00161     bool fs = ( s == qApp->desktop()->size() );
00162 
00163     // if we are in fullscreen mode, do not rotate the video
00164     // (!! the paint routine uses m_rotation + qt_screen-> transformOrientation() !!)
00165     m_rotation = fs ? - qt_screen->transformOrientation() : 0;
00166 
00167     if ( fs && qt_screen->isTransformed() )
00168         s = qt_screen->mapToDevice( s );
00169 
00170     return s;
00171 }
00172 
00173 void XineVideoWidget::paintEvent ( QPaintEvent * )
00174 {
00175     QPainter p ( this );
00176     p. fillRect ( rect (), black );
00177     if (m_logo)
00178         p. drawImage ( 0, 0, *m_logo );
00179 }
00180 
00181 void XineVideoWidget::paintEvent2 ( QPaintEvent * )
00182 {
00183     if ( m_buff == 0 ) {
00184         return;
00185     } else if (m_lastsize){
00186         {
00187             QDirectPainter dp ( this );
00188             int rot = dp. transformOrientation ( ) + m_rotation; // device rotation + custom rotation
00189             bool rot90 = (( -m_rotation ) & 1 );
00190             int _vw,_vh;
00191             switch (rot90) {
00192                 case true:
00193                     _vh = m_framesize.width();
00194                     _vw = m_framesize.height();
00195                     break;
00196                 default:
00197                     _vw = m_framesize.width();
00198                     _vh = m_framesize.height();
00199                     break;
00200                  break;
00201             }
00202             int middle_w = _vw/2;
00203             int middle_h = _vh/2;
00204             m_thisframe.setRect(width()/2-middle_w,height()/2-middle_h,_vw,_vh);
00205             uchar *fb = dp. frameBuffer ( );
00206             uchar *frame = m_buff;
00207 
00208             // where is the video frame in fb coordinates
00209             QRect framerect = qt_screen-> mapToDevice ( QRect ( mapToGlobal ( m_thisframe. topLeft ( )), m_thisframe. size ( )), QSize ( qt_screen-> width ( ),
00210                              qt_screen-> height ( )));
00211 
00212             uchar * src = frame;
00213             uchar * dst = fb+framerect.y()*m_bytes_per_line_fb+framerect.x()*m_bytes_per_pixel;
00214 
00215             /* clean up the fb screen when shrinking the image only! */
00216             if (old_framerect.isValid() && old_size.width()==width()&&old_size.height()==height() &&
00217                 (old_framerect.width()>framerect.width() || old_framerect.height()>framerect.height())) {
00218                 uchar*_dst = fb+old_framerect.y()*m_bytes_per_line_fb+old_framerect.x()*m_bytes_per_pixel;
00219                 for (int z=0;z<old_framerect.height();++z) {
00220                     memset(_dst,0,m_bytes_per_line_fb);
00221                     _dst+=m_bytes_per_line_fb;
00222                 }
00223             }
00224             old_framerect=framerect;
00225             old_size = size();
00226 
00227             if (framerect.height()!=m_framesize.height()) {
00228                 odebug << "Hoehm: " << framerect.height() << " <-> " << m_framesize.height() << oendl;
00229             }
00230             for (int y = 0;y<framerect.height();++y) {
00231                 switch (rot) {
00232                     case 0:
00233                         memcpy(dst,src,m_bytes_per_line_frame);
00234                         src+=m_bytes_per_line_frame;
00235                     break;
00236                     case 1:
00237                         memcpy_step ( dst, src, m_thisframe.size().width(), m_bytes_per_line_frame );
00238                         src -= m_bytes_per_pixel;
00239                         break;
00240                     case 2:
00241                         memcpy_rev ( dst, src, m_thisframe.size().width());
00242                         src-=m_bytes_per_line_frame;
00243                     break;
00244                     case 3:
00245                         memcpy_step_rev ( dst, src, m_thisframe.size().width(), m_bytes_per_line_frame );
00246                         src += m_bytes_per_pixel;
00247                     break;
00248                     default:
00249                         break;
00250                 }
00251                 dst += m_bytes_per_line_fb;
00252             }
00253         }
00254     }
00255 }
00256 
00257 QImage *XineVideoWidget::logo ( ) const
00258 {
00259     return m_logo;
00260 }
00261 
00262 
00263 void XineVideoWidget::setLogo ( QImage* logo )
00264 {
00265     delete m_logo;
00266     m_logo = logo;
00267 }
00268 
00269 void XineVideoWidget::setVideoFrame ( uchar* img, int w, int h, int bpl )
00270 {
00271     // mutex area for AutoLock
00272     {
00273 #if 0
00274         ThreadUtil::AutoLock a(m_bufmutex);
00275 #endif
00276         if (!isVisible()||w>width()||h>height()/*||m_bufmutex.isLocked()*/) {
00277             //drop frame
00278             return;
00279         }
00280         bool rot90 = (( -m_rotation ) & 1 );
00281         int l = h*bpl;
00282 #if 0
00283         if (l!=m_lastsize) {
00284             if (m_buff) {
00285                 delete[]m_buff;
00286             }
00287             if (l>0) {
00288                 m_buff = new uchar[l];
00289                 odebug << "Point to: " << (unsigned long)m_buff << oendl;
00290                 m_lastsize=l;
00291             } else {
00292                 m_buff = 0;
00293             }
00294         }
00295 #endif
00296         m_lastsize = l;
00297         m_framesize = QSize(w,h);
00298 #if 0
00299         if (m_buff && m_lastsize) {
00300             memcpy(m_buff,img,m_lastsize);
00301         }
00302 #endif
00303         m_buff = img;
00304         m_bytes_per_line_frame = bpl;
00305         if (m_buff) paintEvent2(0);
00306     } // Release Mutex
00307 }
00308 
00309 void XineVideoWidget::resizeEvent ( QResizeEvent * )
00310 {
00311 #if 0
00312     ThreadUtil::AutoLock a(m_bufmutex);
00313 #endif
00314     emit videoResized( videoSize() );
00315     odebug << "All resize done" << oendl;
00316 }
00317 
00318 
00319 void XineVideoWidget::mouseReleaseEvent ( QMouseEvent * /*me*/ )
00320 {
00321     emit clicked();
00322 }
00323 

Generated on Sat Nov 5 16:17:33 2005 for OPIE by  doxygen 1.4.2