00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00049
00050
00051
00052
00053
00054
00055 static inline void memcpy_rev ( void *_dst, void *_src, size_t len )
00056 {
00057
00058
00059
00060
00061 char *src_c = static_cast<char*>(_src) + len;
00062
00063
00064
00065
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
00074
00075
00076 while ( len-- )
00077 *dst++ = *--src;
00078
00079 }
00080
00081
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
00092
00093 while ( len-- ) {
00094 *dst++ = *src;
00095 src = reinterpret_cast<short int*>(reinterpret_cast<char*>(src)+step);
00096 }
00097 }
00098
00099
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
00164
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;
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
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
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
00272 {
00273 #if 0
00274 ThreadUtil::AutoLock a(m_bufmutex);
00275 #endif
00276 if (!isVisible()||w>width()||h>height()) {
00277
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 }
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 * )
00320 {
00321 emit clicked();
00322 }
00323