~siretart/xine-lib/ubuntu

« back to all changes in this revision

Viewing changes to src/libffmpeg/video_decoder.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_decoder.c,v 1.39.2.1 2005/04/20 17:21:10 mroi Exp $
 
20
 * $Id: video_decoder.c,v 1.59 2005/11/04 22:37:14 tmattern Exp $
21
21
 *
22
22
 * xine video decoder plugin using ffmpeg
23
23
 *
79
79
  int64_t           pts;
80
80
  int               video_step;
81
81
  int               decoder_ok;
 
82
  int               decoder_init_mode;
82
83
 
83
84
  xine_bmiheader    bih;
84
85
  unsigned char    *buf;
103
104
  int               is_mpeg12;
104
105
 
105
106
  double            aspect_ratio;
 
107
  int               aspect_ratio_prio;
106
108
  int               frame_flags;
107
109
  int               crop_right, crop_bottom;
108
110
  
109
111
  int               output_format;
110
112
  yuv_planes_t      yuv;
 
113
  int               yuv_init;
 
114
 
 
115
  int               cs_convert_init;
111
116
  AVPaletteControl  palette_control;
112
117
};
113
118
 
115
120
static void set_stream_info(ff_video_decoder_t *this) {
116
121
  _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH,  this->bih.biWidth);
117
122
  _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight);
118
 
  _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO,  this->aspect_ratio*10000);
 
123
  _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO,  this->aspect_ratio * 10000);
119
124
}
120
125
 
121
126
#ifdef ENABLE_DIRECT_RENDERING
126
131
  int width  = context->width;
127
132
  int height = context->height;
128
133
        
129
 
  if(!this->bih.biWidth || !this->bih.biHeight) {
 
134
  if (!this->bih.biWidth || !this->bih.biHeight) {
130
135
    this->bih.biWidth = width;
131
136
    this->bih.biHeight = height;
132
 
    this->aspect_ratio = (double)width / (double)height;
133
 
    set_stream_info(this);
 
137
 
 
138
    if (this->aspect_ratio_prio == 0) {
 
139
      this->aspect_ratio = (double)width / (double)height;
 
140
      this->aspect_ratio_prio = 1;
 
141
      lprintf("default aspect ratio: %f\n", this->aspect_ratio);
 
142
      set_stream_info(this);
 
143
    }
134
144
  }
135
145
  
136
146
  avcodec_align_dimensions(context, &width, &height);
144
154
    return avcodec_default_get_buffer(context, av_frame);
145
155
  }
146
156
  
147
 
  if((width != context->width) || (height != context->height)) {
 
157
  if((width != this->bih.biWidth) || (height != this->bih.biHeight)) {
148
158
    if(this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_CROP) {
149
 
      this->crop_right = width - context->width;
150
 
      this->crop_bottom = height - context->height;
 
159
      this->crop_right = width - this->bih.biWidth;
 
160
      this->crop_bottom = height - this->bih.biHeight;
151
161
    } else {
152
162
      xprintf(this->stream->xine, XINE_VERBOSITY_LOG, 
153
163
              _("ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n"));
201
211
}
202
212
#endif
203
213
 
204
 
static void init_video_codec (ff_video_decoder_t *this) {
 
214
static const ff_codec_t ff_video_lookup[] = {
 
215
  {BUF_VIDEO_MSMPEG4_V1,  CODEC_ID_MSMPEG4V1, "Microsoft MPEG-4 v1 (ffmpeg)"},
 
216
  {BUF_VIDEO_MSMPEG4_V2,  CODEC_ID_MSMPEG4V2, "Microsoft MPEG-4 v2 (ffmpeg)"},
 
217
  {BUF_VIDEO_MSMPEG4_V3,  CODEC_ID_MSMPEG4V3, "Microsoft MPEG-4 v3 (ffmpeg)"},
 
218
  {BUF_VIDEO_WMV7,        CODEC_ID_WMV1,      "MS Windows Media Video 7 (ffmpeg)"},
 
219
  {BUF_VIDEO_WMV8,        CODEC_ID_WMV2,      "MS Windows Media Video 8 (ffmpeg)"},
 
220
  {BUF_VIDEO_MPEG4,       CODEC_ID_MPEG4,     "ISO MPEG-4 (ffmpeg)"},
 
221
  {BUF_VIDEO_XVID,        CODEC_ID_MPEG4,     "ISO MPEG-4 (XviD, ffmpeg)"},
 
222
  {BUF_VIDEO_DIVX5,       CODEC_ID_MPEG4,     "ISO MPEG-4 (DivX5, ffmpeg)"},
 
223
  {BUF_VIDEO_3IVX,        CODEC_ID_MPEG4,     "ISO MPEG-4 (3ivx, ffmpeg)"},
 
224
  {BUF_VIDEO_JPEG,        CODEC_ID_MJPEG,     "Motion JPEG (ffmpeg)"},
 
225
  {BUF_VIDEO_MJPEG,       CODEC_ID_MJPEG,     "Motion JPEG (ffmpeg)"},
 
226
  {BUF_VIDEO_MJPEG_B,     CODEC_ID_MJPEGB,    "Motion JPEG B (ffmpeg"},
 
227
  {BUF_VIDEO_I263,        CODEC_ID_H263I,     "ITU H.263 (ffmpeg)"},
 
228
  {BUF_VIDEO_H263,        CODEC_ID_H263,      "H.263 (ffmpeg)"},
 
229
  {BUF_VIDEO_RV10,        CODEC_ID_RV10,      "Real Video 1.0 (ffmpeg)"},
 
230
  {BUF_VIDEO_RV20,        CODEC_ID_RV20,      "Real Video 2.0 (ffmpeg)"},
 
231
  {BUF_VIDEO_IV31,        CODEC_ID_INDEO3,    "Indeo Video 3.1 (ffmpeg)"},
 
232
  {BUF_VIDEO_IV32,        CODEC_ID_INDEO3,    "Indeo Video 3.2 (ffmpeg)"},
 
233
  {BUF_VIDEO_SORENSON_V1, CODEC_ID_SVQ1,      "Sorenson Video 1 (ffmpeg)"},
 
234
  {BUF_VIDEO_SORENSON_V3, CODEC_ID_SVQ3,      "Sorenson Video 3 (ffmpeg)"},
 
235
  {BUF_VIDEO_DV,          CODEC_ID_DVVIDEO,   "DV (ffmpeg)"},
 
236
  {BUF_VIDEO_HUFFYUV,     CODEC_ID_HUFFYUV,   "HuffYUV (ffmpeg)"},
 
237
  {BUF_VIDEO_VP31,        CODEC_ID_VP3,       "On2 VP3.1 (ffmpeg)"},
 
238
  {BUF_VIDEO_4XM,         CODEC_ID_4XM,       "4X Video (ffmpeg)"},
 
239
  {BUF_VIDEO_CINEPAK,     CODEC_ID_CINEPAK,   "Cinepak (ffmpeg)"},
 
240
  {BUF_VIDEO_MSVC,        CODEC_ID_MSVIDEO1,  "Microsoft Video 1 (ffmpeg)"},
 
241
  {BUF_VIDEO_MSRLE,       CODEC_ID_MSRLE,     "Microsoft RLE (ffmpeg)"},
 
242
  {BUF_VIDEO_RPZA,        CODEC_ID_RPZA,      "Apple Quicktime Video/RPZA (ffmpeg)"},
 
243
  {BUF_VIDEO_CYUV,        CODEC_ID_CYUV,      "Creative YUV (ffmpeg)"},
 
244
  {BUF_VIDEO_ROQ,         CODEC_ID_ROQ,       "Id Software RoQ (ffmpeg)"},
 
245
  {BUF_VIDEO_IDCIN,       CODEC_ID_IDCIN,     "Id Software CIN (ffmpeg)"},
 
246
  {BUF_VIDEO_WC3,         CODEC_ID_XAN_WC3,   "Xan (ffmpeg)"},
 
247
  {BUF_VIDEO_VQA,         CODEC_ID_WS_VQA,    "Westwood Studios VQA (ffmpeg)"},
 
248
  {BUF_VIDEO_INTERPLAY,   CODEC_ID_INTERPLAY_VIDEO, "Interplay MVE (ffmpeg)"},
 
249
  {BUF_VIDEO_FLI,         CODEC_ID_FLIC,      "FLIC Video (ffmpeg)"},
 
250
  {BUF_VIDEO_8BPS,        CODEC_ID_8BPS,      "Planar RGB (ffmpeg)"},
 
251
  {BUF_VIDEO_SMC,         CODEC_ID_SMC,       "Apple Quicktime Graphics/SMC (ffmpeg)"},
 
252
  {BUF_VIDEO_DUCKTM1,     CODEC_ID_TRUEMOTION1,"Duck TrueMotion v1 (ffmpeg)"},
 
253
  {BUF_VIDEO_DUCKTM2,     CODEC_ID_TRUEMOTION2,"Duck TrueMotion v2 (ffmpeg)"},
 
254
  {BUF_VIDEO_VMD,         CODEC_ID_VMDVIDEO,   "Sierra VMD Video (ffmpeg)"},
 
255
  {BUF_VIDEO_ZLIB,        CODEC_ID_ZLIB,       "ZLIB Video (ffmpeg)"},
 
256
  {BUF_VIDEO_MSZH,        CODEC_ID_MSZH,       "MSZH Video (ffmpeg)"},
 
257
  {BUF_VIDEO_ASV1,        CODEC_ID_ASV1,       "ASV v1 Video (ffmpeg)"},
 
258
  {BUF_VIDEO_ASV2,        CODEC_ID_ASV2,       "ASV v2 Video (ffmpeg)"},
 
259
  {BUF_VIDEO_ATIVCR1,     CODEC_ID_VCR1,       "ATI VCR-1 (ffmpeg)"},
 
260
  {BUF_VIDEO_FLV1,        CODEC_ID_FLV1,       "Flash Video (ffmpeg)"},
 
261
  {BUF_VIDEO_QTRLE,       CODEC_ID_QTRLE,      "Apple Quicktime Animation/RLE (ffmpeg)"},
 
262
  {BUF_VIDEO_H264,        CODEC_ID_H264,       "H.264/AVC (ffmpeg)"},
 
263
  {BUF_VIDEO_H261,        CODEC_ID_H261,       "H.261 (ffmpeg)"},
 
264
  {BUF_VIDEO_AASC,        CODEC_ID_AASC,       "Autodesk Video (ffmpeg)"},
 
265
  {BUF_VIDEO_LOCO,        CODEC_ID_LOCO,       "LOCO (ffmpeg)"},
 
266
  {BUF_VIDEO_QDRW,        CODEC_ID_QDRAW,      "QuickDraw (ffmpeg)"},
 
267
  {BUF_VIDEO_QPEG,        CODEC_ID_QPEG,       "Q-Team QPEG (ffmpeg)"},
 
268
  {BUF_VIDEO_TSCC,        CODEC_ID_TSCC,       "TechSmith Video (ffmpeg)"},
 
269
  {BUF_VIDEO_ULTI,        CODEC_ID_ULTI,       "IBM UltiMotion (ffmpeg)"},
 
270
  {BUF_VIDEO_WNV1,        CODEC_ID_WNV1,       "Winnow Video (ffmpeg)"},
 
271
  {BUF_VIDEO_XL,          CODEC_ID_VIXL,       "Miro/Pinnacle VideoXL (ffmpeg)"},
 
272
  {BUF_VIDEO_RT21,        CODEC_ID_INDEO2,     "Indeo/RealTime 2 (ffmpeg)"},
 
273
  {BUF_VIDEO_FPS1,        CODEC_ID_FRAPS,      "Fraps (ffmpeg)"},
 
274
  {BUF_VIDEO_MPEG,        CODEC_ID_MPEG1VIDEO, "MPEG 1/2 (ffmpeg)"} };
 
275
 
 
276
 
 
277
static void init_video_codec (ff_video_decoder_t *this, int codec_type) {
 
278
  int i;
 
279
 
 
280
  /* find the decoder */
 
281
  this->codec = NULL;
 
282
 
 
283
  for(i = 0; i < sizeof(ff_video_lookup)/sizeof(ff_codec_t); i++)
 
284
    if(ff_video_lookup[i].type == codec_type) {
 
285
      pthread_mutex_lock(&ffmpeg_lock);
 
286
      this->codec = avcodec_find_decoder(ff_video_lookup[i].id);
 
287
      pthread_mutex_unlock(&ffmpeg_lock);
 
288
      _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC,
 
289
                            ff_video_lookup[i].name);
 
290
      break;
 
291
    }
 
292
 
 
293
  if (!this->codec) {
 
294
    xprintf (this->stream->xine, XINE_VERBOSITY_LOG, 
 
295
            _("ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n"),
 
296
            codec_type);
 
297
    _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
 
298
    return;
 
299
  }
 
300
 
 
301
  lprintf("lavc decoder found\n");
205
302
 
206
303
  /* force (width % 8 == 0), otherwise there will be 
207
304
   * display problems with Xv. 
213
310
  this->context->stream_codec_tag = this->context->codec_tag = 
214
311
    _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC);
215
312
 
216
 
  /* some decoders (eg. dv) do not know the pix_fmt until they decode the
217
 
   * first frame. setting to -1 avoid enabling DR1 for them.
218
 
   */
219
 
  this->context->pix_fmt = -1;
220
313
 
221
314
  /* Some codecs (eg rv10) copy flags in init so it's necessary to set
222
315
   * this flag here in case we are going to use direct rendering */
223
316
  if(this->codec->capabilities & CODEC_CAP_DR1) {
224
317
    this->context->flags |= CODEC_FLAG_EMU_EDGE;
225
 
  } 
 
318
  }
 
319
 
 
320
  pthread_mutex_lock(&ffmpeg_lock);
226
321
  if (avcodec_open (this->context, this->codec) < 0) {
 
322
    pthread_mutex_unlock(&ffmpeg_lock);
227
323
    xprintf (this->stream->xine, XINE_VERBOSITY_LOG, 
228
324
             _("ffmpeg_video_dec: couldn't open decoder\n"));
229
325
    free(this->context);
231
327
    _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
232
328
    return;
233
329
  }
234
 
 
235
 
  
 
330
  pthread_mutex_unlock(&ffmpeg_lock);
 
331
 
 
332
  lprintf("lavc decoder opened\n");
 
333
 
236
334
  this->decoder_ok = 1;
237
 
  
238
 
  this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight;
239
 
 
240
 
  set_stream_info(this);
 
335
 
 
336
  if ((codec_type != BUF_VIDEO_MPEG) &&
 
337
      (codec_type != BUF_VIDEO_DV)) {
 
338
 
 
339
    if (!this->bih.biWidth || !this->bih.biHeight) {
 
340
      this->bih.biWidth = this->context->width;
 
341
      this->bih.biHeight = this->context->height;
 
342
    }
 
343
 
 
344
 
 
345
    set_stream_info(this);
 
346
  }
241
347
 
242
348
  this->stream->video_out->open (this->stream->video_out, this->stream);
243
349
 
244
350
  this->skipframes = 0;
245
351
  
246
 
  if((this->context->pix_fmt == PIX_FMT_RGBA32) ||
247
 
     (this->context->pix_fmt == PIX_FMT_RGB565) ||
248
 
     (this->context->pix_fmt == PIX_FMT_RGB555) ||
249
 
     (this->context->pix_fmt == PIX_FMT_BGR24) ||
250
 
     (this->context->pix_fmt == PIX_FMT_RGB24) ||
251
 
     (this->context->pix_fmt == PIX_FMT_PAL8)) {
252
 
    this->output_format = XINE_IMGFMT_YUY2;
253
 
    init_yuv_planes(&this->yuv, this->bih.biWidth, this->bih.biHeight);
254
 
  } else {
255
 
    this->output_format = XINE_IMGFMT_YV12;
 
352
  /* enable direct rendering by default */
 
353
  this->output_format = XINE_IMGFMT_YV12;
256
354
#ifdef ENABLE_DIRECT_RENDERING
257
 
    if( this->codec->capabilities & CODEC_CAP_DR1 ) {
258
 
      this->context->get_buffer = get_buffer;
259
 
      this->context->release_buffer = release_buffer;
260
 
      xprintf(this->stream->xine, XINE_VERBOSITY_LOG, 
261
 
              _("ffmpeg_video_dec: direct rendering enabled\n"));
262
 
    }
 
355
  if( this->codec->capabilities & CODEC_CAP_DR1 ) {
 
356
    this->context->get_buffer = get_buffer;
 
357
    this->context->release_buffer = release_buffer;
 
358
    xprintf(this->stream->xine, XINE_VERBOSITY_LOG, 
 
359
            _("ffmpeg_video_dec: direct rendering enabled\n"));
 
360
  }
263
361
#endif
 
362
 
 
363
  /* flag for interlaced streams */
 
364
  this->frame_flags = 0;
 
365
  /* FIXME: which codecs can be interlaced?
 
366
      FIXME: check interlaced DCT and other codec specific info. */
 
367
  switch( codec_type ) {
 
368
    case BUF_VIDEO_DV:
 
369
      this->frame_flags |= VO_INTERLACED_FLAG;
 
370
      break;
 
371
    case BUF_VIDEO_MPEG:
 
372
      this->frame_flags |= VO_INTERLACED_FLAG;
 
373
      break;
 
374
    case BUF_VIDEO_MJPEG:
 
375
      this->frame_flags |= VO_INTERLACED_FLAG;
 
376
      break;
 
377
    case BUF_VIDEO_HUFFYUV:
 
378
      this->frame_flags |= VO_INTERLACED_FLAG;
 
379
      break;
264
380
  }
 
381
 
265
382
}
266
383
 
267
384
static void pp_quality_cb(void *user_data, xine_cfg_entry_t *entry) {
335
452
  /*
336
453
   * init codec
337
454
   */
338
 
  if (!this->decoder_ok) {
 
455
  if (this->decoder_init_mode) {
339
456
    _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, 
340
457
                          "mpeg-1 (ffmpeg)");
341
458
 
342
 
    this->codec = avcodec_find_decoder (CODEC_ID_MPEG1VIDEO); 
343
 
    if (!this->codec) {
344
 
      xprintf (this->stream->xine, XINE_VERBOSITY_LOG, 
345
 
               _("avcodec_find_decoder (CODEC_ID_MPEG1VIDEO) failed.\n"));
346
 
      _x_abort();
347
 
    }
348
 
    
349
 
    init_video_codec (this);
 
459
    init_video_codec (this, BUF_VIDEO_MPEG);
 
460
    this->decoder_init_mode = 0;
350
461
  }
351
462
  
352
463
  /* frame format change */
358
469
 
359
470
    this->bih.biWidth  = parser->width;
360
471
    this->bih.biHeight = parser->height;
361
 
    this->aspect_ratio   = parser->frame_aspect_ratio;
 
472
    this->aspect_ratio = parser->frame_aspect_ratio;
 
473
    this->aspect_ratio_prio = 2;
 
474
    lprintf("mpeg seq aspect ratio: %f\n", this->aspect_ratio);
362
475
    set_stream_info(this);
363
476
 
364
477
    event.type = XINE_EVENT_FRAME_FORMAT_CHANGE;
658
771
  }
659
772
}
660
773
 
661
 
 
662
 
static const ff_codec_t ff_video_lookup[] = {
663
 
  {BUF_VIDEO_MSMPEG4_V1,  CODEC_ID_MSMPEG4V1, "Microsoft MPEG-4 v1 (ffmpeg)"},
664
 
  {BUF_VIDEO_MSMPEG4_V2,  CODEC_ID_MSMPEG4V2, "Microsoft MPEG-4 v2 (ffmpeg)"},
665
 
  {BUF_VIDEO_MSMPEG4_V3,  CODEC_ID_MSMPEG4V3, "Microsoft MPEG-4 v3 (ffmpeg)"},
666
 
  {BUF_VIDEO_WMV7,        CODEC_ID_WMV1,      "MS Windows Media Video 7 (ffmpeg)"},
667
 
  {BUF_VIDEO_WMV8,        CODEC_ID_WMV2,      "MS Windows Media Video 8 (ffmpeg)"},
668
 
  {BUF_VIDEO_MPEG4,       CODEC_ID_MPEG4,     "ISO MPEG-4 (ffmpeg)"},
669
 
  {BUF_VIDEO_XVID,        CODEC_ID_MPEG4,     "ISO MPEG-4 (XviD, ffmpeg)"},
670
 
  {BUF_VIDEO_DIVX5,       CODEC_ID_MPEG4,     "ISO MPEG-4 (DivX5, ffmpeg)"},
671
 
  {BUF_VIDEO_3IVX,        CODEC_ID_MPEG4,     "ISO MPEG-4 (3ivx, ffmpeg)"},
672
 
  {BUF_VIDEO_JPEG,        CODEC_ID_MJPEG,     "Motion JPEG (ffmpeg)"},
673
 
  {BUF_VIDEO_MJPEG,       CODEC_ID_MJPEG,     "Motion JPEG (ffmpeg)"},
674
 
  {BUF_VIDEO_MJPEG_B,      CODEC_ID_MJPEGB,    "Motion JPEG B (ffmpeg"},
675
 
  {BUF_VIDEO_I263,        CODEC_ID_H263I,     "ITU H.263 (ffmpeg)"},
676
 
  {BUF_VIDEO_H263,        CODEC_ID_H263,      "H.263 (ffmpeg)"},
677
 
  {BUF_VIDEO_RV10,        CODEC_ID_RV10,      "Real Video 1.0 (ffmpeg)"},
678
 
  {BUF_VIDEO_RV20,        CODEC_ID_RV20,      "Real Video 2.0 (ffmpeg)"},
679
 
  {BUF_VIDEO_IV31,        CODEC_ID_INDEO3,    "Indeo Video 3.1 (ffmpeg)"},
680
 
  {BUF_VIDEO_IV32,        CODEC_ID_INDEO3,    "Indeo Video 3.2 (ffmpeg)"},
681
 
  {BUF_VIDEO_SORENSON_V1, CODEC_ID_SVQ1,      "Sorenson Video 1 (ffmpeg)"},
682
 
  {BUF_VIDEO_SORENSON_V3, CODEC_ID_SVQ3,      "Sorenson Video 3 (ffmpeg)"},
683
 
  {BUF_VIDEO_DV,          CODEC_ID_DVVIDEO,   "DV (ffmpeg)"},
684
 
  {BUF_VIDEO_HUFFYUV,     CODEC_ID_HUFFYUV,   "HuffYUV (ffmpeg)"},
685
 
  {BUF_VIDEO_VP31,        CODEC_ID_VP3,       "On2 VP3.1 (ffmpeg)"},
686
 
  {BUF_VIDEO_4XM,         CODEC_ID_4XM,       "4X Video (ffmpeg)"},
687
 
  {BUF_VIDEO_CINEPAK,     CODEC_ID_CINEPAK,   "Cinepak (ffmpeg)"},
688
 
  {BUF_VIDEO_MSVC,        CODEC_ID_MSVIDEO1,  "Microsoft Video 1 (ffmpeg)"},
689
 
  {BUF_VIDEO_MSRLE,       CODEC_ID_MSRLE,     "Microsoft RLE (ffmpeg)"},
690
 
  {BUF_VIDEO_RPZA,        CODEC_ID_RPZA,      "Apple Quicktime Video/RPZA (ffmpeg)"},
691
 
  {BUF_VIDEO_CYUV,        CODEC_ID_CYUV,      "Creative YUV (ffmpeg)"},
692
 
  {BUF_VIDEO_ROQ,         CODEC_ID_ROQ,       "Id Software RoQ (ffmpeg)"},
693
 
  {BUF_VIDEO_IDCIN,       CODEC_ID_IDCIN,     "Id Software CIN (ffmpeg)"},
694
 
  {BUF_VIDEO_WC3,         CODEC_ID_XAN_WC3,   "Xan (ffmpeg)"},
695
 
  {BUF_VIDEO_VQA,         CODEC_ID_WS_VQA,    "Westwood Studios VQA (ffmpeg)"},
696
 
  {BUF_VIDEO_INTERPLAY,   CODEC_ID_INTERPLAY_VIDEO, "Interplay MVE (ffmpeg)"},
697
 
  {BUF_VIDEO_FLI,         CODEC_ID_FLIC,      "FLIC Video (ffmpeg)"},
698
 
  {BUF_VIDEO_8BPS,        CODEC_ID_8BPS,      "Planar RGB (ffmpeg)"},
699
 
  {BUF_VIDEO_SMC,         CODEC_ID_SMC,       "Apple Quicktime Graphics/SMC (ffmpeg)"},
700
 
  {BUF_VIDEO_DUCKTM1,     CODEC_ID_TRUEMOTION1,"Duck TrueMotion v1 (ffmpeg)"},
701
 
  {BUF_VIDEO_VMD,         CODEC_ID_VMDVIDEO,   "Sierra VMD Video (ffmpeg)"},
702
 
  {BUF_VIDEO_ZLIB,        CODEC_ID_ZLIB,       "ZLIB Video (ffmpeg)"},
703
 
  {BUF_VIDEO_MSZH,        CODEC_ID_MSZH,       "MSZH Video (ffmpeg)"},
704
 
  {BUF_VIDEO_ASV1,        CODEC_ID_ASV1,       "ASV v1 Video (ffmpeg)"},
705
 
  {BUF_VIDEO_ASV2,        CODEC_ID_ASV2,       "ASV v2 Video (ffmpeg)"},
706
 
  {BUF_VIDEO_ATIVCR1,     CODEC_ID_VCR1,       "ATI VCR-1 (ffmpeg)"},
707
 
  {BUF_VIDEO_FLV1,        CODEC_ID_FLV1,       "Flash Video (ffmpeg)"},
708
 
  {BUF_VIDEO_QTRLE,       CODEC_ID_QTRLE,      "Apple Quicktime Animation/RLE (ffmpeg)"},
709
 
  {BUF_VIDEO_H264,        CODEC_ID_H264,       "H.264/AVC (ffmpeg)"} };
710
 
 
711
774
static void ff_check_bufsize (ff_video_decoder_t *this, int size) {
712
775
  if (size > this->bufsize) {
713
776
    this->bufsize = size + size / 2;
714
777
    xprintf(this->stream->xine, XINE_VERBOSITY_LOG, 
715
778
            _("ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n"), 
716
779
            this->bufsize);
717
 
    this->buf = realloc(this->buf, this->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
 
780
    this->buf = realloc(this->buf, this->bufsize);
718
781
  }
719
782
}
720
783
 
721
 
static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
722
 
  ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen;
723
 
  int i, codec_type;
724
 
  uint8_t *ffbuf = this->buf;
725
 
  AVRational avr00 = {0, 0};
726
 
 
727
 
 
728
 
  lprintf ("processing packet type = %08x, len = %d, decoder_flags=%08x\n", 
729
 
           buf->type, buf->size, buf->decoder_flags);
 
784
static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
 
785
  int codec_type;
 
786
 
 
787
  lprintf ("preview buffer\n");
730
788
 
731
789
  codec_type = buf->type & 0xFFFF0000;
732
790
  if (codec_type == BUF_VIDEO_MPEG)
733
791
    this->is_mpeg12 = 1;
734
792
 
735
 
  if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
736
 
 
737
 
    lprintf ("preview\n");
738
 
    return;
 
793
  if (this->decoder_init_mode && !this->is_mpeg12) {
 
794
    init_video_codec(this, codec_type);
 
795
    init_postprocess(this);
 
796
    this->decoder_init_mode = 0;
739
797
  }
740
 
 
741
 
  if ( (buf->decoder_flags & BUF_FLAG_HEADER) && 
742
 
      !(buf->decoder_flags & BUF_FLAG_SPECIAL) ) {
743
 
 
744
 
    lprintf ("header\n");
745
 
 
746
 
    /* init codec */
747
 
    this->codec = NULL;
748
 
 
749
 
    for(i = 0; i < sizeof(ff_video_lookup)/sizeof(ff_codec_t); i++)
750
 
      if(ff_video_lookup[i].type == codec_type) {
751
 
        this->codec = avcodec_find_decoder(ff_video_lookup[i].id);
752
 
        _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC,
753
 
                              ff_video_lookup[i].name);
754
 
        break;
755
 
      }
756
 
 
757
 
    if (!this->codec) {
758
 
      xprintf (this->stream->xine, XINE_VERBOSITY_LOG, 
759
 
               _("ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n"),
760
 
               codec_type);
761
 
      _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0);
762
 
      return;
763
 
    }
 
798
}
 
799
 
 
800
static void ff_handle_header_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
 
801
 
 
802
  lprintf ("header buffer\n");
 
803
 
 
804
  /* accumulate data */
 
805
  ff_check_bufsize(this, this->size + buf->size + FF_INPUT_BUFFER_PADDING_SIZE);
 
806
  xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
 
807
  this->size += buf->size;
 
808
 
 
809
  if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
 
810
    int codec_type;
 
811
 
 
812
    lprintf ("header complete\n");
 
813
    codec_type = buf->type & 0xFFFF0000;
764
814
 
765
815
    if (buf->decoder_flags & BUF_FLAG_STDHEADER) {
 
816
 
 
817
      lprintf("standard header\n");
766
818
    
767
819
      /* init package containing bih */
768
 
      memcpy ( &this->bih, buf->content, sizeof(xine_bmiheader) );
 
820
      memcpy ( &this->bih, this->buf, sizeof(xine_bmiheader) );
769
821
 
770
822
      if (this->bih.biSize > sizeof(xine_bmiheader)) {
771
823
        this->context->extradata_size = this->bih.biSize - sizeof(xine_bmiheader);
772
824
        this->context->extradata = malloc(this->context->extradata_size + 
773
825
                                          FF_INPUT_BUFFER_PADDING_SIZE);
774
 
        memcpy(this->context->extradata, buf->content + sizeof(xine_bmiheader),
775
 
               this->context->extradata_size);
 
826
        memcpy(this->context->extradata, this->buf + sizeof(xine_bmiheader),
 
827
              this->context->extradata_size);
776
828
      }
777
829
      
778
830
      this->context->bits_per_sample = this->bih.biBitCount;
782
834
      switch (codec_type) {
783
835
      case BUF_VIDEO_RV10:
784
836
      case BUF_VIDEO_RV20:
785
 
        this->bih.biWidth  = BE_16(&buf->content[12]);
786
 
        this->bih.biHeight = BE_16(&buf->content[14]);
 
837
        this->bih.biWidth  = BE_16(&this->buf[12]);
 
838
        this->bih.biHeight = BE_16(&this->buf[14]);
787
839
        
788
 
        this->context->sub_id = BE_32(&buf->content[30]);
 
840
        this->context->sub_id = BE_32(&this->buf[30]);
789
841
 
790
842
        this->context->slice_offset = xine_xmalloc(sizeof(int)*SLICE_OFFSET_SIZE);
791
 
        this->slice_offset_size     = SLICE_OFFSET_SIZE;
 
843
        this->slice_offset_size = SLICE_OFFSET_SIZE;
 
844
 
 
845
        lprintf("w=%d, h=%d\n", this->bih.biWidth, this->bih.biHeight);
 
846
 
792
847
        break;
793
848
      default:
794
849
        xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
796
851
        return;
797
852
      }
798
853
    }
799
 
    
800
 
    init_postprocess(this);
801
 
    
802
 
  } else if (buf->decoder_flags & BUF_FLAG_SPECIAL) {
803
 
 
804
 
    /* take care of all the various types of special buffers 
805
 
     * note that order is important here */
806
 
    lprintf("BUF_FLAG_SPECIAL\n");
807
 
    if (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM &&
808
 
        !this->context->extradata_size) {
809
 
 
810
 
      lprintf("BUF_SPECIAL_STSD_ATOM\n");
811
 
      this->context->extradata_size = buf->decoder_info[2];
812
 
      this->context->extradata = xine_xmalloc(buf->decoder_info[2] + 
813
 
                                              FF_INPUT_BUFFER_PADDING_SIZE);
814
 
      memcpy(this->context->extradata, buf->decoder_info_ptr[2],
815
 
        buf->decoder_info[2]);
816
 
 
817
 
    } else if (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG &&
818
 
               !this->context->extradata_size) {
819
 
      
820
 
      lprintf("BUF_SPECIAL_DECODER_CONFIG\n");
821
 
      this->context->extradata_size = buf->decoder_info[2];
822
 
      this->context->extradata = xine_xmalloc(buf->decoder_info[2] +
823
 
                                              FF_INPUT_BUFFER_PADDING_SIZE);
824
 
      memcpy(this->context->extradata, buf->decoder_info_ptr[2],
825
 
        buf->decoder_info[2]);
826
 
        
827
 
    } else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) {
828
 
 
829
 
      palette_entry_t *demuxer_palette;
830
 
      AVPaletteControl *decoder_palette;
831
 
      
832
 
      lprintf("BUF_SPECIAL_PALETTE\n");
833
 
      decoder_palette = (AVPaletteControl *)this->context->palctrl;
834
 
      demuxer_palette = (palette_entry_t *)buf->decoder_info_ptr[2];
835
 
 
836
 
      for (i = 0; i < buf->decoder_info[2]; i++) {
837
 
        decoder_palette->palette[i] = 
838
 
          (demuxer_palette[i].r << 16) |
839
 
          (demuxer_palette[i].g <<  8) |
840
 
          (demuxer_palette[i].b <<  0);
841
 
      }
842
 
      decoder_palette->palette_changed = 1;
843
 
 
844
 
    } else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) {
845
 
    
846
 
      lprintf("BUF_SPECIAL_RV_CHUNK_TABLE\n");
847
 
      this->context->slice_count = buf->decoder_info[2]+1;
848
 
      
849
 
      if(this->context->slice_count > this->slice_offset_size) {
850
 
        this->context->slice_offset = realloc(this->context->slice_offset,
851
 
                                              sizeof(int)*this->context->slice_count);
852
 
        this->slice_offset_size = this->context->slice_count;
853
 
      }
854
 
      
855
 
      for(i = 0; i < this->context->slice_count; i++)
856
 
        this->context->slice_offset[i] = 
857
 
          ((uint32_t *) buf->decoder_info_ptr[2])[(2*i)+1];
858
 
    
859
 
    } else {
860
 
      return; /* do not send special data to the decoder */
861
 
    }
862
 
  } else {
863
 
    if (((this->size == 0) && (buf->decoder_flags & BUF_FLAG_FRAME_END) &&
864
 
         ((buf->size + FF_INPUT_BUFFER_PADDING_SIZE) < buf->max_size)) ||
865
 
        (this->is_mpeg12)) { 
866
 
      /* buf contains a full frame */
 
854
 
 
855
    /* reset accumulator */
 
856
    this->size = 0;
 
857
  }
 
858
}
 
859
 
 
860
static void ff_handle_special_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
 
861
  int i;
 
862
 
 
863
  /* take care of all the various types of special buffers 
 
864
  * note that order is important here */
 
865
  lprintf("special buffer\n");
 
866
 
 
867
  if (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM &&
 
868
      !this->context->extradata_size) {
 
869
 
 
870
    lprintf("BUF_SPECIAL_STSD_ATOM\n");
 
871
    this->context->extradata_size = buf->decoder_info[2];
 
872
    this->context->extradata = xine_xmalloc(buf->decoder_info[2] + 
 
873
                                            FF_INPUT_BUFFER_PADDING_SIZE);
 
874
    memcpy(this->context->extradata, buf->decoder_info_ptr[2],
 
875
      buf->decoder_info[2]);
 
876
 
 
877
  } else if (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG &&
 
878
            !this->context->extradata_size) {
 
879
    
 
880
    lprintf("BUF_SPECIAL_DECODER_CONFIG\n");
 
881
    this->context->extradata_size = buf->decoder_info[2];
 
882
    this->context->extradata = xine_xmalloc(buf->decoder_info[2] +
 
883
                                            FF_INPUT_BUFFER_PADDING_SIZE);
 
884
    memcpy(this->context->extradata, buf->decoder_info_ptr[2],
 
885
      buf->decoder_info[2]);
 
886
      
 
887
  } else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) {
 
888
 
 
889
    palette_entry_t *demuxer_palette;
 
890
    AVPaletteControl *decoder_palette;
 
891
    
 
892
    lprintf("BUF_SPECIAL_PALETTE\n");
 
893
    this->context->palctrl = &this->palette_control;
 
894
    decoder_palette = (AVPaletteControl *)this->context->palctrl;
 
895
    demuxer_palette = (palette_entry_t *)buf->decoder_info_ptr[2];
 
896
 
 
897
    for (i = 0; i < buf->decoder_info[2]; i++) {
 
898
      decoder_palette->palette[i] = 
 
899
        (demuxer_palette[i].r << 16) |
 
900
        (demuxer_palette[i].g <<  8) |
 
901
        (demuxer_palette[i].b <<  0);
 
902
    }
 
903
    decoder_palette->palette_changed = 1;
 
904
 
 
905
  } else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) {
 
906
  
 
907
    lprintf("BUF_SPECIAL_RV_CHUNK_TABLE\n");
 
908
    this->context->slice_count = buf->decoder_info[2]+1;
 
909
 
 
910
    lprintf("slice_count=%d\n", this->context->slice_count);
 
911
    
 
912
    if(this->context->slice_count > this->slice_offset_size) {
 
913
      this->context->slice_offset = realloc(this->context->slice_offset,
 
914
                                            sizeof(int)*this->context->slice_count);
 
915
      this->slice_offset_size = this->context->slice_count;
 
916
    }
 
917
    
 
918
    for(i = 0; i < this->context->slice_count; i++) {
 
919
      this->context->slice_offset[i] = 
 
920
        ((uint32_t *) buf->decoder_info_ptr[2])[(2*i)+1];
 
921
      lprintf("slice_offset[%d]=%d\n", i, this->context->slice_offset[i]);
 
922
    }
 
923
  }
 
924
}
 
925
 
 
926
static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
 
927
 
 
928
  vo_frame_t *img;
 
929
  int         free_img;
 
930
  int         got_picture, len;
 
931
  int         offset = 0;
 
932
  int         flush = 0;
 
933
  int         size = buf->size;
 
934
 
 
935
  lprintf("handle_mpeg12_buffer\n");
 
936
 
 
937
  while ((size > 0) || (flush == 1)) {
 
938
 
 
939
    uint8_t *current;
 
940
    int next_flush;
 
941
 
 
942
    got_picture = 0;
 
943
    if (!flush) {
 
944
      current = mpeg_parser_decode_data(&this->mpeg_parser,
 
945
                                        buf->content + offset, buf->content + offset + size,
 
946
                                        &next_flush);
 
947
    } else {
 
948
      current = buf->content + offset + size; /* end of the buffer */
 
949
      next_flush = 0;
 
950
    }
 
951
    if (current == NULL) {
 
952
      lprintf("current == NULL\n");
 
953
      return;
 
954
    }
 
955
 
 
956
    if (this->mpeg_parser.has_sequence) {
 
957
      ff_handle_mpeg_sequence(this, &this->mpeg_parser);
 
958
    }
 
959
 
 
960
    if (!this->decoder_ok)
 
961
      return;
 
962
    
 
963
    if (flush) {
 
964
      lprintf("flush lavc buffers\n");
 
965
      /* hack: ffmpeg outputs the last frame if size=0 */
 
966
      this->mpeg_parser.buffer_size = 0;
 
967
    }
 
968
 
 
969
    /* skip decoding b frames if too late */
 
970
    this->context->hurry_up = (this->skipframes > 0);
 
971
 
 
972
    lprintf("avcodec_decode_video: size=%d\n", this->mpeg_parser.buffer_size);
 
973
    len = avcodec_decode_video (this->context, this->av_frame,
 
974
                                &got_picture, this->mpeg_parser.chunk_buffer,
 
975
                                this->mpeg_parser.buffer_size);
 
976
    lprintf("avcodec_decode_video: decoded_size=%d, got_picture=%d\n",
 
977
            len, got_picture);
 
978
    len = current - buf->content - offset;
 
979
    lprintf("avcodec_decode_video: consumed_size=%d\n", len);
 
980
    
 
981
    flush = next_flush;
 
982
 
 
983
    if ((len < 0) || (len > buf->size)) {
 
984
      xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
 
985
                "ffmpeg_video_dec: error decompressing frame\n");
 
986
      size = 0; /* draw a bad frame and exit */
 
987
    } else {
 
988
      size -= len;
 
989
      offset += len;
 
990
    }
 
991
 
 
992
    if (got_picture && this->av_frame->data[0]) {
 
993
      /* got a picture, draw it */
 
994
      if(!this->av_frame->opaque) {
 
995
        /* indirect rendering */
 
996
        img = this->stream->video_out->get_frame (this->stream->video_out,
 
997
                                                  this->bih.biWidth,
 
998
                                                  this->bih.biHeight,
 
999
                                                  this->aspect_ratio, 
 
1000
                                                  this->output_format,
 
1001
                                                  VO_BOTH_FIELDS|this->frame_flags);
 
1002
        free_img = 1;
 
1003
      } else {
 
1004
        /* DR1 */
 
1005
        img = (vo_frame_t*) this->av_frame->opaque;
 
1006
        free_img = 0;
 
1007
      }
 
1008
 
 
1009
      img->pts  = this->pts;
 
1010
      this->pts = 0;
 
1011
 
 
1012
      if (this->av_frame->repeat_pict)
 
1013
        img->duration = this->video_step * 3 / 2;
 
1014
      else
 
1015
        img->duration = this->video_step;
 
1016
 
 
1017
      img->crop_right  = this->crop_right;
 
1018
      img->crop_bottom = this->crop_bottom;
 
1019
      
 
1020
      this->skipframes = img->draw(img, this->stream);
 
1021
 
 
1022
      if(free_img)
 
1023
        img->free(img);
 
1024
 
 
1025
    } else {
 
1026
 
 
1027
      if (this->context->hurry_up) {
 
1028
        /* skipped frame, output a bad frame */
 
1029
        img = this->stream->video_out->get_frame (this->stream->video_out,
 
1030
                                                  this->bih.biWidth,
 
1031
                                                  this->bih.biHeight,
 
1032
                                                  this->aspect_ratio, 
 
1033
                                                  this->output_format,
 
1034
                                                  VO_BOTH_FIELDS|this->frame_flags);
 
1035
        img->pts       = 0;
 
1036
        img->duration  = this->video_step;
 
1037
        img->bad_frame = 1;
 
1038
        this->skipframes = img->draw(img, this->stream);
 
1039
        img->free(img);
 
1040
      }
 
1041
    }
 
