~siretart/xine-lib/ubuntu

« back to all changes in this revision

Viewing changes to src/xine-engine/video_out.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2005-12-15 13:13:45 UTC
  • mfrom: (0.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051215131345-8n4osv1j7fy9c1s1
* SECURITY UPDATE: Fix arbitrary code execution with crafted PNG images in
  embedded ffmpeg copy.
* src/libffmpeg/libavcodec/utils.c, avcodec_default_get_buffer(): Apply
  upstream patch to fix buffer overflow on decoding of small PIX_FMT_PAL8
  PNG files.
* References:
  CVE-2005-4048
  http://mplayerhq.hu/pipermail/ffmpeg-devel/2005-November/005333.html
  http://www1.mplayerhq.hu/cgi-bin/cvsweb.cgi/ffmpeg/libavcodec/
  utils.c.diff?r1=1.161&r2=1.162&cvsroot=FFMpeg

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 * along with this program; if not, write to the Free Software
18
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
19
19
 *
20
 
 * $Id: video_out.c,v 1.214.2.1 2005/04/20 17:21:17 mroi Exp $
 
20
 * $Id: video_out.c,v 1.222 2005/11/14 23:48:19 miguelfreitas Exp $
21
21
 *
22
22
 * frame allocation / queuing / scheduling / output functions
23
23
 */
59
59
#define FIRST_FRAME_POLL_DELAY   3000
60
60
#define FIRST_FRAME_MAX_POLL       10    /* poll n times at most */
61
61
 
 
62
/* experimental optimization: try to allocate frames from free queue 
 
63
 * in the same format as requested (avoid unnecessary free/alloc in
 
64
 * vo driver). up to 25% less cpu load using deinterlace with film mode.
 
65
 */ 
 
66
#define EXPERIMENTAL_FRAME_QUEUE_OPTIMIZATION 1
 
67
 
62
68
static vo_frame_t * crop_frame( xine_video_port_t *this_gen, vo_frame_t *img );
63
69
 
64
70
typedef struct {
174
180
  pthread_mutex_unlock (&queue->mutex);
175
181
}
176
182
 
177
 
static vo_frame_t *vo_remove_from_img_buf_queue_int (img_buf_fifo_t *queue, int blocking) {
178
 
  vo_frame_t *img;
179
 
 
180
 
  while (!queue->first || queue->locked_for_read) {
181
 
    if (blocking)
182
 
      pthread_cond_wait (&queue->not_empty, &queue->mutex);
183
 
    else {
184
 
      struct timeval tv;
185
 
      struct timespec ts;
186
 
      gettimeofday(&tv, NULL);
187
 
      ts.tv_sec  = tv.tv_sec + 1;
188
 
      ts.tv_nsec = tv.tv_usec * 1000;
189
 
      if (pthread_cond_timedwait (&queue->not_empty, &queue->mutex, &ts) != 0)
190
 
        return NULL;
 
183
static vo_frame_t *vo_remove_from_img_buf_queue_int (img_buf_fifo_t *queue, int blocking,
 
184
                                                     uint32_t width, uint32_t height,
 
185
                                                     double ratio, int format,
 
186
                                                     int flags) {
 
187
  vo_frame_t *img = NULL;
 
188
  vo_frame_t *previous = NULL;
 
189
 
 
190
  while (!img || queue->locked_for_read) {
 
191
 
 
192
    img = (queue->locked_for_read) ? NULL : queue->first;
 
193
 
 
194
#if EXPERIMENTAL_FRAME_QUEUE_OPTIMIZATION
 
195
    if (img) {
 
196
      /* try to obtain a frame with the same format first.
 
197
       * doing so may avoid unnecessary alloc/free's at the vo
 
198
       * driver, specially when using post plugins that change
 
199
       * format like the tvtime deinterlacer does.
 
200
       */
 
201
      int i = 0;
 
202
      while( img && width && height &&
 
203
            (img->width != width || img->height != height ||
 
204
            img->ratio != ratio || img->format != format) ) {
 
205
        previous = img;
 
206
        img = img->next;
 
207
        i++;
 
208
      }
 
209
      
 
210
      if( width && height ) {
 
211
        if( !img ) {
 
212
          if( queue->num_buffers == 1 && !blocking) {
 
213
            /* non-blocking and only a single frame on fifo with different
 
214
             * format -> ignore it (give another chance of a frame format hit)
 
215
             */
 
216
            lprintf("frame format mismatch - will wait another frame\n");
 
217
          } else {
 
218
            /* we have at least 2 frames on fifo but they don't match ->
 
219
             * give up. return whatever we got.
 
220
             */
 
221
            img = queue->first;
 
222
            lprintf("frame format miss (%d/%d)\n", i, queue->num_buffers);
 
223
          }
 
224
        } else {
 
225
          /* good: format match! */
 
226
          lprintf("frame format hit (%d/%d)\n", i, queue->num_buffers);
 
227
        }
 
228
      }
 
229
    }
 
230
#endif
 
231
 
 
232
    if(!img) {
 
233
      if (blocking)
 
234
        pthread_cond_wait (&queue->not_empty, &queue->mutex);
 
235
      else {
 
236
        struct timeval tv;
 
237
        struct timespec ts;
 
238
        gettimeofday(&tv, NULL);
 
239
        ts.tv_sec  = tv.tv_sec + 1;
 
240
        ts.tv_nsec = tv.tv_usec * 1000;
 
241
        if (pthread_cond_timedwait (&queue->not_empty, &queue->mutex, &ts) != 0)
 
242
          return NULL;
 
243
      }
191
244
    }
192
245
  }
193
246
 
194
 
  img = queue->first;
195
 
 
196
247
  if (img) {
197
 
    queue->first = img->next;
 
248
 
 
249
    if( img == queue->first ) {
 
250
      queue->first = img->next;
 
251
    } else {
 
252
      previous->next = img->next;
 
253
      if( img == queue->last )
 
254
        queue->last = previous;
 
255
    }
 
256
    
198
257
    img->next = NULL;
199
258
    if (!queue->first) {
200
259
      queue->last = NULL;
201
260
      queue->num_buffers = 0;
202
 
    }
203
 
    else {
 
261
    } else {
204
262
      queue->num_buffers--;
205
263
    }
206
264
  }
212
270
  vo_frame_t *img;
213
271
 
214
272
  pthread_mutex_lock (&queue->mutex);
215
 
  img = vo_remove_from_img_buf_queue_int(queue, 1);
 
273
  img = vo_remove_from_img_buf_queue_int(queue, 1, 0, 0, 0, 0, 0);
216
274
  pthread_mutex_unlock (&queue->mutex);
217
275
 
218
276
  return img;
219
277
}
220
278
 
221
 
static vo_frame_t *vo_remove_from_img_buf_queue_nonblock (img_buf_fifo_t *queue) {
 
279
static vo_frame_t *vo_remove_from_img_buf_queue_nonblock (img_buf_fifo_t *queue,
 
280
                                                          uint32_t width, uint32_t height,
 
281
                                                          double ratio, int format,
 
282
                                                          int flags) {
222
283
  vo_frame_t *img;
223
284
 
224
285
  pthread_mutex_lock (&queue->mutex);
225
 
  img = vo_remove_from_img_buf_queue_int(queue, 0);
 
286
  img = vo_remove_from_img_buf_queue_int(queue, 0, width, height, ratio, format, flags);
226
287
  pthread_mutex_unlock (&queue->mutex);
227
288
 
228
289
  return img;
312
373
 
313
374
  lprintf ("get_frame (%d x %d)\n", width, height);
314
375
 
315
 
  while (!(img = vo_remove_from_img_buf_queue_nonblock (this->free_img_buf_queue)))
 
376
  while (!(img = vo_remove_from_img_buf_queue_nonblock (this->free_img_buf_queue,
 
377
                 width, height, ratio, format, flags)))
316
378
    if (this->xine->port_ticket->ticket_revoked)
317
379
      this->xine->port_ticket->renew(this->xine->port_ticket, 1);
318
380
 
338
400
  img->crop_right     = 0;
339
401
  img->crop_top       = 0;
340
402
  img->crop_bottom    = 0;
 
403
  img->overlay_offset_x = 0;
 
404
  img->overlay_offset_y = 0;
341
405
  img->stream         = NULL;
342
406
 
343
407
  _x_extra_info_reset ( img->extra_info );
451
515
        (this->grab_only ||
452
516
         !(this->driver->get_capabilities (this->driver) & VO_CAP_CROP)) ) {
453
517
      if (img->format == XINE_IMGFMT_YV12 || img->format == XINE_IMGFMT_YUY2) {
 
518
        img->overlay_offset_x -= img->crop_left;
 
519
        img->overlay_offset_y -= img->crop_top;
454
520
        img = crop_frame( img->port, img );
455
521
        img_already_locked = 1;
456
522
      } else {
626
692
  dupl->crop_right     = img->crop_right;
627
693
  dupl->crop_top       = img->crop_top;
628
694
  dupl->crop_bottom    = img->crop_bottom;
 
695
  dupl->overlay_offset_x = img->overlay_offset_x;
 
696
  dupl->overlay_offset_y = img->overlay_offset_y;
629
697
  
630
698
  this->driver->update_frame_format (this->driver, dupl, dupl->width, dupl->height, 
631
699
                                     dupl->ratio, dupl->format, dupl->flags);
741
809
        this->num_frames_discarded++;
742
810
      }
743
811
      
744
 
      img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
 
812
      img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
745
813
  
746
814
      if (img->stream) {
747
815
        pthread_mutex_lock( &img->stream->current_extra_info_lock );
889
957
     * remove frame from display queue and show it
890
958
     */
891
959
    
892
 
    img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
 
960
    img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
893
961
    pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
894
962
 
895
963
    return img;
1155
1223
  img = this->display_img_buf_queue->first;
1156
1224
  while (img) {
1157
1225
 
1158
 
    img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
 
1226
    img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
1159
1227
    vo_frame_dec_lock( img );
1160
1228
 
1161
1229
    img = this->display_img_buf_queue->first;
1213
1281
   * remove frame from display queue and show it
1214
1282
   */
1215
1283
    
1216
 
  img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
 
1284
  img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
1217
1285
  pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
1218
1286
 
1219
1287
  frame->vpts         = img->vpts;
1382
1450
  
1383
1451
        lprintf ("flushing out frame\n");
1384
1452
  
1385
 
        img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
 
1453
        img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
1386
1454
  
1387
1455
        vo_frame_dec_lock (img);
1388
1456
      }
1604
1672
  dupl->progressive_frame  = img->progressive_frame;
1605
1673
  dupl->repeat_first_field = img->repeat_first_field;
1606
1674
  dupl->top_field_first    = img->top_field_first;
 
1675
  dupl->overlay_offset_x   = img->overlay_offset_x;
 
1676
  dupl->overlay_offset_y   = img->overlay_offset_y;
1607
1677
  
1608
1678
  switch (img->format) {
1609
1679
  case XINE_IMGFMT_YV12: