summaryrefslogtreecommitdiff
authoralwin <alwin>2005-03-31 14:24:17 (UTC)
committer alwin <alwin>2005-03-31 14:24:17 (UTC)
commitb135ff0f8c4d1876eea8ecc81e2a821ec8e9cb9a (patch) (unidiff)
tree8cc7536354402f62dd99aac590dd91365abe5183
parentdb876361603ccf1664698df926a3c61d32315101 (diff)
downloadopie-b135ff0f8c4d1876eea8ecc81e2a821ec8e9cb9a.zip
opie-b135ff0f8c4d1876eea8ecc81e2a821ec8e9cb9a.tar.gz
opie-b135ff0f8c4d1876eea8ecc81e2a821ec8e9cb9a.tar.bz2
fix for the segfaults when displaying videos (it just had sometimes
invalid inputimages when repainting)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/xinevideowidget.cpp2
1 files changed, 2 insertions, 0 deletions
diff --git a/noncore/multimedia/opieplayer2/xinevideowidget.cpp b/noncore/multimedia/opieplayer2/xinevideowidget.cpp
index 1ac9277..9e86041 100644
--- a/noncore/multimedia/opieplayer2/xinevideowidget.cpp
+++ b/noncore/multimedia/opieplayer2/xinevideowidget.cpp
@@ -100,205 +100,207 @@ static inline void memcpy_step_rev ( void *_dst, void *_src, size_t len, size_t
100 len >>= 1; 100 len >>= 1;
101 101
102 char *src_c = static_cast<char*>( _src ) + (len*step); 102 char *src_c = static_cast<char*>( _src ) + (len*step);
103 short int* dst = static_cast<short int*>( _dst ); 103 short int* dst = static_cast<short int*>( _dst );
104 short int* src = reinterpret_cast<short int*>( src_c ); 104 short int* src = reinterpret_cast<short int*>( src_c );
105 105
106 while ( len-- ) { 106 while ( len-- ) {
107 src_c -= step; 107 src_c -= step;
108 src = reinterpret_cast<short int*>( src_c ); 108 src = reinterpret_cast<short int*>( src_c );
109 *dst++ = *src; 109 *dst++ = *src;
110 } 110 }
111} 111}
112 112
113 113
114XineVideoWidget::XineVideoWidget ( QWidget* parent, const char* name ) 114XineVideoWidget::XineVideoWidget ( QWidget* parent, const char* name )
115 : QWidget ( parent, name, WRepaintNoErase | WResizeNoErase ) 115 : QWidget ( parent, name, WRepaintNoErase | WResizeNoErase )
116{ 116{
117 setBackgroundMode ( NoBackground ); 117 setBackgroundMode ( NoBackground );
118 118
119 m_logo = 0; 119 m_logo = 0;
120 m_buff = 0; 120 m_buff = 0;
121 m_bytes_per_line_fb = qt_screen-> linestep ( ); 121 m_bytes_per_line_fb = qt_screen-> linestep ( );
122 m_bytes_per_pixel = ( qt_screen->depth() + 7 ) / 8; 122 m_bytes_per_pixel = ( qt_screen->depth() + 7 ) / 8;
123 m_rotation = 0; 123 m_rotation = 0;
124} 124}
125 125
126 126
127XineVideoWidget::~XineVideoWidget ( ) 127XineVideoWidget::~XineVideoWidget ( )
128{ 128{
129 delete m_logo; 129 delete m_logo;
130} 130}
131 131
132void XineVideoWidget::clear ( ) 132void XineVideoWidget::clear ( )
133{ 133{
134 m_buff = 0; 134 m_buff = 0;
135 repaint ( false ); 135 repaint ( false );
136} 136}
137 137
138QSize XineVideoWidget::videoSize() const 138QSize XineVideoWidget::videoSize() const
139{ 139{
140 QSize s = size(); 140 QSize s = size();
141 bool fs = ( s == qApp->desktop()->size() ); 141 bool fs = ( s == qApp->desktop()->size() );
142 142
143 // if we are in fullscreen mode, do not rotate the video 143 // if we are in fullscreen mode, do not rotate the video
144 // (!! the paint routine uses m_rotation + qt_screen-> transformOrientation() !!) 144 // (!! the paint routine uses m_rotation + qt_screen-> transformOrientation() !!)
145 m_rotation = fs ? - qt_screen->transformOrientation() : 0; 145 m_rotation = fs ? - qt_screen->transformOrientation() : 0;
146 146
147 if ( fs && qt_screen->isTransformed() ) 147 if ( fs && qt_screen->isTransformed() )
148 s = qt_screen->mapToDevice( s ); 148 s = qt_screen->mapToDevice( s );
149 149
150 return s; 150 return s;
151} 151}
152 152
153void XineVideoWidget::paintEvent ( QPaintEvent * ) 153void XineVideoWidget::paintEvent ( QPaintEvent * )
154{ 154{
155 if ( m_buff == 0 ) { 155 if ( m_buff == 0 ) {
156 QPainter p ( this ); 156 QPainter p ( this );
157 p. fillRect ( rect ( ), black ); 157 p. fillRect ( rect ( ), black );
158 if ( m_logo ) 158 if ( m_logo )
159 p. drawImage ( 0, 0, *m_logo ); 159 p. drawImage ( 0, 0, *m_logo );
160 } 160 }
161 else { 161 else {
162 // Qt needs to be notified which areas were really updated .. strange 162 // Qt needs to be notified which areas were really updated .. strange
163 QArray <QRect> qt_bug_workaround_clip_rects; 163 QArray <QRect> qt_bug_workaround_clip_rects;
164 164
165 { 165 {
166 QDirectPainter dp ( this ); 166 QDirectPainter dp ( this );
167 167
168 int rot = dp. transformOrientation ( ) + m_rotation; // device rotation + custom rotation 168 int rot = dp. transformOrientation ( ) + m_rotation; // device rotation + custom rotation
169 169
170 uchar *fb = dp. frameBuffer ( ); 170 uchar *fb = dp. frameBuffer ( );
171 uchar *frame = m_buff; 171 uchar *frame = m_buff;
172 172
173 // where is the video frame in fb coordinates 173 // where is the video frame in fb coordinates
174 QRect framerect = qt_screen-> mapToDevice ( QRect ( mapToGlobal ( m_thisframe. topLeft ( )), m_thisframe. size ( )), QSize ( qt_screen-> width ( ), qt_screen-> height ( ))); 174 QRect framerect = qt_screen-> mapToDevice ( QRect ( mapToGlobal ( m_thisframe. topLeft ( )), m_thisframe. size ( )), QSize ( qt_screen-> width ( ), qt_screen-> height ( )));
175 175
176 qt_bug_workaround_clip_rects. resize ( dp. numRects ( )); 176 qt_bug_workaround_clip_rects. resize ( dp. numRects ( ));
177 177
178 for ( int i = dp. numRects ( ) - 1; i >= 0; i-- ) { 178 for ( int i = dp. numRects ( ) - 1; i >= 0; i-- ) {
179 const QRect &clip = dp. rect ( i ); 179 const QRect &clip = dp. rect ( i );
180 180
181 qt_bug_workaround_clip_rects [ i ] = qt_screen-> mapFromDevice ( clip, QSize ( qt_screen-> width ( ), qt_screen-> height ( ))); 181 qt_bug_workaround_clip_rects [ i ] = qt_screen-> mapFromDevice ( clip, QSize ( qt_screen-> width ( ), qt_screen-> height ( )));
182 182
183 uchar *dst = fb + ( clip. x ( ) * m_bytes_per_pixel ) + ( clip. y ( ) * m_bytes_per_line_fb ); // clip x/y in the fb 183 uchar *dst = fb + ( clip. x ( ) * m_bytes_per_pixel ) + ( clip. y ( ) * m_bytes_per_line_fb ); // clip x/y in the fb
184 uchar *src = frame; 184 uchar *src = frame;
185 185
186 // Adjust the start the source data based on the rotation (xine frame) 186 // Adjust the start the source data based on the rotation (xine frame)
187 switch ( rot ) { 187 switch ( rot ) {
188 case 0: src += ((( clip. x ( ) - framerect. x ( )) * m_bytes_per_pixel ) + (( clip. y ( ) - framerect. y ( )) * m_bytes_per_line_frame )); break; 188 case 0: src += ((( clip. x ( ) - framerect. x ( )) * m_bytes_per_pixel ) + (( clip. y ( ) - framerect. y ( )) * m_bytes_per_line_frame )); break;
189 case 1: src += ((( clip. y ( ) - framerect. y ( )) * m_bytes_per_pixel ) + (( clip. x ( ) - framerect. x ( )) * m_bytes_per_line_frame ) + (( framerect. height ( ) - 1 ) * m_bytes_per_pixel )); break; 189 case 1: src += ((( clip. y ( ) - framerect. y ( )) * m_bytes_per_pixel ) + (( clip. x ( ) - framerect. x ( )) * m_bytes_per_line_frame ) + (( framerect. height ( ) - 1 ) * m_bytes_per_pixel )); break;
190 case 2: src += ((( clip. x ( ) - framerect. x ( )) * m_bytes_per_pixel ) + (( clip. y ( ) - framerect. y ( )) * m_bytes_per_line_frame ) + (( framerect. height ( ) - 1 ) * m_bytes_per_line_frame )); break; 190 case 2: src += ((( clip. x ( ) - framerect. x ( )) * m_bytes_per_pixel ) + (( clip. y ( ) - framerect. y ( )) * m_bytes_per_line_frame ) + (( framerect. height ( ) - 1 ) * m_bytes_per_line_frame )); break;
191 case 3: src += ((( clip. y ( ) - framerect. y ( )) * m_bytes_per_pixel ) + (( clip. x ( ) - framerect. x ( )) * m_bytes_per_line_frame )); break; 191 case 3: src += ((( clip. y ( ) - framerect. y ( )) * m_bytes_per_pixel ) + (( clip. x ( ) - framerect. x ( )) * m_bytes_per_line_frame )); break;
192 default: break; 192 default: break;
193 } 193 }
194 194
195 // all of the following widths/heights are fb relative (0deg rotation) 195 // all of the following widths/heights are fb relative (0deg rotation)
196 196
197 uint leftfill = 0; // black border on the "left" side of the video frame 197 uint leftfill = 0; // black border on the "left" side of the video frame
198 uint framefill = 0; // "width" of the video frame 198 uint framefill = 0; // "width" of the video frame
199 uint rightfill = 0; // black border on the "right" side of the video frame 199 uint rightfill = 0; // black border on the "right" side of the video frame
200 uint clipwidth = clip. width ( ) * m_bytes_per_pixel; // "width" of the current clip rect 200 uint clipwidth = clip. width ( ) * m_bytes_per_pixel; // "width" of the current clip rect
201 201
202 if ( clip. left ( ) < framerect. left ( )) 202 if ( clip. left ( ) < framerect. left ( ))
203 leftfill = (( framerect. left ( ) - clip. left ( )) * m_bytes_per_pixel ) <? clipwidth; 203 leftfill = (( framerect. left ( ) - clip. left ( )) * m_bytes_per_pixel ) <? clipwidth;
204 if ( clip. right ( ) > framerect. right ( )) 204 if ( clip. right ( ) > framerect. right ( ))
205 rightfill = (( clip. right ( ) - framerect. right ( )) * m_bytes_per_pixel ) <? clipwidth; 205 rightfill = (( clip. right ( ) - framerect. right ( )) * m_bytes_per_pixel ) <? clipwidth;
206 206
207 framefill = clipwidth - ( leftfill + rightfill ); 207 framefill = clipwidth - ( leftfill + rightfill );
208 208
209 for ( int y = clip. top ( ); y <= clip. bottom ( ); y++ ) { 209 for ( int y = clip. top ( ); y <= clip. bottom ( ); y++ ) {
210 if (( y < framerect. top ( )) || ( y > framerect. bottom ( ))) { 210 if (( y < framerect. top ( )) || ( y > framerect. bottom ( ))) {
211 // "above" or "below" the video -> black 211 // "above" or "below" the video -> black
212 memset ( dst, 0, clipwidth ); 212 memset ( dst, 0, clipwidth );
213 } 213 }
214 else { 214 else {
215 if ( leftfill ) 215 if ( leftfill )
216 memset ( dst, 0, leftfill ); // "left" border -> black 216 memset ( dst, 0, leftfill ); // "left" border -> black
217 217
218 if ( framefill ) { // blit in the video frame 218 if ( framefill ) { // blit in the video frame
219 // see above for an explanation of the different memcpys 219 // see above for an explanation of the different memcpys
220 220
221 switch ( rot ) { 221 switch ( rot ) {
222 case 0: memcpy ( dst + leftfill, src, framefill & ~1 ); break; 222 case 0: memcpy ( dst + leftfill, src, framefill & ~1 ); break;
223 case 1: memcpy_step ( dst + leftfill, src, framefill, m_bytes_per_line_frame ); break; 223 case 1: memcpy_step ( dst + leftfill, src, framefill, m_bytes_per_line_frame ); break;
224 case 2: memcpy_rev ( dst + leftfill, src, framefill ); break; 224 case 2: memcpy_rev ( dst + leftfill, src, framefill ); break;
225 case 3: memcpy_step_rev ( dst + leftfill, src, framefill, m_bytes_per_line_frame ); break; 225 case 3: memcpy_step_rev ( dst + leftfill, src, framefill, m_bytes_per_line_frame ); break;
226 default: break; 226 default: break;
227 } 227 }
228 } 228 }
229 if ( rightfill ) 229 if ( rightfill )
230 memset ( dst + leftfill + framefill, 0, rightfill ); // "right" border -> black 230 memset ( dst + leftfill + framefill, 0, rightfill ); // "right" border -> black
231 } 231 }
232 232
233 dst += m_bytes_per_line_fb; // advance one line in the framebuffer 233 dst += m_bytes_per_line_fb; // advance one line in the framebuffer
234 234
235 // advance one "line" in the xine frame data 235 // advance one "line" in the xine frame data
236 switch ( rot ) { 236 switch ( rot ) {
237 case 0: src += m_bytes_per_line_frame;break; 237 case 0: src += m_bytes_per_line_frame;break;
238 case 1: src -= m_bytes_per_pixel; break; 238 case 1: src -= m_bytes_per_pixel; break;
239 case 2: src -= m_bytes_per_line_frame; break; 239 case 2: src -= m_bytes_per_line_frame; break;
240 case 3: src += m_bytes_per_pixel; break; 240 case 3: src += m_bytes_per_pixel; break;
241 default: break; 241 default: break;
242 } 242 }
243 } 243 }
244 } 244 }
245 } 245 }
246 246
247 { 247 {
248 // QVFB hack by Martin Jones 248 // QVFB hack by Martin Jones
249 // We need to "touch" all affected clip rects with a normal QPainter in addition to the QDirectPainter 249 // We need to "touch" all affected clip rects with a normal QPainter in addition to the QDirectPainter
250 250
251 QPainter p ( this ); 251 QPainter p ( this );
252 252
253 for ( int i = qt_bug_workaround_clip_rects. size ( ) - 1; i >= 0; i-- ) { 253 for ( int i = qt_bug_workaround_clip_rects. size ( ) - 1; i >= 0; i-- ) {
254 p. fillRect ( QRect ( mapFromGlobal ( qt_bug_workaround_clip_rects [ i ]. topLeft ( )), qt_bug_workaround_clip_rects [ i ]. size ( )), QBrush ( NoBrush )); 254 p. fillRect ( QRect ( mapFromGlobal ( qt_bug_workaround_clip_rects [ i ]. topLeft ( )), qt_bug_workaround_clip_rects [ i ]. size ( )), QBrush ( NoBrush ));
255 } 255 }
256 } 256 }
257 } 257 }
258} 258}
259 259
260 260
261QImage *XineVideoWidget::logo ( ) const 261QImage *XineVideoWidget::logo ( ) const
262{ 262{
263 return m_logo; 263 return m_logo;
264} 264}
265 265
266 266
267void XineVideoWidget::setLogo ( QImage* logo ) 267void XineVideoWidget::setLogo ( QImage* logo )
268{ 268{
269 delete m_logo; 269 delete m_logo;
270 m_logo = logo; 270 m_logo = logo;
271} 271}
272 272
273void XineVideoWidget::setVideoFrame ( uchar* img, int w, int h, int bpl ) 273void XineVideoWidget::setVideoFrame ( uchar* img, int w, int h, int bpl )
274{ 274{
275 bool rot90 = (( -m_rotation ) & 1 ); 275 bool rot90 = (( -m_rotation ) & 1 );
276 276
277 if ( rot90 ) { // if the rotation is 90 or 270 we have to swap width / height 277 if ( rot90 ) { // if the rotation is 90 or 270 we have to swap width / height
278 int d = w; 278 int d = w;
279 w = h; 279 w = h;
280 h = d; 280 h = d;
281 } 281 }
282 282
283 m_lastframe = m_thisframe; 283 m_lastframe = m_thisframe;
284 m_thisframe. setRect (( width ( ) - w ) / 2, ( height ( ) - h ) / 2, w , h ); 284 m_thisframe. setRect (( width ( ) - w ) / 2, ( height ( ) - h ) / 2, w , h );
285 285
286 m_buff = img; 286 m_buff = img;
287 m_bytes_per_line_frame = bpl; 287 m_bytes_per_line_frame = bpl;
288 288
289 // only repaint the area that *really* needs to be repainted 289 // only repaint the area that *really* needs to be repainted
290 290
291 repaint ((( m_thisframe & m_lastframe ) != m_lastframe ) ? m_lastframe : m_thisframe, false ); 291 repaint ((( m_thisframe & m_lastframe ) != m_lastframe ) ? m_lastframe : m_thisframe, false );
292 // ensure that we always have a valid frame!
293 m_buff = 0;
292} 294}
293 295
294void XineVideoWidget::resizeEvent ( QResizeEvent * ) 296void XineVideoWidget::resizeEvent ( QResizeEvent * )
295{ 297{
296 emit videoResized( videoSize() ); 298 emit videoResized( videoSize() );
297} 299}
298 300
299 301
300void XineVideoWidget::mouseReleaseEvent ( QMouseEvent * /*me*/ ) 302void XineVideoWidget::mouseReleaseEvent ( QMouseEvent * /*me*/ )
301{ 303{
302 emit clicked(); 304 emit clicked();
303} 305}
304 306