1042
  }
 
1043
}
 
1044
 
 
1045
static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
 
1046
  uint8_t *chunk_buf = this->buf;
 
1047
  AVRational avr00 = {0, 1};
 
1048
 
 
1049
  lprintf("handle_buffer\n");
 
1050
 
 
1051
  if (!this->decoder_ok) {
 
1052
    if (this->decoder_init_mode) {
 
1053
      int codec_type = buf->type & 0xFFFF0000;
 
1054
 
 
1055
      /* init ffmpeg decoder */
 
1056
      init_video_codec(this, codec_type);
 
1057
      init_postprocess(this);
 
1058
      this->decoder_init_mode = 0;
 
1059
    } else {
 
1060
      return;
 
1061
    }
 
1062
  }
 
1063
 
 
1064
  if (buf->decoder_flags & BUF_FLAG_FRAME_START) {
 
1065
    lprintf("BUF_FLAG_FRAME_START\n");
 
1066
    this->size = 0;
 
1067
  }
 
1068
 
 
1069
  /* data accumulation */
 
1070
  if (buf->size > 0) {
 
1071
    if ((this->size == 0) &&
 
1072
        ((buf->size + FF_INPUT_BUFFER_PADDING_SIZE) < buf->max_size) && 
 
1073
        (buf->decoder_flags & BUF_FLAG_FRAME_END)) {
 
1074
      /* buf contains a complete frame */
867
1075
      /* no memcpy needed */
868
 
      ffbuf = buf->content;
 
1076
      chunk_buf = buf->content;
869
1077
      this->size = buf->size;
870
1078
      lprintf("no memcpy needed to accumulate data\n");
871
1079
    } else {
872
 
      ff_check_bufsize(this, this->size + buf->size);
873
 
      ffbuf = this->buf; /* ff_check_bufsize can realloc this->buf */
 
1080
      /* copy data into our internal buffer */
 
1081
      ff_check_bufsize(this, this->size + buf->size + FF_INPUT_BUFFER_PADDING_SIZE);
 
1082
      chunk_buf = this->buf; /* ff_check_bufsize might realloc this->buf */
 
1083
 
874
1084
      xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
 
1085
      
875
1086
      this->size += buf->size;
876
1087
      lprintf("accumulate data into this->buf\n");
877
1088
    }
878
1089
  }
879
 
   
880
 
  if (buf->decoder_flags & BUF_FLAG_FRAMERATE) {
881
 
    this->video_step = buf->decoder_info[0];
882
 
    _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step);
883
 
  }
884
 
  
885
 
  if (buf->decoder_flags & BUF_FLAG_ASPECT) {
886
 
    this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2];
887
 
    _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, 
888
 
                       this->aspect_ratio*10000);
889
 
  }
890
 
  
891
 
  if (buf->pts)
892
 
    this->pts = buf->pts;
893
 
 
894
 
  if (this->size || this->is_mpeg12) {
895
 
  
896
 
    if (!this->decoder_ok && !this->is_mpeg12 &&
897
 
        (_x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED) != 0)) {
898
 
      init_video_codec(this);
899
 
    }
900
 
  
901
 
    if (this->is_mpeg12 ||
902
 
        (this->decoder_ok && (buf->decoder_flags & BUF_FLAG_FRAME_END))) {
903
 
 
904
 
      vo_frame_t *img;
905
 
      int         free_img;
906
 
      int         got_picture, len;
907
 
      int         offset;
908
 
      int         flush = 0;
909
 
 
910
 
      /* decode video frame(s) */
911
 
 
912
 
 
913
 
      /* flag for interlaced streams */
914
 
      this->frame_flags = 0;
915
 
      /* FIXME: which codecs can be interlaced?
916
 
         FIXME: check interlaced DCT and other codec specific info. */
917
 
      switch( codec_type ) {
918
 
        case BUF_VIDEO_DV:
919
 
          this->frame_flags |= VO_INTERLACED_FLAG;
920
 
          break;
921
 
        case BUF_VIDEO_MPEG:
922
 
          this->frame_flags |= VO_INTERLACED_FLAG;
923
 
          break;
924
 
        case BUF_VIDEO_MJPEG:
925
 
          this->frame_flags |= VO_INTERLACED_FLAG;
926
 
          break;
927
 
        case BUF_VIDEO_HUFFYUV:
928
 
          this->frame_flags |= VO_INTERLACED_FLAG;
929
 
          break;
930
 
      }
931
 
 
932
 
      /* skip decoding b frames if too late */
933
 
      this->context->hurry_up = (this->skipframes > 0);
934
 
 
935
 
      /* pad input data */
936
 
      ffbuf[this->size] = 0;
 
1090
 
 
1091
  if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
 
1092
 
 
1093
    vo_frame_t *img;
 
1094
    int         free_img;
 
1095
    int         got_picture, len;
 
1096
    int         got_one_picture = 0;
 
1097
    int         offset = 0;
 
1098
    int         codec_type = buf->type & 0xFFFF0000;
 
1099
 
 
1100
    /* pad input data */
 
1101
    chunk_buf[this->size] = 0;
 
1102
 
 
1103
    while (this->size > 0) {
937
1104
      
938
 
      offset = 0;
939
 
      while ((this->size > 0) || (flush == 1)){
940
 
        
941
 
        /* DV frames can be completely skipped */
942
 
        if( codec_type == BUF_VIDEO_DV && this->skipframes ) {
943
 
          len = this->size;
944
 
          got_picture = 1;
945
 
        } else {
946
 
  
947
 
          if (this->is_mpeg12) {
948
 
            uint8_t *current;
949
 
            int next_flush;
950
 
 
951
 
            got_picture = 0;
952
 
            if (!flush) {
953
 
              current = mpeg_parser_decode_data(&this->mpeg_parser,
954
 
                                                ffbuf + offset, ffbuf + offset + this->size,
955
 
                                                &next_flush);
956
 
            } else {
957
 
              current = ffbuf + offset + this->size; /* end of the buffer */
958
 
              next_flush = 0;
959
 
            }
960
 
            if (current == NULL) {
961
 
              lprintf("current == NULL\n");
962
 
              return;
963
 
            } else {
964
 
              
965
 
              if (this->mpeg_parser.has_sequence) {
966
 
                ff_handle_mpeg_sequence(this, &this->mpeg_parser);
967
 
              }
968
 
              
969
 
              if (flush) {
970
 
                lprintf("flush lavc buffers\n");
971
 
                /* hack: ffmpeg outputs the last frame if size=0 */
972
 
                this->mpeg_parser.buffer_size = 0;
973
 
              }
974
 
              lprintf("avcodec_decode_video: size=%d\n", this->mpeg_parser.buffer_size);
975
 
              len = avcodec_decode_video (this->context, this->av_frame,
976
 
                                          &got_picture, this->mpeg_parser.chunk_buffer,
977
 
                                          this->mpeg_parser.buffer_size);
978
 
              lprintf("avcodec_decode_video: decoded_size=%d, got_picture=%d\n",
979
 
                      len, got_picture);
980
 
              len = current - ffbuf - offset;
981
 
              lprintf("avcodec_decode_video: consumed_size=%d\n", len);
982
 
              
983
 
              flush = next_flush;
984
 
            }
985
 
          } else {
986
 
 
987
 
            len = avcodec_decode_video (this->context, this->av_frame,
988
 
                                        &got_picture, &ffbuf[offset],
989
 
                                        this->size);
990
 
          }
991
 
        }
992
 
        if ((len < 0) || (len > this->size)) {
 
1105
      /* DV frames can be completely skipped */
 
1106
      if( codec_type == BUF_VIDEO_DV && this->skipframes ) {
 
1107
        this->size = 0;
 
1108
        got_picture = 0;
 
1109
      } else {
 
1110
        /* skip decoding b frames if too late */
 
1111
        this->context->hurry_up = (this->skipframes > 0);
 
1112
 
 
1113
        lprintf("buffer size: %d\n", this->size);
 
1114
        len = avcodec_decode_video (this->context, this->av_frame,
 
1115
                                    &got_picture, &chunk_buf[offset],
 
1116
                                    this->size);
 
1117
        lprintf("consumed size: %d, got_picture: %d\n", len, got_picture);
 
1118
        if ((len <= 0) || (len > this->size)) {
993
1119
          xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
994
 
                   "ffmpeg_video_dec: error decompressing frame\n");
 
1120
                    "ffmpeg_video_dec: error decompressing frame\n");
995
1121
          this->size = 0;
996
 
          return;
997
 
        }
998
 
 
999
 
        this->size -= len;
1000
 
        offset += len;
1001
 
 
1002
 
        if(!this->bih.biWidth || !this->bih.biHeight) {
1003
 
          this->bih.biWidth = this->context->width;
1004
 
          this->bih.biHeight = this->context->height;
1005
 
          this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight;
1006
 
          set_stream_info(this);
1007
 
        }
1008
 
        
1009
 
        if (!got_picture || !this->av_frame->data[0]) {
1010
 
          xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, 
1011
 
                  "ffmpeg_video_dec: didn't get a picture, %d bytes left\n", 
1012
 
                  this->size);
1013
 
 
1014
 
          if (!this->is_mpeg12) {
1015
 
            if (this->size > 0) {
1016
 
              ff_check_bufsize(this, offset + this->size);
1017
 
              memmove (this->buf, &ffbuf[offset], this->size);
1018
 
              ffbuf = this->buf;
1019
 
            }
1020
 
            return;
1021
 
          } else {
1022
 
            if (this->context->hurry_up) {
1023
 
              /* skipped frame, output a bad frame */
1024
 
              img = this->stream->video_out->get_frame (this->stream->video_out,
1025
 
                                                        this->bih.biWidth,
1026
 
                                                        this->bih.biHeight,
1027
 
                                                        this->aspect_ratio, 
1028
 
                                                        this->output_format,
1029
 
                                                        VO_BOTH_FIELDS|this->frame_flags);
1030
 
              img->pts       = 0;
1031
 
              img->duration  = this->video_step;
1032
 
              img->bad_frame = 1;
1033
 
              this->skipframes = img->draw(img, this->stream);
1034
 
              img->free(img);
1035
 
            }
1036
 
            continue;
 
1122
 
 
1123
        } else {
 
1124
 
 
1125
          offset += len;
 
1126
          this->size -= len;
 
1127
 
 
1128
          if (this->size > 0) {
 
1129
            ff_check_bufsize(this, this->size + FF_INPUT_BUFFER_PADDING_SIZE);
 
1130
            memmove (this->buf, &chunk_buf[offset], this->size);
 
1131
            chunk_buf = this->buf;
1037
1132
          }
1038
1133
        }
1039
 
 
1040
 
        lprintf ("got a picture\n");
1041
 
 
1042
 
        if(av_cmp_q(this->context->sample_aspect_ratio, avr00)) {
1043
 
          this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) * 
1044
 
              (double)this->bih.biWidth / (double)this->bih.biHeight;
1045
 
          _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO,  
1046
 
                             this->aspect_ratio*10000);
1047
 
        }
1048
 
 
 
1134
      }
 
