~ubuntu-branches/ubuntu/intrepid/gstreamer0.10-ffmpeg/intrepid

« back to all changes in this revision

Viewing changes to ext/ffmpeg/gstffmpegdec.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-12-13 23:10:28 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20061213231028-gb7p40u24i5dk331
Tags: 0.10.2-0ubuntu1
* Sync with pkg-gstreamer SVN:
  + debian/rules:
    - Enable the encoders again
* debian/control:
  + Add part about encoders to the description again

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
    } video;
64
64
    struct
65
65
    {
66
 
      gint channels, samplerate;
 
66
      gint channels;
 
67
      gint samplerate;
67
68
    } audio;
68
69
  } format;
69
70
  gboolean waiting_for_key;
70
 
  guint64 next_ts, synctime;
 
71
  gboolean discont;
 
72
  guint64 next_ts;
71
73
 
72
74
  /* parsing */
73
75
  AVCodecParserContext *pctx;
78
80
  GValue *par;                  /* pixel aspect ratio of incoming data */
79
81
 
80
82
  gint hurry_up, lowres;
 
83
 
 
84
  /* QoS stuff *//* with LOCK */
 
85
  gdouble proportion;
 
86
  GstClockTime earliest_time;
 
87
 
 
88
  /* clipping segment */
 
89
  GstSegment segment;
81
90
};
82
91
 
83
92
typedef struct _GstFFMpegDecClass GstFFMpegDecClass;
106
115
  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEC,GstFFMpegDecClass))
107
116
#define GST_IS_FFMPEGDEC(obj) \
108
117
  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEC))
109
 
#define GST_IS_FFMPEGDEC_CLASS(obj) \
 
118
#define GST_IS_FFMPEGDEC_CLASS(klass) \
110
119
  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEC))
111
120
 
112
121
enum
122
131
static void gst_ffmpegdec_base_init (GstFFMpegDecClass * klass);
123
132
static void gst_ffmpegdec_class_init (GstFFMpegDecClass * klass);
124
133
static void gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec);
125
 
static void gst_ffmpegdec_dispose (GObject * object);
 
134
static void gst_ffmpegdec_finalize (GObject * object);
126
135
 
127
136
static gboolean gst_ffmpegdec_query (GstPad * pad, GstQuery * query);
128
 
static gboolean gst_ffmpegdec_event (GstPad * pad, GstEvent * event);
 
137
static gboolean gst_ffmpegdec_src_event (GstPad * pad, GstEvent * event);
129
138
 
130
139
static gboolean gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps);
131
140
static gboolean gst_ffmpegdec_sink_event (GstPad * pad, GstEvent * event);
156
165
  static GType ffmpegdec_lowres_type = 0;
157
166
 
158
167
  if (!ffmpegdec_lowres_type) {
159
 
    static GEnumValue ffmpegdec_lowres[] = {
 
168
    static const GEnumValue ffmpegdec_lowres[] = {
160
169
      {0, "0", "full"},
161
170
      {1, "1", "1/2-size"},
162
171
      {2, "2", "1/4-size"},
177
186
  static GType ffmpegdec_skipframe_type = 0;
178
187
 
179
188
  if (!ffmpegdec_skipframe_type) {
180
 
    static GEnumValue ffmpegdec_skipframe[] = {
 
189
    static const GEnumValue ffmpegdec_skipframe[] = {
181
190
      {0, "0", "Skip nothing"},
182
191
      {1, "1", "Skip B-frames"},
183
192
      {2, "2", "Skip IDCT/Dequantization"},
243
252
 
244
253
  parent_class = g_type_class_peek_parent (klass);
245
254
 
246
 
  gobject_class->dispose = gst_ffmpegdec_dispose;
 
255
  gobject_class->finalize = gst_ffmpegdec_finalize;
 
256
 
247
257
  gobject_class->set_property = gst_ffmpegdec_set_property;
248
258
  gobject_class->get_property = gst_ffmpegdec_get_property;
 
259
 
 
260
  if (klass->in_plugin->type == CODEC_TYPE_VIDEO) {
 
261
    g_object_class_install_property (gobject_class, ARG_SKIPFRAME,
 
262
        g_param_spec_enum ("skip-frame", "Skip frames",
 
263
            "Which types of frames to skip during decoding",
 
264
            GST_FFMPEGDEC_TYPE_SKIPFRAME, 0, G_PARAM_READWRITE));
 
265
    g_object_class_install_property (gobject_class, ARG_LOWRES,
 
266
        g_param_spec_enum ("lowres", "Low resolution",
 
267
            "At which resolution to decode images",
 
268
            GST_FFMPEGDEC_TYPE_LOWRES, 0, G_PARAM_READWRITE));
 
269
  }
 
270
 
249
271
  gstelement_class->change_state = gst_ffmpegdec_change_state;
250
 
 
251
 
  g_object_class_install_property (gobject_class, ARG_SKIPFRAME,
252
 
      g_param_spec_enum ("skip-frame", "Skip frames",
253
 
          "Which types of frames to skip during decoding",
254
 
          GST_FFMPEGDEC_TYPE_SKIPFRAME, 0, G_PARAM_READWRITE));
255
 
  g_object_class_install_property (gobject_class, ARG_LOWRES,
256
 
      g_param_spec_enum ("lowres", "Low resolution",
257
 
          "At which resolution to decode images",
258
 
          GST_FFMPEGDEC_TYPE_LOWRES, 0, G_PARAM_READWRITE));
259
272
}
260
273
 
261
274
static void
262
275
gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec)
263
276
{
264
 
  GstFFMpegDecClass *oclass =
265
 
      (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
277
  GstFFMpegDecClass *oclass;
 
278
 
 
279
  oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
266
280
 
267
281
  /* setup pads */
268
282
  ffmpegdec->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink");
269
 
  gst_pad_set_setcaps_function (ffmpegdec->sinkpad, gst_ffmpegdec_setcaps);
270
 
  gst_pad_set_event_function (ffmpegdec->sinkpad, gst_ffmpegdec_sink_event);
271
 
  gst_pad_set_chain_function (ffmpegdec->sinkpad, gst_ffmpegdec_chain);
 
283
  gst_pad_set_setcaps_function (ffmpegdec->sinkpad,
 
284
      GST_DEBUG_FUNCPTR (gst_ffmpegdec_setcaps));
 
285
  gst_pad_set_event_function (ffmpegdec->sinkpad,
 
286
      GST_DEBUG_FUNCPTR (gst_ffmpegdec_sink_event));
 
287
  gst_pad_set_chain_function (ffmpegdec->sinkpad,
 
288
      GST_DEBUG_FUNCPTR (gst_ffmpegdec_chain));
272
289
  gst_element_add_pad (GST_ELEMENT (ffmpegdec), ffmpegdec->sinkpad);
273
290
 
274
291
  ffmpegdec->srcpad = gst_pad_new_from_template (oclass->srctempl, "src");
275
292
  gst_pad_use_fixed_caps (ffmpegdec->srcpad);
276
293
  gst_pad_set_event_function (ffmpegdec->srcpad,
277
 
      GST_DEBUG_FUNCPTR (gst_ffmpegdec_event));
 
294
      GST_DEBUG_FUNCPTR (gst_ffmpegdec_src_event));
278
295
  gst_pad_set_query_function (ffmpegdec->srcpad,
279
296
      GST_DEBUG_FUNCPTR (gst_ffmpegdec_query));
280
297
  gst_element_add_pad (GST_ELEMENT (ffmpegdec), ffmpegdec->srcpad);
286
303
  ffmpegdec->pcache = NULL;
287
304
  ffmpegdec->par = NULL;
288
305
  ffmpegdec->opened = FALSE;
289
 
  ffmpegdec->waiting_for_key = FALSE;
 
306
  ffmpegdec->waiting_for_key = TRUE;
290
307
  ffmpegdec->hurry_up = ffmpegdec->lowres = 0;
291
308
 
292
309
  ffmpegdec->last_buffer = NULL;
293
310
 
294
311
  ffmpegdec->format.video.fps_n = -1;
295
312
  ffmpegdec->format.video.old_fps_n = -1;
 
313
  gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
296
314
}
297
315
 
298
316
static void
299
 
gst_ffmpegdec_dispose (GObject * object)
 
317
gst_ffmpegdec_finalize (GObject * object)
300
318
{
301
319
  GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) object;
302
320
 
303
 
  G_OBJECT_CLASS (parent_class)->dispose (object);
304
 
  /* old session should have been closed in element_class->dispose */
305
321
  g_assert (!ffmpegdec->opened);
306
322
 
307
323
  /* clean up remaining allocated data */
308
324
  av_free (ffmpegdec->context);
309
325
  av_free (ffmpegdec->picture);
 
326
 
 
327
  G_OBJECT_CLASS (parent_class)->finalize (object);
310
328
}
311
329
 
312
330
static gboolean
314
332
{
315
333
  GstFFMpegDec *ffmpegdec;
316
334
  GstPad *peer;
317
 
  GstFormat bfmt;
318
 
 
319
 
  bfmt = GST_FORMAT_BYTES;
320
 
  ffmpegdec = (GstFFMpegDec *) GST_PAD_PARENT (pad);
321
 
  peer = GST_PAD_PEER (ffmpegdec->sinkpad);
322
 
 
323
 
  if (!peer)
324
 
    goto no_peer;
325
 
 
326
 
  /* just forward to peer */
327
 
  if (gst_pad_query (peer, query))
328
 
    return TRUE;
329
 
 
 
335
  gboolean res;
 
336
 
 
337
  ffmpegdec = (GstFFMpegDec *) gst_pad_get_parent (pad);
 
338
 
 
339
  res = FALSE;
 
340
 
 
341
  if ((peer = gst_pad_get_peer (ffmpegdec->sinkpad))) {
 
342
    /* just forward to peer */
 
343
    res = gst_pad_query (peer, query);
 
344
    gst_object_unref (peer);
 
345
  }
330
346
#if 0
331
 
  /* ok, do bitrate calc... */
332
 
  if ((type != GST_QUERY_POSITION && type != GST_QUERY_TOTAL) ||
333
 
      *fmt != GST_FORMAT_TIME || ffmpegdec->context->bit_rate == 0 ||
334
 
      !gst_pad_query (peer, type, &bfmt, value))
335
 
    return FALSE;
336
 
 
337
 
  if (ffmpegdec->pcache && type == GST_QUERY_POSITION)
338
 
    *value -= GST_BUFFER_SIZE (ffmpegdec->pcache);
339
 
  *value *= GST_SECOND / ffmpegdec->context->bit_rate;
 
347
  {
 
348
    GstFormat bfmt;
 
349
 
 
350
    bfmt = GST_FORMAT_BYTES;
 
351
 
 
352
    /* ok, do bitrate calc... */
 
353
    if ((type != GST_QUERY_POSITION && type != GST_QUERY_TOTAL) ||
 
354
        *fmt != GST_FORMAT_TIME || ffmpegdec->context->bit_rate == 0 ||
 
355
        !gst_pad_query (peer, type, &bfmt, value))
 
356
      return FALSE;
 
357
 
 
358
    if (ffmpegdec->pcache && type == GST_QUERY_POSITION)
 
359
      *value -= GST_BUFFER_SIZE (ffmpegdec->pcache);
 
360
    *value *= GST_SECOND / ffmpegdec->context->bit_rate;
 
361
  }
340
362
#endif
341
363
 
342
 
  return FALSE;
343
 
 
344
 
no_peer:
345
 
  {
346
 
    return FALSE;
347
 
  }
 
364
  gst_object_unref (ffmpegdec);
 
365
 
 
366
  return res;
 
367
}
 
368
 
 
369
static void
 
370
gst_ffmpegdec_update_qos (GstFFMpegDec * ffmpegdec, gdouble proportion,
 
371
    GstClockTime time)
 
372
{
 
373
  GST_OBJECT_LOCK (ffmpegdec);
 
374
  ffmpegdec->proportion = proportion;
 
375
  ffmpegdec->earliest_time = time;
 
376
  GST_OBJECT_UNLOCK (ffmpegdec);
 
377
}
 
378
 
 
379
static void
 
380
gst_ffmpegdec_reset_qos (GstFFMpegDec * ffmpegdec)
 
381
{
 
382
  gst_ffmpegdec_update_qos (ffmpegdec, 0.5, GST_CLOCK_TIME_NONE);
 
383
}
 
384
 
 
385
static void
 
386
gst_ffmpegdec_read_qos (GstFFMpegDec * ffmpegdec, gdouble * proportion,
 
387
    GstClockTime * time)
 
388
{
 
389
  GST_OBJECT_LOCK (ffmpegdec);
 
390
  *proportion = ffmpegdec->proportion;
 
391
  *time = ffmpegdec->earliest_time;
 
392
  GST_OBJECT_UNLOCK (ffmpegdec);
348
393
}
349
394
 
350
395
static gboolean
351
 
gst_ffmpegdec_event (GstPad * pad, GstEvent * event)
 
396
gst_ffmpegdec_src_event (GstPad * pad, GstEvent * event)
352
397
{
353
398
  GstFFMpegDec *ffmpegdec;
354
 
  GstPad *peer;
355
 
 
356
 
  ffmpegdec = (GstFFMpegDec *) GST_PAD_PARENT (pad);
357
 
  peer = GST_PAD_PEER (ffmpegdec->sinkpad);
358
 
 
359
 
  if (!peer)
360
 
    return FALSE;
361
 
 
362
 
  gst_event_ref (event);
363
 
  if (gst_pad_send_event (peer, event)) {
364
 
    gst_event_unref (event);
365
 
    return TRUE;
 
399
  gboolean res;
 
400
 
 
401
  ffmpegdec = (GstFFMpegDec *) gst_pad_get_parent (pad);
 
402
 
 
403
  switch (GST_EVENT_TYPE (event)) {
 
404
    case GST_EVENT_QOS:
 
405
    {
 
406
      gdouble proportion;
 
407
      GstClockTimeDiff diff;
 
408
      GstClockTime timestamp;
 
409
 
 
410
      gst_event_parse_qos (event, &proportion, &diff, &timestamp);
 
411
 
 
412
      /* update our QoS values */
 
413
      gst_ffmpegdec_update_qos (ffmpegdec, proportion, timestamp + diff);
 
414
 
 
415
      /* forward upstream */
 
416
      res = gst_pad_push_event (ffmpegdec->sinkpad, event);
 
417
      break;
 
418
    }
 
419
    default:
 
420
      /* forward upstream */
 
421
      res = gst_pad_push_event (ffmpegdec->sinkpad, event);
 
422
      break;
366
423
  }
367
424
 
368
 
  gst_event_unref (event);
 
425
  gst_object_unref (ffmpegdec);
369
426
 
370
 
  return FALSE;                 /* .. */
 
427
  return res;
371
428
}
372
429
 
373
430
/* with LOCK */
413
470
static gboolean
414
471
gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec)
415
472
{
416
 
  GstFFMpegDecClass *oclass =
417
 
      (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
473
  GstFFMpegDecClass *oclass;
 
474
 
 
475
  oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
418
476
 
419
477
  if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
420
478
    goto could_not_open;
421
479
 
422
480
  ffmpegdec->opened = TRUE;
423
481
 
424
 
  GST_LOG ("Opened ffmpeg codec %s", oclass->in_plugin->name);
 
482
  GST_LOG_OBJECT (ffmpegdec, "Opened ffmpeg codec %s, id %d",
 
483
      oclass->in_plugin->name, oclass->in_plugin->id);
425
484
 
426
 
  /* open a parser if we can - exclude mpeg4, because it is already
427
 
   * framed (divx), mp3 because it doesn't work (?) and mjpeg because
428
 
   * of $(see mpeg4)... */
429
 
  if (oclass->in_plugin->id != CODEC_ID_MPEG4 &&
430
 
      oclass->in_plugin->id != CODEC_ID_MJPEG &&
431
 
      oclass->in_plugin->id != CODEC_ID_MP3 &&
432
 
      oclass->in_plugin->id != CODEC_ID_H264) {
433
 
    ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
 
485
  /* open a parser if we can */
 
486
  switch (oclass->in_plugin->id) {
 
487
    case CODEC_ID_MPEG4:
 
488
    case CODEC_ID_MJPEG:
 
489
    case CODEC_ID_MP3:
 
490
      GST_LOG_OBJECT (ffmpegdec, "not using parser, blacklisted codec");
 
491
      ffmpegdec->pctx = NULL;
 
492
      break;
 
493
    case CODEC_ID_H264:
 
494
      /* For H264, only use a parser if there is no context data, if there is, 
 
495
       * we're talking AVC */
 
496
      if (ffmpegdec->context->extradata_size == 0) {
 
497
        GST_LOG_OBJECT (ffmpegdec, "H264 with no extradata, creating parser");
 
498
        ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
 
499
      }
 
500
      else {
 
501
        GST_LOG_OBJECT (ffmpegdec, 
 
502
            "H264 with extradata implies framed data - not using parser");
 
503
        ffmpegdec->pctx = NULL;
 
504
      }
 
505
      break;
 
506
    default:
 
507
      GST_LOG_OBJECT (ffmpegdec, "Using parser");
 
508
      ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
 
509
      break;
434
510
  }
435
511
 
436
512
  switch (oclass->in_plugin->type) {
446
522
    default:
447
523
      break;
448
524
  }
449
 
  ffmpegdec->next_ts = 0;
450
 
  ffmpegdec->synctime = GST_CLOCK_TIME_NONE;
 
525
  ffmpegdec->next_ts = GST_CLOCK_TIME_NONE;
451
526
  ffmpegdec->last_buffer = NULL;
 
527
  /* FIXME, reset_qos holds the LOCK */
 
528
  ffmpegdec->proportion = 0.0;
 
529
  ffmpegdec->earliest_time = -1;
452
530
 
453
531
  return TRUE;
454
532
 
456
534
could_not_open:
457
535
  {
458
536
    gst_ffmpegdec_close (ffmpegdec);
459
 
    GST_DEBUG ("ffdec_%s: Failed to open FFMPEG codec",
 
537
    GST_DEBUG_OBJECT (ffmpegdec, "ffdec_%s: Failed to open FFMPEG codec",
460
538
        oclass->in_plugin->name);
461
539
    return FALSE;
462
540
  }
465
543
static GstPadLinkReturn
466
544
gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps)
467
545
{
468
 
  GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) (GST_OBJECT_PARENT (pad));
469
 
  GstFFMpegDecClass *oclass =
470
 
      (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
546
  GstFFMpegDec *ffmpegdec;
 
547
  GstFFMpegDecClass *oclass;
471
548
  GstStructure *structure;
472
549
  const GValue *par;
473
550
  const GValue *fps;
474
551
  gboolean ret = TRUE;
475
552
 
 
553
  ffmpegdec = (GstFFMpegDec *) (gst_pad_get_parent (pad));
 
554
  oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
555
 
476
556
  GST_DEBUG_OBJECT (pad, "setcaps called");
477
557
 
478
558
  GST_OBJECT_LOCK (ffmpegdec);
492
572
      oclass->in_plugin->type, caps, ffmpegdec->context);
493
573
 
494
574
  if (!ffmpegdec->context->time_base.den || !ffmpegdec->context->time_base.num) {
495
 
    GST_DEBUG ("forcing 25/1 framerate");
 
575
    GST_DEBUG_OBJECT (ffmpegdec, "forcing 25/1 framerate");
496
576
    ffmpegdec->context->time_base.num = 1;
497
577
    ffmpegdec->context->time_base.den = 25;
498
578
  }
499
579
 
500
580
  /* get pixel aspect ratio if it's set */
501
581
  structure = gst_caps_get_structure (caps, 0);
 
582
 
502
583
  par = gst_structure_get_value (structure, "pixel-aspect-ratio");
503
584
  if (par) {
504
585
    GST_DEBUG_OBJECT (ffmpegdec, "sink caps have pixel-aspect-ratio of %d:%d",
505
586
        gst_value_get_fraction_numerator (par),
506
587
        gst_value_get_fraction_denominator (par));
 
588
    /* should be NULL */
 
589
    if (ffmpegdec->par)
 
590
      g_free (ffmpegdec->par);
507
591
    ffmpegdec->par = g_new0 (GValue, 1);
508
592
    gst_value_init_and_copy (ffmpegdec->par, par);
509
593
  }
510
594
 
 
595
  /* get the framerate from incomming caps. fps_n is set to -1 when
 
596
   * there is no valid framerate */
511
597
  fps = gst_structure_get_value (structure, "framerate");
512
598
  if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
513
599
    ffmpegdec->format.video.fps_n = gst_value_get_fraction_numerator (fps);
514
600
    ffmpegdec->format.video.fps_d = gst_value_get_fraction_denominator (fps);
515
 
    GST_DEBUG_OBJECT (ffmpegdec, "Using framerate %d/%d from incoming caps\n",
 
601
    GST_DEBUG_OBJECT (ffmpegdec, "Using framerate %d/%d from incoming caps",
516
602
        ffmpegdec->format.video.fps_n, ffmpegdec->format.video.fps_d);
517
603
  } else {
518
604
    ffmpegdec->format.video.fps_n = -1;
519
 
    GST_DEBUG_OBJECT (ffmpegdec, "Using framerate from codec\n");
 
605
    GST_DEBUG_OBJECT (ffmpegdec, "Using framerate from codec");
520
606
  }
521
607
 
522
608
  /* do *not* draw edges */
532
618
  /* open codec - we don't select an output pix_fmt yet,
533
619
   * simply because we don't know! We only get it
534
620
   * during playback... */
535
 
  if (!gst_ffmpegdec_open (ffmpegdec)) {
 
621
  if (!gst_ffmpegdec_open (ffmpegdec))
 
622
    goto open_failed;
 
623
 
 
624
done:
 
625
  GST_OBJECT_UNLOCK (ffmpegdec);
 
626
 
 
627
  gst_object_unref (ffmpegdec);
 
628
 
 
629
  return ret;
 
630
 
 
631
  /* ERRORS */
 
632
open_failed:
 
633
  {
 
634
    GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
536
635
    if (ffmpegdec->par) {
537
636
      g_free (ffmpegdec->par);
538
637
      ffmpegdec->par = NULL;
539
638
    }
540
639
    ret = FALSE;
 
640
    goto done;
541
641
  }
542
 
 
543
 
  GST_OBJECT_UNLOCK (ffmpegdec);
544
 
 
545
 
  return ret;
546
642
}
547
643
 
548
644
static int
550
646
{
551
647
  GstBuffer *buf = NULL;
552
648
  gulong bufsize = 0;
553
 
  GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) context->opaque;
554
 
  int width = context->width;
555
 
  int height = context->height;
 
649
  GstFFMpegDec *ffmpegdec;
 
650
  int width;
 
651
  int height;
 
652
 
 
653
  ffmpegdec = (GstFFMpegDec *) context->opaque;
 
654
 
 
655
  width = context->width;
 
656
  height = context->height;
556
657
 
557
658
  switch (context->codec_type) {
558
659
    case CODEC_TYPE_VIDEO:
559
 
 
560
660
      avcodec_align_dimensions (context, &width, &height);
561
661
 
562
662
      bufsize = avpicture_get_size (context->pix_fmt, width, height);
572
672
 
573
673
        return avcodec_default_get_buffer (context, picture);
574
674
#endif
575
 
 
576
675
      }
577
676
 
578
677
      if (!gst_ffmpegdec_negotiate (ffmpegdec)) {
581
680
        return avcodec_default_get_buffer (context, picture);
582
681
      }
583
682
 
584
 
      if (gst_pad_alloc_buffer_and_set_caps (ffmpegdec->srcpad, GST_BUFFER_OFFSET_NONE,
585
 
              bufsize, GST_PAD_CAPS (ffmpegdec->srcpad), &buf) != GST_FLOW_OK)
 
683
      if (gst_pad_alloc_buffer_and_set_caps (ffmpegdec->srcpad,
 
684
              GST_BUFFER_OFFSET_NONE, bufsize, GST_PAD_CAPS (ffmpegdec->srcpad),
 
685
              &buf) != GST_FLOW_OK)
586
686
        return -1;
587
687
      ffmpegdec->last_buffer = buf;
588
688
 
590
690
          GST_BUFFER_DATA (buf),
591
691
          context->pix_fmt, context->width, context->height);
592
692
      break;
593
 
 
594
693
    case CODEC_TYPE_AUDIO:
595
694
    default:
596
 
      g_assert (0);
 
695
      g_assert_not_reached ();
597
696
      break;
598
697
  }
599
698
 
605
704
   * so that we don't need to copy data */
606
705
  picture->type = FF_BUFFER_TYPE_USER;
607
706
  picture->age = G_MAXINT;
 
707
  gst_buffer_ref (buf);
608
708
  picture->opaque = buf;
609
 
  gst_buffer_ref (buf);
610
709
 
611
710
  GST_LOG_OBJECT (ffmpegdec, "END");
612
711
 
618
717
{
619
718
  gint i;
620
719
  GstBuffer *buf;
621
 
  GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) context->opaque;
 
720
  GstFFMpegDec *ffmpegdec;
622
721
 
623
722
  g_return_if_fail (picture->type == FF_BUFFER_TYPE_USER);
624
723
 
625
724
  buf = GST_BUFFER (picture->opaque);
626
 
 
627
725
  g_return_if_fail (buf != NULL);
628
726
 
 
727
  ffmpegdec = (GstFFMpegDec *) context->opaque;
 
728
 
629
729
  if (buf == ffmpegdec->last_buffer)
630
730
    ffmpegdec->last_buffer = NULL;
631
731
  gst_buffer_unref (buf);
645
745
{
646
746
  gboolean demuxer_par_set = FALSE;
647
747
  gboolean decoder_par_set = FALSE;
648
 
  gint demuxer_num, demuxer_denom;
649
 
  gint decoder_num, decoder_denom;
 
748
  gint demuxer_num = 1, demuxer_denom = 1;
 
749
  gint decoder_num = 1, decoder_denom = 1;
650
750
 
651
751
  GST_OBJECT_LOCK (ffmpegdec);
652
752
 
654
754
    demuxer_num = gst_value_get_fraction_numerator (ffmpegdec->par);
655
755
    demuxer_denom = gst_value_get_fraction_denominator (ffmpegdec->par);
656
756
    demuxer_par_set = TRUE;
657
 
    GST_DEBUG ("Demuxer PAR: %d:%d", demuxer_num, demuxer_denom);
 
757
    GST_DEBUG_OBJECT (ffmpegdec, "Demuxer PAR: %d:%d", demuxer_num,
 
758
        demuxer_denom);
658
759
  }
659
760
 
660
761
  if (ffmpegdec->context->sample_aspect_ratio.num &&
662
763
    decoder_num = ffmpegdec->context->sample_aspect_ratio.num;
663
764
    decoder_denom = ffmpegdec->context->sample_aspect_ratio.den;
664
765
    decoder_par_set = TRUE;
665
 
    GST_DEBUG ("Decoder PAR: %d:%d", decoder_num, decoder_denom);
 
766
    GST_DEBUG_OBJECT (ffmpegdec, "Decoder PAR: %d:%d", decoder_num,
 
767
        decoder_denom);
666
768
  }
667
769
 
668
770
  GST_OBJECT_UNLOCK (ffmpegdec);
669
771
 
670
 
  if (!demuxer_par_set && !decoder_par_set) {
671
 
    GST_DEBUG ("Neither demuxer nor codec provide a pixel-aspect-ratio");
672
 
    return;
673
 
  }
 
772
  if (!demuxer_par_set && !decoder_par_set)
 
773
    goto no_par;
674
774
 
675
775
  if (demuxer_par_set && !decoder_par_set)
676
776
    goto use_demuxer_par;
682
782
   * the two PARs is 1:1 and the other one is not, use the one
683
783
   * that is not 1:1. If both are non-1:1, use the pixel aspect
684
784
   * ratio provided by the codec */
685
 
 
686
785
  if (demuxer_num == demuxer_denom && decoder_num != decoder_denom)
687
786
    goto use_decoder_par;
688
787
 
690
789
    goto use_demuxer_par;
691
790
 
692
791
  /* fall through and use decoder pixel aspect ratio */
693
 
 
694
792
use_decoder_par:
695
793
  {
696
 
    GST_DEBUG ("Setting decoder provided pixel-aspect-ratio of %u:%u",
697
 
        decoder_num, decoder_denom);
698
 
    gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION,
699
 
        decoder_num, decoder_denom, NULL);
 
794
    GST_DEBUG_OBJECT (ffmpegdec,
 
795
        "Setting decoder provided pixel-aspect-ratio of %u:%u", decoder_num,
 
796
        decoder_denom);
 
797
    gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, decoder_num,
 
798
        decoder_denom, NULL);
700
799
    return;
701
800
  }
702
801
 
703
802
use_demuxer_par:
704
803
  {
705
 
    GST_DEBUG ("Setting demuxer provided pixel-aspect-ratio of %u:%u",
706
 
        demuxer_num, demuxer_denom);
707
 
    gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION,
708
 
        demuxer_num, demuxer_denom, NULL);
709
 
    return;
710
 
  }
711
 
 
 
804
    GST_DEBUG_OBJECT (ffmpegdec,
 
805
        "Setting demuxer provided pixel-aspect-ratio of %u:%u", demuxer_num,
 
806
        demuxer_denom);
 
807
    gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, demuxer_num,
 
808
        demuxer_denom, NULL);
 
809
    return;
 
810
  }
 
811
no_par:
 
812
  {
 
813
    GST_DEBUG_OBJECT (ffmpegdec,
 
814
        "Neither demuxer nor codec provide a pixel-aspect-ratio");
 
815
    return;
 
816
  }
712
817
}
713
818
 
714
819
static gboolean
715
820
gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec)
716
821
{
717
 
  GstFFMpegDecClass *oclass =
718
 
      (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
822
  GstFFMpegDecClass *oclass;
719
823
  GstCaps *caps;
720
824
 
 
825
  oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
826
 
721
827
  switch (oclass->in_plugin->type) {
722
828
    case CODEC_TYPE_VIDEO:
723
829
      if (ffmpegdec->format.video.width == ffmpegdec->context->width &&
743
849
          ffmpegdec->context->sample_rate &&
744
850
          ffmpegdec->format.audio.channels == ffmpegdec->context->channels)
745
851
        return TRUE;
746
 
      GST_DEBUG ("Renegotiating audio from %dHz@%dchannels to %dHz@%dchannels",
 
852
      GST_DEBUG_OBJECT (ffmpegdec,
 
853
          "Renegotiating audio from %dHz@%dchannels to %dHz@%dchannels",
747
854
          ffmpegdec->format.audio.samplerate, ffmpegdec->format.audio.channels,
748
855
          ffmpegdec->context->sample_rate, ffmpegdec->context->channels);
749
856
      ffmpegdec->format.audio.samplerate = ffmpegdec->context->sample_rate;
756
863
  caps = gst_ffmpeg_codectype_to_caps (oclass->in_plugin->type,
757
864
      ffmpegdec->context);
758
865
 
759
 
  if (caps) {
760
 
    /* If a demuxer provided a framerate then use it (#313970) */
 
866
  if (caps == NULL)
 
867
    goto no_caps;
 
868
 
 
869
  switch (oclass->in_plugin->type) {
 
870
    case CODEC_TYPE_VIDEO:
 
871
      /* If a demuxer provided a framerate then use it (#313970) */
 
872
      if (ffmpegdec->format.video.fps_n != -1) {
 
873
        gst_caps_set_simple (caps, "framerate",
 
874
            GST_TYPE_FRACTION, ffmpegdec->format.video.fps_n,
 
875
            ffmpegdec->format.video.fps_d, NULL);
 
876
      }
 
877
      gst_ffmpegdec_add_pixel_aspect_ratio (ffmpegdec,
 
878
          gst_caps_get_structure (caps, 0));
 
879
      break;
 
880
    case CODEC_TYPE_AUDIO:
 
881
    {
 
882
      break;
 
883
    }
 
884
    default:
 
885
      break;
 
886
  }
 
887
 
 
888
  if (!gst_pad_set_caps (ffmpegdec->srcpad, caps))
 
889
    goto caps_failed;
 
890
 
 
891
  gst_caps_unref (caps);
 
892
 
 
893
  return TRUE;
 
894
 
 
895
  /* ERRORS */
 
896
no_caps:
 
897
  {
 
898
    GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
 
899
        ("could not find caps for codec (%s), unknown type",
 
900
            oclass->in_plugin->name));
 
901
    return FALSE;
 
902
  }
 
903
caps_failed:
 
904
  {
 
905
    GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
 
906
        ("Could not set caps for ffmpeg decoder (%s), not fixed?",
 
907
            oclass->in_plugin->name));
 
908
    gst_caps_unref (caps);
 
909
 
 
910
    return FALSE;
 
911
  }
 
912
}
 
913
 
 
914
/* perform qos calculations before decoding the next frame.
 
915
 *
 
916
 * Sets the hurry_up flag and if things are really bad, skips to the next
 
917
 * keyframe.
 
918
 * 
 
919
 * Returns TRUE if the frame should be decoded, FALSE if the frame can be dropped
 
920
 * entirely.
 
921
 */
 
922
static gboolean
 
923
gst_ffmpegdec_do_qos (GstFFMpegDec * ffmpegdec, GstClockTime timestamp,
 
924
    gboolean * mode_switch)
 
925
{
 
926
  GstClockTimeDiff diff;
 
927
  gdouble proportion;
 
928
  GstClockTime qostime, earliest_time;
 
929
 
 
930
  *mode_switch = FALSE;
 
931
 
 
932
  /* no timestamp, can't do QoS */
 
933
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp)))
 
934
    goto no_qos;
 
935
 
 
936
  /* get latest QoS observation values */
 
937
  gst_ffmpegdec_read_qos (ffmpegdec, &proportion, &earliest_time);
 
938
 
 
939
  /* skip qos if we have no observation (yet) */
 
940
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
 
941
    /* no hurry_up initialy */
 
942
    ffmpegdec->context->hurry_up = 0;
 
943
    goto no_qos;
 
944
  }
 
945
 
 
946
  /* qos is done on running time */
 
947
  qostime = gst_segment_to_running_time (&ffmpegdec->segment, GST_FORMAT_TIME,
 
948
      timestamp);
 
949
 
 
950
  /* see how our next timestamp relates to the latest qos timestamp. negative
 
951
   * values mean we are early, positive values mean we are too late. */
 
952
  diff = GST_CLOCK_DIFF (qostime, earliest_time);
 
953
 
 
954
  GST_DEBUG_OBJECT (ffmpegdec, "QOS: qostime %" GST_TIME_FORMAT
 
955
      ", earliest %" GST_TIME_FORMAT, GST_TIME_ARGS (qostime),
 
956
      GST_TIME_ARGS (earliest_time));
 
957
 
 
958
  /* if we using less than 40% of the available time, we can try to
 
959
   * speed up again when we were slow. */
 
960
  if (proportion < 0.4 && diff < 0) {
 
961
    goto normal_mode;
 
962
  } else {
 
963
    /* if we're more than two seconds late, switch to the next keyframe */
 
964
    /* FIXME, let the demuxer decide what's the best since we might be dropping
 
965
     * a lot of frames when the keyframe is far away or we even might not get a new
 
966
     * keyframe at all.. */
 
967
    if (diff > ((GstClockTimeDiff) GST_SECOND * 2)
 
968
        && !ffmpegdec->waiting_for_key) {
 
969
      goto skip_to_keyframe;
 
970
    } else if (diff >= 0) {
 
971
      /* we're too slow, try to speed up */
 
972
      if (ffmpegdec->waiting_for_key) {
 
973
        /* we were waiting for a keyframe, that's ok */
 
974
        goto skipping;
 
975
      }
 
976
      /* switch to hurry_up mode */
 
977
      goto hurry_up;
 
978
    }
 
979
  }
 
980
 
 
981
no_qos:
 
982
  return TRUE;
 
983
 
 
984
skipping:
 
985
  {
 
986
    return FALSE;
 
987
  }
 
988
normal_mode:
 
989
  {
 
990
    if (ffmpegdec->context->hurry_up != 0) {
 
991
      ffmpegdec->context->hurry_up = 0;
 
992
      *mode_switch = TRUE;
 
993
      GST_DEBUG_OBJECT (ffmpegdec, "QOS: normal mode %g < 0.4", proportion);
 
994
    }
 
995
    return TRUE;
 
996
  }
 
997
skip_to_keyframe:
 
998
  {
 
999
    ffmpegdec->context->hurry_up = 1;
 
1000
    ffmpegdec->waiting_for_key = TRUE;
 
1001
    *mode_switch = TRUE;
 
1002
    GST_DEBUG_OBJECT (ffmpegdec,
 
1003
        "QOS: keyframe, %" G_GINT64_FORMAT " > GST_SECOND/2", diff);
 
1004
    /* we can skip the current frame */
 
1005
    return FALSE;
 
1006
  }
 
1007
hurry_up:
 
1008
  {
 
1009
    if (ffmpegdec->context->hurry_up != 1) {
 
1010
      ffmpegdec->context->hurry_up = 1;
 
1011
      *mode_switch = TRUE;
 
1012
      GST_DEBUG_OBJECT (ffmpegdec,
 
1013
          "QOS: hurry up, diff %" G_GINT64_FORMAT " >= 0", diff);
 
1014
    }
 
1015
    return TRUE;
 
1016
  }
 
1017
}
 
1018
 
 
1019
/* returns TRUE if buffer is within segment, else FALSE.
 
1020
 * if Buffer is on segment border, it's timestamp and duration will be clipped */
 
1021
static gboolean
 
1022
clip_video_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
 
1023
    GstClockTime in_dur)
 
1024
{
 
1025
  gboolean res = TRUE;
 
1026
  gint64 cstart, cstop;
 
1027
  GstClockTime stop;
 
1028
 
 
1029
  GST_LOG_OBJECT (dec,
 
1030
      "timestamp:%" GST_TIME_FORMAT " , duration:%" GST_TIME_FORMAT,
 
1031
      GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur));
 
1032
 
 
1033
  /* can't clip without TIME segment */
 
1034
  if (G_UNLIKELY (dec->segment.format != GST_FORMAT_TIME))
 
1035
    goto beach;
 
1036
 
 
1037
  /* we need a start time */
 
1038
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (in_ts)))
 
1039
    goto beach;
 
1040
 
 
1041
  /* generate valid stop, if duration unknown, we have unknown stop */
 
1042
  stop =
 
1043
      GST_CLOCK_TIME_IS_VALID (in_dur) ? (in_ts + in_dur) : GST_CLOCK_TIME_NONE;
 
1044
 
 
1045
  /* now clip */
 
1046
  res =
 
1047
      gst_segment_clip (&dec->segment, GST_FORMAT_TIME, in_ts, stop, &cstart,
 
1048
      &cstop);
 
1049
  if (G_UNLIKELY (!res))
 
1050
    goto beach;
 
1051
 
 
1052
  /* update timestamp and possibly duration if the clipped stop time is
 
1053
   * valid */
 
1054
  GST_BUFFER_TIMESTAMP (buf) = cstart;
 
1055
  if (GST_CLOCK_TIME_IS_VALID (cstop))
 
1056
    GST_BUFFER_DURATION (buf) = cstop - cstart;
 
1057
 
 
1058
beach:
 
1059
  GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : ""));
 
1060
  return res;
 
1061
}
 
1062
 
 
1063
 
 
1064
/* figure out if the current picture is a keyframe, return TRUE if that is
 
1065
 * the case. */
 
1066
static gboolean
 
1067
check_keyframe (GstFFMpegDec * ffmpegdec)
 
1068
{
 
1069
  GstFFMpegDecClass *oclass;
 
1070
  gboolean is_itype = FALSE;
 
1071
  gboolean is_reference = FALSE;
 
1072
  gboolean iskeyframe;
 
1073
 
 
1074
  /* figure out if we are dealing with a keyframe */
 
1075
  oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
1076
 
 
1077
  is_itype = (ffmpegdec->picture->pict_type == FF_I_TYPE);
 
1078
  is_reference = (ffmpegdec->picture->reference == 1);
 
1079
 
 
1080
  iskeyframe = (is_itype || is_reference || ffmpegdec->picture->key_frame)
 
1081
      || (oclass->in_plugin->id == CODEC_ID_INDEO3)
 
1082
      || (oclass->in_plugin->id == CODEC_ID_MSZH)
 
1083
      || (oclass->in_plugin->id == CODEC_ID_ZLIB)
 
1084
      || (oclass->in_plugin->id == CODEC_ID_VP3)
 
1085
      || (oclass->in_plugin->id == CODEC_ID_HUFFYUV);
 
1086
 
 
1087
  GST_LOG_OBJECT (ffmpegdec,
 
1088
      "current picture: type: %d, is_keyframe:%d, is_itype:%d, is_reference:%d",
 
1089
      ffmpegdec->picture->pict_type, iskeyframe, is_itype, is_reference);
 
1090
 
 
1091
  return iskeyframe;
 
1092
}
 
1093
 
 
1094
/* get an outbuf buffer with the current picture */
 
1095
static GstFlowReturn
 
1096
get_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf)
 
1097
{
 
1098
  GstFlowReturn ret;
 
1099
 
 
1100
  ret = GST_FLOW_ERROR;
 
1101
  *outbuf = NULL;
 
1102
 
 
1103
  /* libavcodec constantly crashes on stupid buffer allocation
 
1104
   * errors inside. This drives me crazy, so we let it allocate
 
1105
   * its own buffers and copy to our own buffer afterwards... */
 
1106
  /* BUFFER CREATION */
 
1107
  if (ffmpegdec->picture->opaque != NULL) {
 
1108
    *outbuf = (GstBuffer *) ffmpegdec->picture->opaque;
 
1109
    if (*outbuf == ffmpegdec->last_buffer)
 
1110
      ffmpegdec->last_buffer = NULL;
 
1111
    if (*outbuf != NULL)
 
1112
      ret = GST_FLOW_OK;
 
1113
  } else {
 
1114
    AVPicture pic;
 
1115
    gint fsize;
 
1116
 
 
1117
    /* see if we need renegotiation */
 
1118
    if (G_UNLIKELY (!gst_ffmpegdec_negotiate (ffmpegdec)))
 
1119
      goto negotiate_failed;
 
1120
 
 
1121
    fsize = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
 
1122
        ffmpegdec->context->width, ffmpegdec->context->height);
 
1123
 
 
1124
    if (!ffmpegdec->context->palctrl) {
 
1125
      ret = gst_pad_alloc_buffer_and_set_caps (ffmpegdec->srcpad,
 
1126
          GST_BUFFER_OFFSET_NONE, fsize,
 
1127
          GST_PAD_CAPS (ffmpegdec->srcpad), outbuf);
 
1128
      if (G_UNLIKELY (ret != GST_FLOW_OK))
 
1129
        goto alloc_failed;
 
1130
 
 
1131
    } else {
 
1132
      /* for paletted data we can't use pad_alloc_buffer(), because
 
1133
       * fsize contains the size of the palette, so the overall size
 
1134
       * is bigger than ffmpegcolorspace's unit size, which will
 
1135
       * prompt GstBaseTransform to complain endlessly ... */
 
1136
      *outbuf = gst_buffer_new_and_alloc (fsize);
 
1137
      gst_buffer_set_caps (*outbuf, GST_PAD_CAPS (ffmpegdec->srcpad));
 
1138
      ret = GST_FLOW_OK;
 
1139
    }
 
1140
 
 
1141
    /* original ffmpeg code does not handle odd sizes correctly.
 
1142
     * This patched up version does */
 
1143
    gst_ffmpeg_avpicture_fill (&pic, GST_BUFFER_DATA (*outbuf),
 
1144
        ffmpegdec->context->pix_fmt,
 
1145
        ffmpegdec->context->width, ffmpegdec->context->height);
 
1146
 
 
1147
    /* the original convert function did not do the right thing, this
 
1148
     * is a patched up version that adjust widht/height so that the
 
1149
     * ffmpeg one works correctly. */
 
1150
    gst_ffmpeg_img_convert (&pic, ffmpegdec->context->pix_fmt,
 
1151
        (AVPicture *) ffmpegdec->picture,
 
1152
        ffmpegdec->context->pix_fmt,
 
1153
        ffmpegdec->context->width, ffmpegdec->context->height);
 
1154
  }
 
1155
  return ret;
 
1156
 
 
1157
  /* special cases */
 
1158
negotiate_failed:
 
1159
  {
 
1160
    GST_DEBUG_OBJECT (ffmpegdec, "negotiate failed");
 
1161
    return GST_FLOW_NOT_NEGOTIATED;
 
1162
  }
 
1163
alloc_failed:
 
1164
  {
 
1165
    GST_DEBUG_OBJECT (ffmpegdec, "pad_alloc failed");
 
1166
    return ret;
 
1167
  }
 
1168
}
 
1169
 
 
1170
/* gst_ffmpegdec_[video|audio]_frame:
 
1171
 * ffmpegdec:
 
1172
 * data: pointer to the data to decode
 
1173
 * size: size of data in bytes
 
1174
 * in_timestamp: incoming timestamp.
 
1175
 * in_duration: incoming duration.
 
1176
 * outbuf: outgoing buffer. Different from NULL ONLY if it contains decoded data.
 
1177
 * ret: Return flow.
 
1178
 *
 
1179
 * Returns: number of bytes used in decoding. The check for successful decode is
 
1180
 *   outbuf being non-NULL.
 
1181
 */
 
1182
 
 
1183
static gint
 
1184
gst_ffmpegdec_video_frame (GstFFMpegDec * ffmpegdec,
 
1185
    guint8 * data, guint size,
 
1186
    GstClockTime in_timestamp, GstClockTime in_duration, 
 
1187
    GstBuffer ** outbuf, GstFlowReturn * ret)
 
1188
{
 
1189
  gint len = -1;
 
1190
  gint have_data;
 
1191
  gboolean iskeyframe;
 
1192
  gboolean mode_switch;
 
1193
 
 
1194
  *ret = GST_FLOW_OK;
 
1195
  *outbuf = NULL;
 
1196
 
 
1197
  ffmpegdec->context->opaque = ffmpegdec;
 
1198
 
 
1199
  /* run QoS code, returns FALSE if we can skip decoding this
 
1200
   * frame entirely. */
 
1201
  if (G_UNLIKELY (!gst_ffmpegdec_do_qos (ffmpegdec, in_timestamp, &mode_switch)))
 
1202
    goto drop_qos;
 
1203
 
 
1204
  /* in case we skip frames */
 
1205
  ffmpegdec->picture->pict_type = -1;
 
1206
 
 
1207
  /* now decode the frame */
 
1208
  len = avcodec_decode_video (ffmpegdec->context,
 
1209
      ffmpegdec->picture, &have_data, data, size);
 
1210
 
 
1211
  GST_DEBUG_OBJECT (ffmpegdec, "after decode: len %d, have_data %d",
 
1212
      len, have_data);
 
1213
 
 
1214
  /* when we are in hurry_up mode, don't complain when ffmpeg returned
 
1215
   * no data because we told it to skip stuff. */
 
1216
  if (len < 0 && (mode_switch || ffmpegdec->context->hurry_up))
 
1217
    len = 0;
 
1218
 
 
1219
  /* no data, we're done */
 
1220
  if (len < 0 || have_data <= 0)
 
1221
    goto beach;
 
1222
 
 
1223
  GST_DEBUG_OBJECT (ffmpegdec, "picture: pts %"G_GUINT64_FORMAT, ffmpegdec->picture->pts);
 
1224
  GST_DEBUG_OBJECT (ffmpegdec, "picture: num %d", ffmpegdec->picture->coded_picture_number);
 
1225
  GST_DEBUG_OBJECT (ffmpegdec, "picture: display %d", ffmpegdec->picture->display_picture_number);
 
1226
 
 
1227
  /* check if we are dealing with a keyframe here */
 
1228
  iskeyframe = check_keyframe (ffmpegdec);
 
1229
 
 
1230
  /* when we're waiting for a keyframe, see if we have one or drop the current
 
1231
   * non-keyframe */
 
1232
  if (G_UNLIKELY (ffmpegdec->waiting_for_key)) {
 
1233
    if (G_LIKELY (!iskeyframe))
 
1234
      goto drop_non_keyframe;
 
1235
 
 
1236
    /* we have a keyframe, we can stop waiting for one */
 
1237
    ffmpegdec->waiting_for_key = FALSE;
 
1238
  }
 
1239
 
 
1240
  /* get a handle to the output buffer */
 
1241
  *ret = get_output_buffer (ffmpegdec, outbuf);
 
1242
  if (G_UNLIKELY (*ret != GST_FLOW_OK))
 
1243
    goto no_output;
 
1244
 
 
1245
  /*
 
1246
   * Timestamps:
 
1247
   *
 
1248
   *  1) Copy parse context timestamp if present and valid (FIXME)
 
1249
   *  2) Copy input timestamp if valid
 
1250
   *  3) else interpolate from previous input timestamp
 
1251
   */
 
1252
#if 0
 
1253
  /* this does not work reliably, for some files this works fine, for other
 
1254
   * files it returns the same timestamp twice. Leaving the code here for when
 
1255
   * the parsers are improved in ffmpeg. */
 
1256
  if (ffmpegdec->pctx) {
 
1257
    GST_DEBUG_OBJECT (ffmpegdec, "picture: ffpts %"G_GUINT64_FORMAT, ffmpegdec->pctx->pts);
 
1258
    if (ffmpegdec->pctx->pts != AV_NOPTS_VALUE) {
 
1259
      in_timestamp = gst_ffmpeg_time_ff_to_gst (ffmpegdec->pctx->pts,
 
1260
            ffmpegdec->context->time_base);
 
1261
    }
 
1262
  }
 
1263
#endif
 
1264
  if (!GST_CLOCK_TIME_IS_VALID (in_timestamp)) {
 
1265
    GST_LOG_OBJECT (ffmpegdec, "using timestamp returned by ffmpeg");
 
1266
    /* Get (interpolated) timestamp from FFMPEG */
 
1267
    in_timestamp = gst_ffmpeg_time_ff_to_gst ((guint64) ffmpegdec->picture->pts,
 
1268
        ffmpegdec->context->time_base);
 
1269
  }
 
1270
  GST_BUFFER_TIMESTAMP (*outbuf) = in_timestamp;
 
1271
 
 
1272
  /*
 
1273
   * Duration:
 
1274
   *
 
1275
   *  1) Copy input duration if valid
 
1276
   *  2) else use input framerate
 
1277
   *  3) else use ffmpeg framerate
 
1278
   */
 
1279
  if (!GST_CLOCK_TIME_IS_VALID (in_duration)) {
 
1280
    /* if we have an input framerate, use that */
761
1281
    if (ffmpegdec->format.video.fps_n != -1) {
762
 
      gst_structure_set (gst_caps_get_structure (caps, 0), "framerate",
763
 
          GST_TYPE_FRACTION, ffmpegdec->format.video.fps_n,
764
 
          ffmpegdec->format.video.fps_d, NULL);
765
 
    }
766
 
 
767
 
    gst_ffmpegdec_add_pixel_aspect_ratio (ffmpegdec,
768
 
        gst_caps_get_structure (caps, 0));
769
 
  }
770
 
 
771
 
  if (caps == NULL || !gst_pad_set_caps (ffmpegdec->srcpad, caps)) {
772
 
    GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
773
 
        ("Failed to link ffmpeg decoder (%s) to next element",
774
 
            oclass->in_plugin->name));
775
 
 
776
 
    if (caps != NULL)
777
 
      gst_caps_unref (caps);
778
 
 
779
 
    return FALSE;
780
 
  }
781
 
 
782
 
  gst_caps_unref (caps);
783
 
 
784
 
  return TRUE;
785
 
}
 
1282
      GST_LOG_OBJECT (ffmpegdec, "using input framerate for duration");
 
1283
      in_duration = gst_util_uint64_scale_int (GST_SECOND,
 
1284
          ffmpegdec->format.video.fps_d, ffmpegdec->format.video.fps_n);
 
1285
    } else {
 
1286
      /* don't try to use the decoder's framerate when it seems a bit abnormal,
 
1287
       * which we assume when den >= 1000... */
 
1288
      if (ffmpegdec->context->time_base.num != 0 &&
 
1289
          (ffmpegdec->context->time_base.den > 0 &&
 
1290
              ffmpegdec->context->time_base.den < 1000)) {
 
1291
        GST_LOG_OBJECT (ffmpegdec, "using decoder's framerate for duration");
 
1292
        in_duration = gst_util_uint64_scale_int (GST_SECOND,
 
1293
            ffmpegdec->context->time_base.num,
 
1294
            ffmpegdec->context->time_base.den);
 
1295
      } else {
 
1296
        GST_LOG_OBJECT (ffmpegdec, "no valid duration found");
 
1297
      }
 
1298
    }
 
1299
  }
 
1300
 
 
1301
  /* Take repeat_pict into account */
 
1302
  if (GST_CLOCK_TIME_IS_VALID (in_duration)) {
 
1303
    in_duration += in_duration * ffmpegdec->picture->repeat_pict / 2;
 
1304
  }
 
1305
  GST_BUFFER_DURATION (*outbuf) = in_duration;
 
1306
 
 
1307
  /* palette is not part of raw video frame in gst and the size
 
1308
   * of the outgoing buffer needs to be adjusted accordingly */
 
1309
  if (ffmpegdec->context->palctrl != NULL)
 
1310
    GST_BUFFER_SIZE (*outbuf) -= AVPALETTE_SIZE;
 
1311
 
 
1312
  /* now see if we need to clip the buffer against the segment boundaries. */
 
1313
  if (G_UNLIKELY (!clip_video_buffer (ffmpegdec, *outbuf, in_timestamp, in_duration)))
 
1314
    goto clipped;
 
1315
 
 
1316
  /* mark as keyframe or delta unit */
 
1317
  if (!iskeyframe)
 