1135
 
 
1136
      /* aspect ratio provided by ffmpeg, override previous setting */
 
1137
      if ((this->aspect_ratio_prio < 2) &&
 
1138
          av_cmp_q(this->context->sample_aspect_ratio, avr00)) {
 
1139
 
 
1140
        this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) * 
 
1141
          (double)this->bih.biWidth / (double)this->bih.biHeight;
 
1142
        this->aspect_ratio_prio = 2;
 
1143
        lprintf("ffmpeg aspect ratio: %f\n", this->aspect_ratio);
 
1144
        set_stream_info(this);
 
1145
      }
 
1146
 
 
1147
      if (got_picture && this->av_frame->data[0]) {
 
1148
        /* got a picture, draw it */
 
1149
        got_one_picture = 1;
1049
1150
        if(!this->av_frame->opaque) {
 
1151
          /* indirect rendering */
 
1152
 
 
1153
          /* initialize the colorspace converter */
 
1154
          if (!this->cs_convert_init) {
 
1155
            if ((this->context->pix_fmt == PIX_FMT_RGBA32) ||
 
1156
                (this->context->pix_fmt == PIX_FMT_RGB565) ||
 
1157
                (this->context->pix_fmt == PIX_FMT_RGB555) ||
 
1158
                (this->context->pix_fmt == PIX_FMT_BGR24) ||
 
1159
                (this->context->pix_fmt == PIX_FMT_RGB24) ||
 
1160
                (this->context->pix_fmt == PIX_FMT_PAL8)) {
 
1161
              this->output_format = XINE_IMGFMT_YUY2;
 
1162
              init_yuv_planes(&this->yuv, this->bih.biWidth, this->bih.biHeight);
 
1163
              this->yuv_init = 1;
 
1164
            }
 
1165
            this->cs_convert_init = 1;
 
1166
          }
 
1167
 
 
1168
          if (this->aspect_ratio_prio == 0) {
 
1169
            this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight;
 
1170
            this->aspect_ratio_prio = 1;
 
1171
            lprintf("default aspect ratio: %f\n", this->aspect_ratio);
 
1172
            set_stream_info(this);
 
1173
          }
 
1174
 
1050
1175
          img = this->stream->video_out->get_frame (this->stream->video_out,
1051
1176
                                                    this->bih.biWidth,
1052
1177
                                                    this->bih.biHeight,
1055
1180
                                                    VO_BOTH_FIELDS|this->frame_flags);
1056
1181
          free_img = 1;
1057
1182
        } else {
 
1183
          /* DR1 */
1058
1184
          img = (vo_frame_t*) this->av_frame->opaque;
1059
1185
          free_img = 0;
1060
1186
        }
1061
1187
 
1062
 
        if (len < 0) {
1063
 
          xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
1064
 
                   "ffmpeg_video_dec: error decompressing frame\n");
1065
 
          img->bad_frame = 1;
1066
 
        } else {
1067
 
          img->bad_frame = 0;
1068
 
 
1069
 
          if(this->pp_quality != this->class->pp_quality)
1070
 
            pp_change_quality(this);
1071
 
 
1072
 
          if(this->pp_available && this->pp_quality) {
1073
 
 
1074
 
            if(this->av_frame->opaque) {
1075
 
              img = this->stream->video_out->get_frame (this->stream->video_out,
1076
 
                                                        img->width,
1077
 
                                                        img->height,
1078
 
                                                        this->aspect_ratio, 
1079
 
                                                        this->output_format,
1080
 
                                                        VO_BOTH_FIELDS|this->frame_flags);
1081
 
              free_img = 1;
1082
 
              img->bad_frame = 0;
1083
 
            }
1084
 
 
1085
 
            pp_postprocess(this->av_frame->data, this->av_frame->linesize, 
1086
 
                           img->base, img->pitches, 
1087
 
                           img->width, img->height,
1088
 
                           this->av_frame->qscale_table, this->av_frame->qstride,
1089
 
                           this->pp_mode, this->pp_context, 
1090
 
                           this->av_frame->pict_type);
1091
 
 
1092
 
          } else if(!this->av_frame->opaque) {
1093
 
            ff_convert_frame(this, img);
 
1188
        /* post processing */
 
1189
        if(this->pp_quality != this->class->pp_quality)
 
1190
          pp_change_quality(this);
 
1191
 
 
1192
        if(this->pp_available && this->pp_quality) {
 
1193
 
 
1194
          if(this->av_frame->opaque) {
 
1195
            /* DR1 */
 
1196
            img = this->stream->video_out->get_frame (this->stream->video_out,
 
1197
                                                      img->width,
 
1198
                                                      img->height,
 
1199
                                                      this->aspect_ratio, 
 
1200
                                                      this->output_format,
 
1201
                                                      VO_BOTH_FIELDS|this->frame_flags);
 
1202
            free_img = 1;
1094
1203
          }
 
1204
 
 
1205
          pp_postprocess(this->av_frame->data, this->av_frame->linesize, 
 
1206
                        img->base, img->pitches, 
 
1207
                        img->width, img->height,
 
1208
                        this->av_frame->qscale_table, this->av_frame->qstride,
 
1209
                        this->pp_mode, this->pp_context, 
 
1210
                        this->av_frame->pict_type);
 
1211
 
 
1212
        } else if (!this->av_frame->opaque) {
 
1213
          /* colorspace conversion or copy */
 
1214
          ff_convert_frame(this, img);
1095
1215
        }
1096
 
      
1097
 
        img->pts      = this->pts;
1098
 
        this->pts     = 0;
 
1216
 
 
1217
        img->pts  = this->pts;
 
1218
        this->pts = 0;
1099
1219
 
1100
1220
        /* workaround for weird 120fps streams */
1101
1221
        if( this->video_step == 750 ) {
1102
 
#if 0          
1103
 
          /* use ffmpeg frame rate if available. i'm unsure if ffmpeg
1104
 
           * really knows it better than what demux told us.
1105
 
           */
1106
 
          if( this->context->frame_rate && this->context->frame_rate_base )
1107
 
            this->video_step = 90000 * this->context->frame_rate_base / 
1108
 
                               this->context->frame_rate;
1109
 
          else
1110
 
#endif
1111
 
            /* fallback to the VIDEO_PTS_MODE */
1112
 
            this->video_step = 0;
 
1222
          /* fallback to the VIDEO_PTS_MODE */
 
1223
          this->video_step = 0;
1113
1224
        }
1114
1225
        
1115
 
        if (!this->av_frame->repeat_pict)
 
1226
        if (this->av_frame->repeat_pict)
 
1227
          img->duration = this->video_step * 3 / 2;
 
1228
        else
1116
1229
          img->duration = this->video_step;
1117
 
        else
1118
 
          img->duration = this->video_step * 3 / 2;
1119
1230
 
1120
1231
        img->crop_right  = this->crop_right;
1121
1232
        img->crop_bottom = this->crop_bottom;
1122
1233
        
1123
1234
        this->skipframes = img->draw(img, this->stream);
1124
 
        if( this->skipframes < 0 )
1125
 
          this->skipframes = 0;
1126
1235
 
1127
1236
        if(free_img)
1128
1237
          img->free(img);
1129
1238
      }
1130
1239
    }
 