1318
    GST_BUFFER_FLAG_SET (*outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
 
1319
 
 
1320
beach:
 
1321
  GST_DEBUG_OBJECT (ffmpegdec, "return flow %d, out %p, len %d",
 
1322
      *ret, *outbuf, len);
 
1323
  return len;
 
1324
 
 
1325
  /* special cases */
 
1326
drop_qos:
 
1327
  {
 
1328
    GST_WARNING_OBJECT (ffmpegdec, "Dropping frame because of QoS");
 
1329
    goto beach;
 
1330
  }
 
1331
drop_non_keyframe:
 
1332
  {
 
1333
    GST_WARNING_OBJECT (ffmpegdec, "Dropping non-keyframe (seek/init)");
 
1334
    goto beach;
 
1335
  }
 
1336
no_output:
 
1337
  {
 
1338
    GST_DEBUG_OBJECT (ffmpegdec, "no output buffer");
 
1339
    len = -1;
 
1340
    goto beach;
 
1341
  }
 
1342
clipped:
 
1343
  {
 
1344
    GST_DEBUG_OBJECT (ffmpegdec, "buffer clipped");
 
1345
    gst_buffer_unref (*outbuf);
 
1346
    *outbuf = NULL;
 
1347
    goto beach;
 
1348
  }
 
1349
}
 
1350
 
 
1351
/* returns TRUE if buffer is within segment, else FALSE.
 
1352
 * if Buffer is on segment border, it's timestamp and duration will be clipped */
 
1353
static gboolean
 
1354
clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
 
1355
    GstClockTime in_dur)
 
1356
{
 
1357
  GstClockTime stop;
 
1358
  gint64 diff, ctime, cstop;
 
1359
  gboolean res = TRUE;
 
1360
 
 
1361
  GST_LOG_OBJECT (dec,
 
1362
      "timestamp:%" GST_TIME_FORMAT ", duration:%" GST_TIME_FORMAT
 
1363
      ", size %u", GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur),
 
1364
      GST_BUFFER_SIZE (buf));
 
1365
 
 
1366
  /* can't clip without TIME segment */
 
1367
  if (G_UNLIKELY (dec->segment.format != GST_FORMAT_TIME))
 
1368
    goto beach;
 
1369
 
 
1370
  /* we need a start time */
 
1371
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (in_ts)))
 
1372
    goto beach;
 
1373
 
 
1374
  /* trust duration */
 
1375
  stop = in_ts + in_dur;
 
1376
 
 
1377
  res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME, in_ts, stop, &ctime,
 
1378
          &cstop);
 
1379
  if (G_UNLIKELY (!res))
 
1380
    goto out_of_segment;
 
1381
 
 
1382
  /* see if some clipping happened */
 
1383
  if (G_UNLIKELY ((diff = ctime - in_ts) > 0)) {
 
1384
    /* bring clipped time to bytes */
 
1385
    diff =
 
1386
        gst_util_uint64_scale_int (diff, dec->format.audio.samplerate,
 
1387
        GST_SECOND) * (2 * dec->format.audio.channels);
 
1388
 
 
1389
    GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %"
 
1390
        G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff);
 
1391
 
 
1392
    GST_BUFFER_SIZE (buf) -= diff;
 
1393
    GST_BUFFER_DATA (buf) += diff;
 
1394
  }
 
1395
  if (G_UNLIKELY ((diff = stop - cstop) > 0)) {
 
1396
    /* bring clipped time to bytes */
 
1397
    diff =
 
1398
        gst_util_uint64_scale_int (diff, dec->format.audio.samplerate,
 
1399
        GST_SECOND) * (2 * dec->format.audio.channels);
 
1400
 
 
1401
    GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %"
 
1402
        G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
 
1403
 
 
1404
    GST_BUFFER_SIZE (buf) -= diff;
 
1405
  }
 
1406
  GST_BUFFER_TIMESTAMP (buf) = ctime;
 
1407
  GST_BUFFER_DURATION (buf) = cstop - ctime;
 
1408
 
 
1409
beach:
 
1410
  GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : ""));
 
1411
  return res;
 
1412
 
 
1413
  /* ERRORS */
 
1414
out_of_segment:
 
1415
  {
 
1416
    GST_LOG_OBJECT (dec, "out of segment");
 
1417
    goto beach;
 
1418
  }
 
1419
}
 
1420
 
 
1421
static gint
 
1422
gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
 
1423
    guint8 * data, guint size,
 
1424
    GstClockTime in_timestamp, GstClockTime in_duration, 
 
1425
    GstBuffer ** outbuf, GstFlowReturn * ret)
 
1426
{
 
1427
  gint len = -1;
 
1428
  gint have_data;
 
1429
 
 
1430
  GST_DEBUG_OBJECT (ffmpegdec,
 
1431
      "size:%d, ts:%" GST_TIME_FORMAT ", dur:%"GST_TIME_FORMAT", ffmpegdec->next_ts:%"
 
1432
      GST_TIME_FORMAT, size, GST_TIME_ARGS (in_timestamp), GST_TIME_ARGS (in_duration),
 
1433
      GST_TIME_ARGS (ffmpegdec->next_ts));
 
1434
 
 
1435
  /* outgoing buffer */
 
1436
  if (!ffmpegdec->last_buffer)
 
1437
    *outbuf = gst_buffer_new_and_alloc (AVCODEC_MAX_AUDIO_FRAME_SIZE);
 
1438
  else {
 
1439
    *outbuf = ffmpegdec->last_buffer;
 
1440
    ffmpegdec->last_buffer = NULL;
 
1441
  }
 
1442
 
 
1443
  len = avcodec_decode_audio (ffmpegdec->context,
 
1444
      (int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size);
 
1445
  GST_DEBUG_OBJECT (ffmpegdec,
 
1446
      "Decode audio: len=%d, have_data=%d", len, have_data);
 
1447
 
 
1448
  if (len >= 0 && have_data > 0) {
 
1449
    GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
 
1450
    if (!gst_ffmpegdec_negotiate (ffmpegdec)) {
 
1451
      gst_buffer_unref (*outbuf);
 
1452
      *outbuf = NULL;
 
1453
      len = -1;
 
1454
      goto beach;
 
1455
    }
 
1456
 
 
1457
    /* Buffer size */
 
1458
    GST_BUFFER_SIZE (*outbuf) = have_data;
 
1459
 
 
1460
    /*
 
1461
     * Timestamps:
 
1462
     *
 
1463
     *  1) Copy input timestamp if valid
 
1464
     *  2) else interpolate from previous input timestamp
 
1465
     */
 
1466
    /* always take timestamps from the input buffer if any */
 
1467
    if (!GST_CLOCK_TIME_IS_VALID (in_timestamp)) {
 
1468
      in_timestamp = ffmpegdec->next_ts;
 
1469
    }
 
1470
 
 
1471
    /*
 
1472
     * Duration:
 
1473
     *
 
1474
     *  1) calculate based on number of samples
 
1475
     */
 
1476
    in_duration = gst_util_uint64_scale_int (have_data, GST_SECOND,
 
1477
        2 * ffmpegdec->context->channels * ffmpegdec->context->sample_rate);
 
1478
 
 
1479
    GST_DEBUG_OBJECT (ffmpegdec,
 
1480
        "Buffer created. Size:%d , timestamp:%" GST_TIME_FORMAT " , duration:%"
 
1481
        GST_TIME_FORMAT, have_data,
 
1482
        GST_TIME_ARGS (in_timestamp), GST_TIME_ARGS (in_duration));
 
1483
 
 
1484
    GST_BUFFER_TIMESTAMP (*outbuf) = in_timestamp;
 
1485
    GST_BUFFER_DURATION (*outbuf) = in_duration;
 
1486
 
 
1487
    /* the next timestamp we'll use when interpolating */
 
1488
    ffmpegdec->next_ts = in_timestamp + in_duration;
 
1489
 
 
1490
    /* now see if we need to clip the buffer against the segment boundaries. */
 
1491
    if (G_UNLIKELY (!clip_audio_buffer (ffmpegdec, *outbuf, in_timestamp, in_duration)))
 
1492
      goto clipped;
 
1493
 
 
1494
  } else if (len > 0 && have_data == 0) {
 
1495
    /* cache output, because it may be used for caching (in-place) */
 
1496
    ffmpegdec->last_buffer = *outbuf;
 
1497
    *outbuf = NULL;
 
1498
  } else {
 
1499
    gst_buffer_unref (*outbuf);
 
1500
    *outbuf = NULL;
 
1501
  }
 
1502
 
 
1503
beach:
 
1504
  GST_DEBUG_OBJECT (ffmpegdec, "return flow %d, out %p, len %d",
 
1505
      *ret, *outbuf, len);
 
1506
  return len;
 
1507
 
 
1508
  /* ERRORS */
 
1509
clipped:
 
1510
  {
 
1511
    GST_DEBUG_OBJECT (ffmpegdec, "buffer clipped");
 
1512
    gst_buffer_unref (*outbuf);
 
1513
    *outbuf = NULL;
 
1514
    goto beach;
 
1515
  }
 
1516
}
 
1517
 
 
1518
 
 
1519
/* gst_ffmpegdec_frame:
 
1520
 * ffmpegdec:
 
1521
 * data: pointer to the data to decode
 
1522
 * size: size of data in bytes
 
1523
 * got_data: 0 if no data was decoded, != 0 otherwise.
 
1524
 * in_time: timestamp of data
 
1525
 * in_duration: duration of data
 
1526
 * ret: GstFlowReturn to return in the chain function
 
1527
 *
 
1528
 * Decode the given frame and pushes it downstream.
 
1529
 *
 
1530
 * Returns: Number of bytes used in decoding, -1 on error/failure.
 
1531
 */
786
1532
 
787
1533
static gint
788
1534
gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
789
 
    guint8 * data, guint size, gint * got_data, guint64 * in_ts,
790
 
    GstBuffer * inbuf, GstFlowReturn * ret)
 
1535
    guint8 * data, guint size, gint * got_data,
 
1536
    GstClockTime in_timestamp, GstClockTime in_duration, 
 
1537
    GstFlowReturn * ret)
791
1538
{
792
 
  GstFFMpegDecClass *oclass =
793
 
      (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
1539
  GstFFMpegDecClass *oclass;
794
1540
  GstBuffer *outbuf = NULL;
795
1541
  gint have_data = 0, len = 0;
796
1542
 
797
 
  if (ffmpegdec->context->codec == NULL)
798
 
    return -1;
 
1543
  if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
 
1544
    goto no_codec;
799
1545
 
800
1546
  GST_LOG_OBJECT (ffmpegdec,
801
 
      "data:%p, size:%d, *in_ts:%" GST_TIME_FORMAT " inbuf:%p  inbuf.ts:%"
802
 
      GST_TIME_FORMAT, data, size, GST_TIME_ARGS (*in_ts), inbuf,
803
 
      GST_TIME_ARGS ((inbuf) ? GST_BUFFER_TIMESTAMP (inbuf) : 0));
 
1547
      "data:%p, size:%d, ts:%" GST_TIME_FORMAT", dur:%"GST_TIME_FORMAT, 
 
1548
      data, size, GST_TIME_ARGS (in_timestamp), GST_TIME_ARGS (in_duration));
804
1549
 
 
1550
  *ret = GST_FLOW_OK;
805
1551
  ffmpegdec->context->frame_number++;
806
1552
 
 
1553
  oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
1554
 
807
1555
  switch (oclass->in_plugin->type) {
808
 
  case CODEC_TYPE_VIDEO:
809
 
    {
810
 
      gboolean  iskeyframe = FALSE;
811
 
      gboolean  is_itype = FALSE;
812
 
      gboolean  is_reference = FALSE;
813
 
      
814
 
      ffmpegdec->picture->pict_type = -1;       /* in case we skip frames */
815
 
 
816
 
      ffmpegdec->context->opaque = ffmpegdec;
817
 
 
818
 
      len = avcodec_decode_video (ffmpegdec->context,
819
 
          ffmpegdec->picture, &have_data, data, size);
820
 
      is_itype = (ffmpegdec->picture->pict_type == FF_I_TYPE);
821
 
      is_reference = (ffmpegdec->picture->reference == 1);
822
 
      iskeyframe = (is_itype || is_reference || ffmpegdec->picture->key_frame)
823
 
        || (oclass->in_plugin->id == CODEC_ID_INDEO3)
824
 
        || (oclass->in_plugin->id == CODEC_ID_MSZH)
825
 
        || (oclass->in_plugin->id == CODEC_ID_ZLIB)
826
 
        || (oclass->in_plugin->id == CODEC_ID_VP3)
827
 
        || (oclass->in_plugin->id == CODEC_ID_HUFFYUV);
828
 
      GST_LOG_OBJECT (ffmpegdec,
829
 
          "Decoded video: len=%d, have_data=%d, "
830
 
          "is_keyframe:%d, is_itype:%d, is_reference:%d",
831
 
          len, have_data, iskeyframe, is_itype, is_reference);
832
 
 
833
 
      if (ffmpegdec->waiting_for_key) {
834
 
        if (iskeyframe) {
835
 
          ffmpegdec->waiting_for_key = FALSE;
836
 
        } else {
837
 
          GST_WARNING_OBJECT (ffmpegdec, "Dropping non-keyframe (seek/init)");
838
 
          have_data = 0;
839
 
          break;
840
 
        }
841
 
      }
842
 
 
843
 
      /* note that ffmpeg sometimes gets the FPS wrong.
844
 
       * For B-frame containing movies, we get all pictures delayed
845
 
       * except for the I frames, so we synchronize only on I frames
846
 
       * and keep an internal counter based on FPS for the others. */
847
 
      if (!(oclass->in_plugin->capabilities & CODEC_CAP_DELAY) ||
848
 
          ((iskeyframe || !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) &&
849
 
           GST_CLOCK_TIME_IS_VALID (*in_ts))) {
850
 
        GST_LOG_OBJECT (ffmpegdec, "setting next_ts to %" GST_TIME_FORMAT,
851
 
                          GST_TIME_ARGS (*in_ts));
852
 
        ffmpegdec->next_ts = *in_ts;
853
 
        *in_ts = GST_CLOCK_TIME_NONE;
854
 
      }
855
 
 
856
 
      /* precise seeking.... */
857
 
      if (GST_CLOCK_TIME_IS_VALID (ffmpegdec->synctime)) {
858
 
        if (ffmpegdec->next_ts >= ffmpegdec->synctime) {
859
 
          ffmpegdec->synctime = GST_CLOCK_TIME_NONE;
860
 
        } else {
861
 
          GST_WARNING_OBJECT (ffmpegdec,
862
 
              "Dropping frame for synctime %" GST_TIME_FORMAT
863
 
              ", expected(next_ts) %" GST_TIME_FORMAT,
864
 
              GST_TIME_ARGS (ffmpegdec->synctime),
865
 
              GST_TIME_ARGS (ffmpegdec->next_ts));
866
 
 
867
 
          if (ffmpegdec->picture->opaque != NULL) {
868
 
            outbuf = (GstBuffer *) ffmpegdec->picture->opaque;
869
 
            gst_buffer_unref (outbuf);
870
 
          }
871
 
 
872
 
          have_data = 0;
873
 
          /* don´t break here! Timestamps are updated below */
874
 
        }
875
 
      }
876
 
 
877
 
      if (ffmpegdec->waiting_for_key && !iskeyframe) {
878
 
        have_data = 0;
879
 
      } else if (len >= 0 && have_data > 0) {
880
 
        /* libavcodec constantly crashes on stupid buffer allocation
881
 
         * errors inside. This drives me crazy, so we let it allocate
882
 
         * its own buffers and copy to our own buffer afterwards... */
883
 
 
884
 
        if (ffmpegdec->picture->opaque != NULL) {
885
 
          outbuf = (GstBuffer *) ffmpegdec->picture->opaque;
886
 
          if (outbuf == ffmpegdec->last_buffer)
887
 
            ffmpegdec->last_buffer = NULL;
888
 
        } else {
889
 
          AVPicture pic;
890
 
          gint fsize =
891
 
              gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
892
 
              ffmpegdec->context->width, ffmpegdec->context->height);
893
 
 
894
 
          if (!gst_ffmpegdec_negotiate (ffmpegdec))
895
 
            return -1;
896
 
 
897
 
          if (!ffmpegdec->context->palctrl) {
898
 
            if ((*ret =
899
 
                    gst_pad_alloc_buffer_and_set_caps (ffmpegdec->srcpad,
900
 
                        GST_BUFFER_OFFSET_NONE, fsize,
901
 
                        GST_PAD_CAPS (ffmpegdec->srcpad),
902
 
                        &outbuf)) != GST_FLOW_OK)
903
 
              return -1;
904
 
          } else {
905
 
            /* for paletted data we can't use pad_alloc_buffer(), because
906
 
             * fsize contains the size of the palette, so the overall size
907
 
             * is bigger than ffmpegcolorspace's unit size, which will
908
 
             * prompt GstBaseTransform to complain endlessly ... */
909
 
            outbuf = gst_buffer_new_and_alloc (fsize);
910
 
            gst_buffer_set_caps (outbuf, GST_PAD_CAPS (ffmpegdec->srcpad));
911
 
          }
912
 
 
913
 
          /* original ffmpeg code does not handle odd sizes correctly.
914
 
           * This patched up version does */
915
 
          gst_ffmpeg_avpicture_fill (&pic, GST_BUFFER_DATA (outbuf),
916
 
              ffmpegdec->context->pix_fmt,
917
 
              ffmpegdec->context->width, ffmpegdec->context->height);
918
 
 
919
 
          /* the original convert function did not do the right thing, this
920
 
           * is a patched up version that adjust widht/height so that the
921
 
           * ffmpeg one works correctly. */
922
 
          gst_ffmpeg_img_convert (&pic, ffmpegdec->context->pix_fmt,
923
 
              (AVPicture *) ffmpegdec->picture,
924
 
              ffmpegdec->context->pix_fmt,
925
 
              ffmpegdec->context->width, ffmpegdec->context->height);
926
 
        }
927
 
 
928
 
        ffmpegdec->waiting_for_key = FALSE;
929
 
 
930
 
        if (!iskeyframe) {
931
 
          GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
932
 
        }
933
 
 
934
 
        /* If we have used the framerate from the demuxer then
935
 
         * also use the demuxer's timestamp information (#317596) */
936
 
        if (ffmpegdec->format.video.fps_n != -1 && inbuf != NULL) {
937
 
          GST_LOG_OBJECT (ffmpegdec, "using incoming buffer's timestamps");
938
 
          GST_LOG_OBJECT (ffmpegdec, "incoming timestamp %" GST_TIME_FORMAT,
939
 
            GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)));
940
 
          gst_buffer_stamp (outbuf, inbuf);
941
 
        } else {
942
 
          GST_LOG_OBJECT (ffmpegdec, "using decoder's timestamps");
943
 
          GST_BUFFER_TIMESTAMP (outbuf) = ffmpegdec->next_ts;
944
 
          if (ffmpegdec->context->time_base.num != 0 &&
945
 
              ffmpegdec->context->time_base.den != 0) {
946
 
            GST_BUFFER_DURATION (outbuf) =
947
 
                gst_util_uint64_scale_int (GST_SECOND,
948
 
                ffmpegdec->context->time_base.num,
949
 
                ffmpegdec->context->time_base.den);
950
 
 
951
 
            /* Take repeat_pict into account */
952
 
            GST_BUFFER_DURATION (outbuf) += GST_BUFFER_DURATION (outbuf)
953
 
                * ffmpegdec->picture->repeat_pict / 2;
954
 
            GST_DEBUG_OBJECT (ffmpegdec,
955
 
                "advancing next_ts by duration of %" GST_TIME_FORMAT,
956
 
                GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
957
 
            ffmpegdec->next_ts += GST_BUFFER_DURATION (outbuf);
958
 
          } else {
959
 
            GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to NONE");
960
 
            ffmpegdec->next_ts = GST_CLOCK_TIME_NONE;
961
 
          }
962
 
        }
963
 
        GST_LOG_OBJECT (ffmpegdec, "outgoing timestamp %" GST_TIME_FORMAT,
964
 
            GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
965
 
      } else if (ffmpegdec->picture->pict_type != -1 &&
966
 
          oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
967
 
        /* update time for skip-frame */
968
 
        if ((!have_data) || 
969
 
            (iskeyframe || !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts))
970
 
            && GST_CLOCK_TIME_IS_VALID (*in_ts)) {
971
 
          GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to *in_ts");
972
 
          ffmpegdec->next_ts = *in_ts;
973
 
          *in_ts = GST_CLOCK_TIME_NONE;
974
 
        }
975
 
 
976
 
        if (ffmpegdec->context->time_base.num != 0 &&
977
 
            ffmpegdec->context->time_base.den != 0) {
978
 
          guint64 dur = GST_SECOND *
979
 
              ffmpegdec->context->time_base.num /
980
 
              ffmpegdec->context->time_base.den;
981
 
 
982
 
          /* Take repeat_pict into account */
983
 
          dur += dur * ffmpegdec->picture->repeat_pict / 2;
984
 
          GST_DEBUG_OBJECT (ffmpegdec,
985
 
              "Advancing next_ts by dur:%" GST_TIME_FORMAT,
986
 
              GST_TIME_ARGS (dur));
987
 
          ffmpegdec->next_ts += dur;
988
 
        } else {
989
 
          GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to NONE");
990
 
          ffmpegdec->next_ts = GST_CLOCK_TIME_NONE;
991
 
        }
992
 
      }
993
 
      /* palette is not part of raw video frame in gst and the size
994
 
       * of the outgoing buffer needs to be adjusted accordingly */
995
 
      if (ffmpegdec->context->palctrl != NULL && outbuf != NULL)
996
 
        GST_BUFFER_SIZE (outbuf) -= AVPALETTE_SIZE;
 
1556
    case CODEC_TYPE_VIDEO:
 
1557
      len =
 
1558
          gst_ffmpegdec_video_frame (ffmpegdec, data, size, in_timestamp, in_duration, &outbuf,
 
1559
          ret);
997
1560
      break;
998
 
    }
999
1561
    case CODEC_TYPE_AUDIO:
1000
 
      if (!ffmpegdec->last_buffer)
1001
 
        outbuf = gst_buffer_new_and_alloc (AVCODEC_MAX_AUDIO_FRAME_SIZE);
1002
 
      else {
1003
 
        outbuf = ffmpegdec->last_buffer;
1004
 
        ffmpegdec->last_buffer = NULL;
1005
 
      }
1006
 
      len = avcodec_decode_audio (ffmpegdec->context,
1007
 
          (int16_t *) GST_BUFFER_DATA (outbuf), &have_data, data, size);
1008
 
      GST_DEBUG_OBJECT (ffmpegdec,
1009
 
          "Decode audio: len=%d, have_data=%d", len, have_data);
1010
 
 
1011
 
      if (len >= 0 && have_data > 0) {
1012
 
        if (!gst_ffmpegdec_negotiate (ffmpegdec)) {
1013
 
          gst_buffer_unref (outbuf);
1014
 
          return -1;
1015
 
        }
1016
 
 
1017
 
        GST_BUFFER_SIZE (outbuf) = have_data;
1018
 
        if (GST_CLOCK_TIME_IS_VALID (*in_ts)) {
1019
 
          ffmpegdec->next_ts = *in_ts;
1020
 
        }
1021
 
        GST_BUFFER_TIMESTAMP (outbuf) = ffmpegdec->next_ts;
1022
 
        GST_BUFFER_DURATION (outbuf) = (have_data * GST_SECOND) /
1023
 
            (2 * ffmpegdec->context->channels *
1024
 
            ffmpegdec->context->sample_rate);
1025
 
        ffmpegdec->next_ts += GST_BUFFER_DURATION (outbuf);
1026
 
        if (GST_CLOCK_TIME_IS_VALID (*in_ts))
1027
 
          *in_ts += GST_BUFFER_DURATION (outbuf);
1028
 
      } else if (len > 0 && have_data == 0) {
1029
 
        /* cache output, because it may be used for caching (in-place) */
1030
 
        ffmpegdec->last_buffer = outbuf;
1031
 
      } else {
1032
 
        gst_buffer_unref (outbuf);
1033
 
      }
 
1562
      len =
 
1563
          gst_ffmpegdec_audio_frame (ffmpegdec, data, size, in_timestamp, in_duration, &outbuf,
 
1564
          ret);
1034
1565
      break;
1035
1566
    default:
1036
 
      g_assert (0);
 
1567
      g_assert_not_reached ();
1037
1568
      break;
1038
1569
  }
1039
1570
 
 
1571
  if (outbuf)
 
1572
    have_data = 1;
 
1573
 