1240
 
 
1241
    if (!got_one_picture) {
 
1242
      /* skipped frame, output a bad frame */
 
1243
      img = this->stream->video_out->get_frame (this->stream->video_out,
 
1244
                                                this->bih.biWidth,
 
1245
                                                this->bih.biHeight,
 
1246
                                                this->aspect_ratio, 
 
1247
                                                this->output_format,
 
1248
                                                VO_BOTH_FIELDS|this->frame_flags);
 
1249
      img->pts       = 0;
 
1250
      img->duration  = this->video_step;
 
1251
      img->bad_frame = 1;
 
1252
      this->skipframes = img->draw(img, this->stream);
 
1253
      img->free(img);
 
1254
    }
 
1255
  }
 
1256
}
 
1257
 
 
1258
static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
 
1259
  ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen;
 
1260
 
 
1261
  lprintf ("processing packet type = %08x, len = %d, decoder_flags=%08x\n", 
 
1262
           buf->type, buf->size, buf->decoder_flags);
 
1263
 
 
1264
  if (buf->decoder_flags & BUF_FLAG_FRAMERATE) {
 
1265
    this->video_step = buf->decoder_info[0];
 
1266
    _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step);
 
1267
  }
 
1268
 
 
1269
  if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
 
1270
  
 
1271
    ff_handle_preview_buffer(this, buf);
 
1272
 
 
1273
  } else {
 
1274
 
 
1275
    if (buf->decoder_flags & BUF_FLAG_SPECIAL) {
 
1276
 
 
1277
      ff_handle_special_buffer(this, buf);
 
1278
                     
 
1279
    }
 
1280
 
 
1281
    if (buf->decoder_flags & BUF_FLAG_HEADER) {
 
1282
 
 
1283
      ff_handle_header_buffer(this, buf);
 
1284
 
 
1285
      if (buf->decoder_flags & BUF_FLAG_ASPECT) {
 
1286
        if (this->aspect_ratio_prio < 3) {
 
1287
          this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2];
 
1288
          this->aspect_ratio_prio = 3;
 
1289
          lprintf("aspect ratio: %f\n", this->aspect_ratio);
 
1290
          set_stream_info(this);
 
1291
        }
 
1292
      }  
 
1293
 
 
1294
    } else {
 
1295
 
 
1296
      /* decode */
 
1297
      if (buf->pts)
 
1298
        this->pts = buf->pts;
 
1299
 
 
1300
      if (this->is_mpeg12) {
 
1301
        ff_handle_mpeg12_buffer(this, buf);
 
1302
      } else {
 
1303
        ff_handle_buffer(this, buf);
 
1304
      }
 
1305
 
 
1306
    }
1131
1307
  }
1132
1308
}
1133
1309
 
1162
1338
  lprintf ("ff_dispose\n");
1163
1339
 
1164
1340
  if (this->decoder_ok) {
 
1341
    pthread_mutex_lock(&ffmpeg_lock);
1165
1342
    avcodec_close (this->context);
 
1343
    pthread_mutex_unlock(&ffmpeg_lock);
1166
1344
 
1167
1345
    this->stream->video_out->close(this->stream->video_out, this->stream);
1168
1346
    this->decoder_ok = 0;
1174
1352
  if(this->context && this->context->extradata)
1175
1353
    free(this->context->extradata);
1176
1354
 
1177
 
  if((this->context) && 
1178
 
   ((this->context->pix_fmt == PIX_FMT_RGBA32) ||
1179
 
    (this->context->pix_fmt == PIX_FMT_RGB565) ||
1180
 
    (this->context->pix_fmt == PIX_FMT_RGB555) ||
1181
 
    (this->context->pix_fmt == PIX_FMT_PAL8)))
 
1355
  if(this->yuv_init)
1182
1356
    free_yuv_planes(&this->yuv);
1183
1357
  
1184
1358
  if( this->context )
1218
1392
  this->stream                            = stream;
1219
1393
  this->class                             = (ff_video_class_t *) class_gen;
1220
1394
 
1221
 
  this->av_frame        = avcodec_alloc_frame();
1222
 
  this->context         = avcodec_alloc_context();
1223
 
  this->context->opaque = this;
1224
 
  this->context->palctrl = &this->palette_control;
 
1395
  this->av_frame          = avcodec_alloc_frame();
 
1396
  this->context           = avcodec_alloc_context();
 
1397
  this->context->opaque   = this;
 
1398
  this->context->palctrl  = NULL;
1225
1399
  
1226
 
  this->decoder_ok    = 0;
1227
 
  this->buf           = xine_xmalloc(VIDEOBUFSIZE + FF_INPUT_BUFFER_PADDING_SIZE);
1228
 
  this->bufsize       = VIDEOBUFSIZE;
1229
 
 
1230
 
  this->is_mpeg12    = 0;
1231
 
  this->aspect_ratio = 0;
1232
 
 
1233
 
  this->pp_quality  = 0;
1234
 
  this->pp_context  = NULL;
1235
 
  this->pp_mode     = NULL;
 
1400
  this->decoder_ok        = 0;
 
1401
  this->decoder_init_mode = 1;
 
1402
  this->buf               = xine_xmalloc(VIDEOBUFSIZE + FF_INPUT_BUFFER_PADDING_SIZE);
 
1403
  this->bufsize           = VIDEOBUFSIZE;
 
1404
 
 
1405
  this->is_mpeg12         = 0;
 
1406
  this->aspect_ratio      = 0;
 
1407
 
 
1408
  this->pp_quality        = 0;
 
1409
  this->pp_context        = NULL;
 
1410
  this->pp_mode           = NULL;
1236
1411
  
1237
1412
  mpeg_parser_init(&this->mpeg_parser);
1238
1413
 
1322
1497
  BUF_VIDEO_SMC,
1323
1498
  BUF_VIDEO_VMD,
1324
1499
  BUF_VIDEO_DUCKTM1,
 
1500
  BUF_VIDEO_DUCKTM2,
1325
1501
  BUF_VIDEO_ZLIB,
1326
1502
  BUF_VIDEO_MSZH,
1327
1503
  BUF_VIDEO_ASV1,
1330
1506
  BUF_VIDEO_FLV1,
1331
1507
  BUF_VIDEO_QTRLE,
1332
1508
  BUF_VIDEO_H264,
 
1509
  BUF_VIDEO_H261,
 
1510
  BUF_VIDEO_AASC,
 
1511
  BUF_VIDEO_LOCO,
 
1512
  BUF_VIDEO_QDRW,
 
1513
  BUF_VIDEO_QPEG,
 
1514
  BUF_VIDEO_TSCC,
 
1515
  BUF_VIDEO_ULTI,
 
1516
  BUF_VIDEO_WNV1,
 
1517
  BUF_VIDEO_XL,
 
1518
  BUF_VIDEO_RT21,
 
1519
  BUF_VIDEO_FPS1,
1333
1520
  0 
1334
1521
};
1335
1522