1040
1574
  if (len < 0 || have_data < 0) {
1041
 
    GST_ERROR_OBJECT (ffmpegdec,
 
1575
    GST_WARNING_OBJECT (ffmpegdec,
1042
1576
        "ffdec_%s: decoding error (len: %d, have_data: %d)",
1043
1577
        oclass->in_plugin->name, len, have_data);
1044
1578
    *got_data = 0;
1045
 
    return len;
 
1579
    goto beach;
1046
1580
  } else if (len == 0 && have_data == 0) {
1047
1581
    *got_data = 0;
1048
 
    return 0;
 
1582
    goto beach;
1049
1583
  } else {
1050
1584
    /* this is where I lost my last clue on ffmpeg... */
1051
 
    *got_data = 1;              //(ffmpegdec->pctx || have_data) ? 1 : 0;
 
1585
    *got_data = 1; 
1052
1586
  }
1053
1587
 
1054
 
  if (have_data) {
1055
 
    GST_LOG_OBJECT (ffmpegdec, "Decoded data, now pushing with timestamp %"
1056
 
        GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
 
1588
  if (outbuf) {
 
1589
    GST_LOG_OBJECT (ffmpegdec,
 
1590
        "Decoded data, now pushing buffer with timestamp %" GST_TIME_FORMAT
 
1591
        " and duration %" GST_TIME_FORMAT,
 
1592
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
 
1593
        GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1057
1594
 
 
1595
    /* mark pending discont */
 
1596
    if (ffmpegdec->discont) {
 
1597
      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
 
1598
      ffmpegdec->discont = FALSE;
 
1599
    }
 
1600
    /* set caps */
1058
1601
    gst_buffer_set_caps (outbuf, GST_PAD_CAPS (ffmpegdec->srcpad));
 
1602
    /* and off we go */
1059
1603
    *ret = gst_pad_push (ffmpegdec->srcpad, outbuf);
 
1604
  } else {
 
1605
    GST_DEBUG_OBJECT (ffmpegdec, "We didn't get a decoded buffer");
1060
1606
  }
1061
1607
 
 
1608
beach:
1062
1609
  return len;
 
1610
 
 
1611
  /* ERRORS */
 
1612
no_codec:
 
1613
  {
 
1614
    GST_ERROR_OBJECT (ffmpegdec, "no codec context");
 
1615
    return -1;
 
1616
  }
 
1617
}
 
1618
 
 
1619
static void
 
1620
gst_ffmpegdec_flush_pcache (GstFFMpegDec * ffmpegdec)
 
1621
{
 
1622
  if (ffmpegdec->pcache) {
 
1623
    gst_buffer_unref (ffmpegdec->pcache);
 
1624
    ffmpegdec->pcache = NULL;
 
1625
  }
 
1626
  if (ffmpegdec->pctx) {
 
1627
    GstFFMpegDecClass *oclass;
 
1628
 
 
1629
    oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
1630
 
 
1631
    av_parser_close (ffmpegdec->pctx);
 
1632
    ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
 
1633
  }
1063
1634
}
1064
1635
 
1065
1636
static gboolean
1066
1637
gst_ffmpegdec_sink_event (GstPad * pad, GstEvent * event)
1067
1638
{
1068
 
  GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) GST_OBJECT_PARENT (pad);
1069
 
  GstFFMpegDecClass *oclass =
1070
 
      (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1071
 
  gboolean ret;
 
1639
  GstFFMpegDec *ffmpegdec;
 
1640
  GstFFMpegDecClass *oclass;
 
1641
  gboolean ret = FALSE;
 
1642
 
 
1643
  ffmpegdec = (GstFFMpegDec *) gst_pad_get_parent (pad);
 
1644
  oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1072
1645
 
1073
1646
  GST_DEBUG_OBJECT (ffmpegdec, "Handling %s event",
1074
1647
      GST_EVENT_TYPE_NAME (event));
1078
1651
      if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
1079
1652
        gint have_data, len, try = 0;
1080
1653
 
 
1654
        GST_LOG_OBJECT (ffmpegdec,
 
1655
            "codec has delay capabilities, calling until ffmpeg has drained everything");
 
1656
 
1081
1657
        do {
1082
1658
          GstFlowReturn ret;
1083
1659
 
1084
1660
          len = gst_ffmpegdec_frame (ffmpegdec, NULL, 0, &have_data,
1085
 
              &ffmpegdec->next_ts, NULL, &ret);
 
1661
              GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, &ret);
1086
1662
          if (len < 0 || have_data == 0)
1087
1663
            break;
1088
1664
        } while (try++ < 10);
1093
1669
      if (ffmpegdec->opened) {
1094
1670
        avcodec_flush_buffers (ffmpegdec->context);
1095
1671
      }
 
1672
      ffmpegdec->next_ts = GST_CLOCK_TIME_NONE;
 
1673
      gst_ffmpegdec_reset_qos (ffmpegdec);
 
1674
      gst_ffmpegdec_flush_pcache (ffmpegdec);
 
1675
      ffmpegdec->waiting_for_key = TRUE;
 
1676
      gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
1096
1677
      break;
1097
1678
    }
1098
1679
    case GST_EVENT_NEWSEGMENT:{
1099
 
      gint64 base, start, end;
1100
 
      gdouble rate;
 
1680
      gboolean update;
1101
1681
      GstFormat fmt;
1102
 
 
1103
 
      gst_event_parse_new_segment (event, NULL, &rate, &fmt, &start, &end,
1104
 
          &base);
1105
 
      if (fmt == GST_FORMAT_TIME) {
1106
 
        ffmpegdec->next_ts = start;
1107
 
        GST_DEBUG_OBJECT (ffmpegdec,
1108
 
            "Discont to time (next_ts) %" GST_TIME_FORMAT " -- %"
1109
 
            GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
1110
 
      } else if (ffmpegdec->context->bit_rate && fmt == GST_FORMAT_BYTES) {
1111
 
        ffmpegdec->next_ts = start * GST_SECOND / ffmpegdec->context->bit_rate;
1112
 
        GST_DEBUG_OBJECT (ffmpegdec,
1113
 
            "Newsegment in bytes from byte %" G_GINT64_FORMAT
1114
 
            " (time %" GST_TIME_FORMAT ") to byte % " G_GINT64_FORMAT
1115
 
            " (time %" GST_TIME_FORMAT ")",
1116
 
            start, GST_TIME_ARGS (ffmpegdec->next_ts),
1117
 
            end,
1118
 
            GST_TIME_ARGS (end * GST_SECOND / ffmpegdec->context->bit_rate));
1119
 
        gst_event_unref (event);
1120
 
        event = gst_event_new_new_segment (FALSE, rate, fmt,
1121
 
            start * GST_SECOND / ffmpegdec->context->bit_rate,
1122
 
            end == -1 ? -1 : end * GST_SECOND / ffmpegdec->context->bit_rate,
1123
 
            base * GST_SECOND / ffmpegdec->context->bit_rate);
1124
 
      } else {
1125
 
        GST_WARNING_OBJECT (ffmpegdec,
1126
 
            "Received discont with no useful value...");
1127
 
      }
1128
 
      if (ffmpegdec->opened) {
1129
 
        avcodec_flush_buffers (ffmpegdec->context);
1130
 
 
1131
 
        if (ffmpegdec->context->codec_id == CODEC_ID_MPEG2VIDEO ||
1132
 
            ffmpegdec->context->codec_id == CODEC_ID_MPEG4 ||
1133
 
            ffmpegdec->context->codec_id == CODEC_ID_H264) {
1134
 
          ffmpegdec->waiting_for_key = TRUE;
 
1682
      gint64 start, stop, time;
 
1683
      gdouble rate, arate;
 
1684
 
 
1685
      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
 
1686
          &start, &stop, &time);
 
1687
 
 
1688
      /* no negative rates for now */
 
1689
      if (rate <= 0.0)
 
1690
        goto newseg_wrong_rate;
 
1691
 
 
1692
      switch (fmt) {
 
1693
        case GST_FORMAT_TIME:
 
1694
          /* fine, our native segment format */
 
1695
          break;
 
1696
        case GST_FORMAT_BYTES:
 
1697
        {
 
1698
          gint bit_rate;
 
1699
 
 
1700
          bit_rate = ffmpegdec->context->bit_rate;
 
1701
 
 
1702
          /* convert to time or fail */
 
1703
          if (!bit_rate)
 
1704
            goto no_bitrate;
 
1705
 
 
1706
          GST_DEBUG_OBJECT (ffmpegdec, "bitrate: %d", bit_rate);
 
1707
 
 
1708
          /* convert values to TIME */
 
1709
          if (start != -1)
 
1710
            start = gst_util_uint64_scale_int (start, GST_SECOND, bit_rate);
 
1711
          if (stop != -1)
 
1712
            stop = gst_util_uint64_scale_int (stop, GST_SECOND, bit_rate);
 
1713
          if (time != -1)
 
1714
            time = gst_util_uint64_scale_int (time, GST_SECOND, bit_rate);
 
1715
 
 
1716
          /* unref old event */
 
1717
          gst_event_unref (event);
 
1718
 
 
1719
          /* create new converted time segment */
 
1720
          fmt = GST_FORMAT_TIME;
 
1721
          /* FIXME, bitrate is not good enough too find a good stop, let's
 
1722
           * hope start and time were 0... meh. */
 
1723
          stop = -1;
 
1724
          event = gst_event_new_new_segment (update, rate, fmt,
 
1725
              start, stop, time);
 
1726
          break;
1135
1727
        }
 
1728
        default:
 
1729
          /* invalid format */
 
1730
          goto invalid_format;
1136
1731
      }
1137
 
      ffmpegdec->waiting_for_key = TRUE;
1138
 
      ffmpegdec->synctime = ffmpegdec->next_ts;
 
1732
 
 
1733
      GST_DEBUG_OBJECT (ffmpegdec,
 
1734
          "NEWSEGMENT in time start %" GST_TIME_FORMAT " -- stop %"
 
1735
          GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
 
1736
 
 
1737
      /* and store the values */
 
1738
      gst_segment_set_newsegment_full (&ffmpegdec->segment, update,
 
1739
          rate, arate, fmt, start, stop, time);
1139
1740
      break;
1140
1741
    }
1141
1742
    default:
1142
1743
      break;
1143
1744
  }
1144
1745
 
1145
 
  ret = gst_pad_event_default (ffmpegdec->sinkpad, event);
 
1746
  /* and push segment downstream */
 
1747
  ret = gst_pad_push_event (ffmpegdec->srcpad, event);
 
1748
 
 
1749
done:
 
1750
  gst_object_unref (ffmpegdec);
1146
1751
 
1147
1752
  return ret;
 
1753
 
 
1754
  /* ERRORS */
 
1755
newseg_wrong_rate:
 
1756
  {
 
1757
    GST_WARNING_OBJECT (ffmpegdec, "negative rates not supported yet");
 
1758
    gst_event_unref (event);
 
1759
    goto done;
 
1760
  }
 
1761
no_bitrate:
 
1762
  {
 
1763
    GST_WARNING_OBJECT (ffmpegdec, "no bitrate to convert BYTES to TIME");
 
1764
    gst_event_unref (event);
 
1765
    goto done;
 
1766
  }
 
1767
invalid_format:
 
1768
  {
 
1769
    GST_WARNING_OBJECT (ffmpegdec, "unknown format received in NEWSEGMENT");
 
1770
    gst_event_unref (event);
 
1771
    goto done;
 
1772
  }
1148
1773
}
1149
1774
 
1150
1775
static GstFlowReturn
1151
1776
gst_ffmpegdec_chain (GstPad * pad, GstBuffer * inbuf)
1152
1777
{
1153
 
  GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) (GST_PAD_PARENT (pad));
1154
 
  GstFFMpegDecClass *oclass =
1155
 
      (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1156
 
  guint8 *bdata, *data;
1157
 
  gint bsize, size, len, have_data;
1158
 
  guint64 in_ts = GST_BUFFER_TIMESTAMP (inbuf);
 
1778
  GstFFMpegDec *ffmpegdec;
 
1779
  GstFFMpegDecClass *oclass;
 
1780
  guint8 *data, *bdata;
 
1781
  gint size, bsize, len, have_data;
1159
1782
  GstFlowReturn ret = GST_FLOW_OK;
1160
 
 
1161
 
  if (!ffmpegdec->opened)
 
1783
  guint left;
 
1784
  GstClockTime in_timestamp, in_duration;
 
1785
  GstClockTime next_timestamp, next_duration;
 
1786
  GstClockTime pending_timestamp, pending_duration;
 
1787
 
 
1788
  ffmpegdec = (GstFFMpegDec *) (GST_PAD_PARENT (pad));
 
1789
 
 
1790
  if (G_UNLIKELY (!ffmpegdec->opened))
1162
1791
    goto not_negotiated;
1163
1792
 
 
1793
  /* The discont flags marks a buffer that is not continuous with the previous
 
1794
   * buffer. This means we need to clear whatever data we currently have. We
 
1795
   * currently also wait for a new keyframe, which might be suboptimal in the
 
1796
   * case of a network error, better show the errors than to drop all data.. */
 
1797
  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DISCONT))) {
 
1798
    GST_DEBUG_OBJECT (ffmpegdec, "received DISCONT");
 
1799
    gst_ffmpegdec_flush_pcache (ffmpegdec);
 
1800
    avcodec_flush_buffers (ffmpegdec->context);
 
1801
    ffmpegdec->waiting_for_key = TRUE;
 
1802
    ffmpegdec->discont = TRUE;
 
1803
    ffmpegdec->next_ts = GST_CLOCK_TIME_NONE;
 
1804
  }
 
1805
 
 
1806
  oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
 
1807
 
 
1808
  /* do early keyframe check pretty bad to rely on the keyframe flag in the
 
1809
   * source for this as it might not even be parsed (UDP/file/..).  */
 
1810
  if (G_UNLIKELY (ffmpegdec->waiting_for_key)) {
 
1811
    if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DELTA_UNIT) &&
 
1812
        oclass->in_plugin->type != CODEC_TYPE_AUDIO)
 
1813
      goto skip_keyframe;
 
1814
 
 
1815
    GST_DEBUG_OBJECT (ffmpegdec, "got keyframe");
 
1816
    ffmpegdec->waiting_for_key = FALSE;
 
1817
  }
 
1818
 
 
1819
  pending_timestamp = GST_BUFFER_TIMESTAMP (inbuf);
 
1820
  pending_duration  = GST_BUFFER_DURATION (inbuf);
 
1821
 
1164
1822
  GST_LOG_OBJECT (ffmpegdec,
1165
 
      "Received new data of size %d, time %" GST_TIME_FORMAT " next_ts %"
1166
 
      GST_TIME_FORMAT, GST_BUFFER_SIZE (inbuf),
1167
 
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
1168
 
      GST_TIME_ARGS (ffmpegdec->next_ts));
 
1823
      "Received new data of size %d, ts:%" GST_TIME_FORMAT ", dur:%"GST_TIME_FORMAT, 
 
1824
      GST_BUFFER_SIZE (inbuf), GST_TIME_ARGS (pending_timestamp), GST_TIME_ARGS (pending_duration)); 
1169
1825
 
1170
 
  /* parse cache joining */
 
1826
  /* parse cache joining. If there is cached data, its timestamp will be what we
 
1827
   * send to the parse. */
1171
1828
  if (ffmpegdec->pcache) {
1172
 
    GstClockTime timestamp = GST_CLOCK_TIME_NONE;
1173
 
    GstClockTime duration = GST_CLOCK_TIME_NONE;
1174
 
 
1175
 
 
1176
 
    /* decide on resulting timestamp/duration before we give away our ref */
1177
 
    /* since the cache is all data that did not result in an outgoing frame,
1178
 
     * we should timestamp with the new incoming buffer.  This is probably
1179
 
     * not entirely correct though, but better than nothing. */
1180
 
    if (GST_BUFFER_TIMESTAMP_IS_VALID (inbuf))
1181
 
      timestamp = GST_BUFFER_TIMESTAMP (inbuf);
1182
 
 
1183
 
    if (GST_BUFFER_DURATION_IS_VALID (ffmpegdec->pcache)
1184
 
        && GST_BUFFER_DURATION_IS_VALID (inbuf))
1185
 
      duration = GST_BUFFER_DURATION (ffmpegdec->pcache) +
1186
 
          GST_BUFFER_DURATION (inbuf);
1187
 
 
 
1829
    /* keep track of how many bytes to consume before we can use the incomming
 
1830
     * timestamp, which we have stored in pending_timestamp. */
 
1831
    left = GST_BUFFER_SIZE (ffmpegdec->pcache);
 
1832
 
 
1833
    /* use timestamp and duration of what is in the cache */
 
1834
    in_timestamp = GST_BUFFER_TIMESTAMP (ffmpegdec->pcache);
 
1835
    in_duration  = GST_BUFFER_DURATION (ffmpegdec->pcache);
 
1836
 
 
1837
    /* join with previous data */
1188
1838
    inbuf = gst_buffer_join (ffmpegdec->pcache, inbuf);
1189
 
/*     inbuf = gst_buffer_span (ffmpegdec->pcache, 0, inbuf, */
1190
 
/*         GST_BUFFER_SIZE (ffmpegdec->pcache) + GST_BUFFER_SIZE (inbuf)); */
1191
 
 
1192
 
    /* update time info as appropriate */
1193
 
    GST_BUFFER_TIMESTAMP (inbuf) = timestamp;
1194
 
    GST_BUFFER_DURATION (inbuf) = duration;
1195
 
    GST_LOG_OBJECT (ffmpegdec, "joined parse cache, inbuf now has ts %" GST_TIME_FORMAT
1196
 
        " and duration %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp),
1197
 
        GST_TIME_ARGS (duration));
 
1839
 
 
1840
    GST_LOG_OBJECT (ffmpegdec,
 
1841
        "joined parse cache, inbuf now has ts:%" GST_TIME_FORMAT,
 
1842
        GST_TIME_ARGS (in_timestamp));
 
1843
 
 
1844
    /* no more cached data, we assume we can consume the complete cache */
1198
1845
    ffmpegdec->pcache = NULL;
1199
 
    bdata = GST_BUFFER_DATA (inbuf);
1200
 
    bsize = GST_BUFFER_SIZE (inbuf);
1201
 
  }
 
1846
  }
 
1847
  else {
 
1848
    /* no cache, input timestamp matches the buffer we try to decode */
 
1849
    left = 0;
 
1850
    in_timestamp = pending_timestamp;
 
1851
    in_duration  = pending_duration;
 
1852
  }
 
1853
 
1202
1854
  /* workarounds, functions write to buffers:
1203
1855
   *  libavcodec/svq1.c:svq1_decode_frame writes to the given buffer.
1204
1856
   *  libavcodec/svq3.c:svq3_decode_slice_header too.
1205
1857
   * ffmpeg devs know about it and will fix it (they said). */
1206
 
  else if (oclass->in_plugin->id == CODEC_ID_SVQ1 ||
 
1858
  if (oclass->in_plugin->id == CODEC_ID_SVQ1 ||
1207
1859
      oclass->in_plugin->id == CODEC_ID_SVQ3) {
1208
1860
    inbuf = gst_buffer_make_writable (inbuf);
1209
 
    bdata = GST_BUFFER_DATA (inbuf);
1210
 
    bsize = GST_BUFFER_SIZE (inbuf);
1211
 
  } else {
1212
 
    bdata = GST_BUFFER_DATA (inbuf);
1213
 
    bsize = GST_BUFFER_SIZE (inbuf);
1214
1861
  }
1215
1862
 
 
1863
  bdata = GST_BUFFER_DATA (inbuf);
 
1864
  bsize = GST_BUFFER_SIZE (inbuf);
 
1865
 
1216
1866
  do {
1217
1867
    /* parse, if at all possible */
1218
1868
    if (ffmpegdec->pctx) {
1219
1869
      gint res;
1220
1870
      gint64 ffpts;
1221
1871
 
1222
 
      ffpts = gst_ffmpeg_time_gst_to_ff (in_ts, ffmpegdec->context->time_base);
 
1872
      /* convert timestamp to ffmpeg timestamp */
 
1873
      ffpts = gst_ffmpeg_time_gst_to_ff (in_timestamp, ffmpegdec->context->time_base);
 
1874
 
 
1875
      GST_LOG_OBJECT (ffmpegdec,
 
1876
          "Calling av_parser_parse with ts:%" GST_TIME_FORMAT", ffpts:%"G_GINT64_FORMAT,
 
1877
          GST_TIME_ARGS (in_timestamp), ffpts);
 
1878
 
 
1879
      /* feed the parser */
1223
1880
      res = av_parser_parse (ffmpegdec->pctx, ffmpegdec->context,
1224
1881
          &data, &size, bdata, bsize, ffpts, ffpts);
1225
1882
 
1226
 
      GST_LOG_OBJECT (ffmpegdec, "Parsed video frame, res=%d, size=%d",
1227
 
          res, size);
1228
 
 
1229
 
      in_ts = gst_ffmpeg_time_ff_to_gst (ffmpegdec->pctx->pts,
1230
 
          ffmpegdec->context->time_base);
1231
 
      if (res == 0 || size == 0)
1232
 
        break;
 
1883
      GST_LOG_OBJECT (ffmpegdec,
 
1884
            "parser returned res %d and size %d", res, size);
 
1885
 
 
1886
      GST_LOG_OBJECT (ffmpegdec, "consuming %d bytes. Next ts at %d, ffpts:%"
 
1887
          G_GINT64_FORMAT, size, left, ffmpegdec->pctx->pts);
 
1888
 
 
1889
      /* there is output, set pointers for next round. */
 
1890
      bsize -= res;
 
1891
      bdata += res;
 
1892
 
 
1893
      /* if there is no output, we must break and wait for more data. also the
 
1894
       * timestamp in the context is not updated. */
 
1895
      if (size == 0) {
 
1896
        if(bsize>0)
 
1897
           continue;
 
1898
        else
 
1899
           break;
 
1900
      }
 
1901
 
 
1902
      if (left <= size) {
 
1903
        left = 0;
 
1904
        /* activate the pending timestamp/duration and mark it invalid */
 
1905
        next_timestamp = pending_timestamp;
 
1906
        next_duration = pending_duration;
 
1907
 
 
1908
        pending_timestamp = GST_CLOCK_TIME_NONE;
 
1909
        pending_duration = GST_CLOCK_TIME_NONE;
 
1910
 
 
1911
        GST_LOG_OBJECT (ffmpegdec, "activated ts:%" GST_TIME_FORMAT", dur:%"GST_TIME_FORMAT,
 
1912
                        GST_TIME_ARGS (next_timestamp), GST_TIME_ARGS (next_duration));
 
1913
      }
1233
1914
      else {
1234
 
        bsize -= res;
1235
 
        bdata += res;
 
1915
        left -= size;
 
1916
        /* get new timestamp from the parser, this could be interpolated by the
 
1917
         * parser. We lost track of duration here. */
 
1918
        next_timestamp = gst_ffmpeg_time_ff_to_gst (ffmpegdec->pctx->pts,
 
1919
            ffmpegdec->context->time_base);
 
1920
        next_duration = GST_CLOCK_TIME_NONE;
 
1921
        GST_LOG_OBJECT (ffmpegdec, "parse context next ts:%" GST_TIME_FORMAT", ffpts:%"G_GINT64_FORMAT,
 
1922
                        GST_TIME_ARGS (next_timestamp), ffpts);
1236
1923
      }
1237
 
    } else {
 
1924
    }
 
1925
    else {
1238
1926
      data = bdata;
1239
1927
      size = bsize;
 
1928
      /* after decoding this input buffer, we don't know the timestamp anymore
 
1929
       * of any other decodable frame in this buffer, we let the interpolation
 
1930
       * code work. */
 
1931
      next_timestamp = GST_CLOCK_TIME_NONE;
 
1932
      next_duration = GST_CLOCK_TIME_NONE;
1240
1933
    }
1241
1934
 
1242
 
    if ((len = gst_ffmpegdec_frame (ffmpegdec, data, size,
1243
 
                &have_data, &in_ts, inbuf, &ret)) < 0 || ret != GST_FLOW_OK)
 
1935
    /* decode a frame of audio/video now */
 
1936
    len = gst_ffmpegdec_frame (ffmpegdec, data, size, &have_data, in_timestamp, in_duration, &ret);
 
1937
    if (len < 0 || ret != GST_FLOW_OK)
1244
1938
      break;
1245
1939
 
 
1940
    /* we decoded something, prepare to use next_timestamp in the next round */
 
1941
    in_timestamp = next_timestamp;
 
1942
    in_duration = next_duration;
 
1943
 
1246
1944
    if (!ffmpegdec->pctx) {
1247
1945
      bsize -= len;
1248
1946
      bdata += len;
1249
1947
    }
1250
 
 
1251
1948
    if (!have_data) {
 
1949
      GST_LOG_OBJECT (ffmpegdec, "Decoding didn't return any data, breaking");
1252
1950
      break;
1253
1951
    }
 
1952
 
 
1953
    GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0).  bsize:%d , bdata:%p",
 
1954
        bsize, bdata);
1254
1955
  } while (bsize > 0);
1255
1956
 
 
1957
  /* keep left-over */
1256
1958
  if ((ffmpegdec->pctx || oclass->in_plugin->id == CODEC_ID_MP3) && bsize > 0) {
1257
 
    GST_LOG_OBJECT (ffmpegdec, "Keeping %d bytes of data", bsize);
 
1959
    GST_LOG_OBJECT (ffmpegdec,
 
1960
        "Keeping %d bytes of data with timestamp %" GST_TIME_FORMAT, bsize,
 
1961
        GST_TIME_ARGS (in_timestamp));
1258
1962
 
1259
1963
    ffmpegdec->pcache = gst_buffer_create_sub (inbuf,
1260
1964
        GST_BUFFER_SIZE (inbuf) - bsize, bsize);
1261
1965
    /* we keep timestamp, even though all we really know is that the correct
1262
1966
     * timestamp is not below the one from inbuf */
1263
 
    GST_BUFFER_TIMESTAMP (ffmpegdec->pcache) = GST_BUFFER_TIMESTAMP (inbuf);
 
1967
    GST_BUFFER_TIMESTAMP (ffmpegdec->pcache) = in_timestamp;
1264
1968
  } else if (bsize > 0) {
1265
1969
    GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize);
1266
1970
  }
1271
1975
  /* ERRORS */
1272
1976
not_negotiated:
1273
1977
  {
 
1978
    oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1274
1979
    GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
1275
1980
        ("ffdec_%s: input format was not set before data start",
1276
1981
            oclass->in_plugin->name));
 
1982
    gst_buffer_unref (inbuf);
1277
1983
    return GST_FLOW_NOT_NEGOTIATED;
1278
1984
  }
 
1985
skip_keyframe:
 
1986
  {
 
1987
    GST_DEBUG_OBJECT (ffmpegdec, "skipping non keyframe");
 
1988
    gst_buffer_unref (inbuf);
 
1989
    return GST_FLOW_OK;
 
1990
  }
1279
1991
}
1280
1992
 
1281
1993
static GstStateChangeReturn
1366
2078
 
1367
2079
  while (in_plugin) {
1368
2080
    GstFFMpegDecClassParams *params;
1369
 
    GstCaps *srccaps, *sinkcaps;
 
2081
    GstCaps *srccaps = NULL, *sinkcaps = NULL;
1370
2082
    gchar *type_name;
1371
2083
 
1372
2084
    /* no quasi-codecs, please */
1394
2106
    } else {
1395
2107
      srccaps = gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL);
1396
2108
    }
1397
 
    if (!sinkcaps || !srccaps) {
1398
 
      if (sinkcaps)
1399
 
        gst_caps_unref (sinkcaps);
1400
 
      if (srccaps)
1401
 
        gst_caps_unref (srccaps);
 
2109
    if (!sinkcaps || !srccaps)
1402
2110
      goto next;
1403
 
    }
1404
2111
 
1405
2112
    /* construct the type */
1406
2113
    type_name = g_strdup_printf ("ffdec_%s", in_plugin->name);
1413
2120
 
1414
2121
    params = g_new0 (GstFFMpegDecClassParams, 1);
1415
2122
    params->in_plugin = in_plugin;
1416
 
    params->srccaps = srccaps;
1417
 
    params->sinkcaps = sinkcaps;
 
2123
    params->srccaps = gst_caps_ref (srccaps);
 
2124
    params->sinkcaps = gst_caps_ref (sinkcaps);
1418
2125
    g_hash_table_insert (global_plugins,
1419
2126
        GINT_TO_POINTER (0), (gpointer) params);
1420
2127
 
1431
2138
      case CODEC_ID_H264:
1432
2139
        rank = GST_RANK_PRIMARY;
1433
2140
        break;
 
2141
      case CODEC_ID_DVVIDEO:
 
2142
        /* we have a good dv decoder, fast on both ppc as well as x86. they say
 
2143
           libdv's quality is better though. leave as secondary.
 
2144
           note: if you change this, see the code in gstdv.c in good/ext/dv. */
 
2145
        rank = GST_RANK_SECONDARY;
 
2146
        break;
1434
2147
      default:
1435
2148
        rank = GST_RANK_MARGINAL;
1436
2149
        break;
1437
 
      case CODEC_ID_WMV3:
1438
 
      case CODEC_ID_VC9:
1439
2150
        /* what's that? */
1440
2151
      case CODEC_ID_SP5X:
1441
2152
        /* MP3 and MPEG2 have better alternatives and
1458
2169
        GINT_TO_POINTER (type), (gpointer) params);
1459
2170
 
1460
2171
  next:
 
2172
    if (sinkcaps)
 
2173
      gst_caps_unref (sinkcaps);
 
2174
    if (srccaps)
 
2175
      gst_caps_unref (srccaps);
1461
2176
    in_plugin = in_plugin->next;
1462
2177
  }
1463
2178
  g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));