gstvideodecoder.c 135 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* GStreamer
 * Copyright (C) 2008 David Schleef <ds@schleef.org>
 * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
 * Copyright (C) 2011 Nokia Corporation. All rights reserved.
 *   Contact: Stefan Kost <stefan.kost@nokia.com>
 * Copyright (C) 2012 Collabora Ltd.
 *	Author : Edward Hervey <edward@collabora.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
Tim-Philipp Müller's avatar
Tim-Philipp Müller committed
21
22
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
23
24
25
26
27
 */

/**
 * SECTION:gstvideodecoder
 * @short_description: Base class for video decoders
28
 * @see_also:
29
30
31
32
 *
 * This base class is for video decoders turning encoded data into raw video
 * frames.
 *
33
34
 * The GstVideoDecoder base class and derived subclasses should cooperate as
 * follows:
35
36
37
38
39
 * <orderedlist>
 * <listitem>
 *   <itemizedlist><title>Configuration</title>
 *   <listitem><para>
 *     Initially, GstVideoDecoder calls @start when the decoder element
40
 *     is activated, which allows the subclass to perform any global setup.
41
42
 *   </para></listitem>
 *   <listitem><para>
43
 *     GstVideoDecoder calls @set_format to inform the subclass of caps
44
45
46
47
48
49
 *     describing input video data that it is about to receive, including
 *     possibly configuration data.
 *     While unlikely, it might be called more than once, if changing input
 *     parameters require reconfiguration.
 *   </para></listitem>
 *   <listitem><para>
50
51
 *     Incoming data buffers are processed as needed, described in Data
 *     Processing below.
52
53
 *   </para></listitem>
 *   <listitem><para>
54
55
56
57
58
59
60
61
 *     GstVideoDecoder calls @stop at end of all processing.
 *   </para></listitem>
 *   </itemizedlist>
 * </listitem>
 * <listitem>
 *   <itemizedlist>
 *   <title>Data processing</title>
 *     <listitem><para>
62
 *       The base class gathers input data, and optionally allows subclass
63
64
65
66
 *       to parse this into subsequently manageable chunks, typically
 *       corresponding to and referred to as 'frames'.
 *     </para></listitem>
 *     <listitem><para>
67
68
 *       Each input frame is provided in turn to the subclass' @handle_frame
 *       callback.
69
 *       The ownership of the frame is given to the @handle_frame callback.
70
71
 *     </para></listitem>
 *     <listitem><para>
72
 *       If codec processing results in decoded data, the subclass should call
73
 *       @gst_video_decoder_finish_frame to have decoded data pushed.
74
75
76
77
 *       downstream. Otherwise, the subclass must call
 *       @gst_video_decoder_drop_frame, to allow the base class to do timestamp
 *       and offset tracking, and possibly to requeue the frame for a later
 *       attempt in the case of reverse playback.
78
79
80
81
82
83
 *     </para></listitem>
 *   </itemizedlist>
 * </listitem>
 * <listitem>
 *   <itemizedlist><title>Shutdown phase</title>
 *   <listitem><para>
84
 *     The GstVideoDecoder class calls @stop to inform the subclass that data
85
86
87
88
 *     parsing will be stopped.
 *   </para></listitem>
 *   </itemizedlist>
 * </listitem>
89
90
91
92
93
 * <listitem>
 *   <itemizedlist><title>Additional Notes</title>
 *   <listitem>
 *     <itemizedlist><title>Seeking/Flushing</title>
 *     <listitem><para>
94
95
96
97
98
 *   When the pipeline is seeked or otherwise flushed, the subclass is
 *   informed via a call to its @reset callback, with the hard parameter
 *   set to true. This indicates the subclass should drop any internal data
 *   queues and timestamps and prepare for a fresh set of buffers to arrive
 *   for parsing and decoding.
99
100
101
102
103
104
 *     </para></listitem>
 *     </itemizedlist>
 *   </listitem>
 *   <listitem>
 *     <itemizedlist><title>End Of Stream</title>
 *     <listitem><para>
105
106
107
108
 *   At end-of-stream, the subclass @parse function may be called some final
 *   times with the at_eos parameter set to true, indicating that the element
 *   should not expect any more data to be arriving, and it should parse and
 *   remaining frames and call gst_video_decoder_have_frame() if possible.
109
110
111
112
113
 *     </para></listitem>
 *     </itemizedlist>
 *   </listitem>
 *   </itemizedlist>
 * </listitem>
114
115
 * </orderedlist>
 *
116
 * The subclass is responsible for providing pad template caps for
117
 * source and sink pads. The pads need to be named "sink" and "src". It also
118
119
120
121
122
 * needs to provide information about the ouptput caps, when they are known.
 * This may be when the base class calls the subclass' @set_format function,
 * though it might be during decoding, before calling
 * @gst_video_decoder_finish_frame. This is done via
 * @gst_video_decoder_set_output_state
123
 *
124
 * The subclass is also responsible for providing (presentation) timestamps
125
 * (likely based on corresponding input ones).  If that is not applicable
126
 * or possible, the base class provides limited framerate based interpolation.
127
 *
128
129
 * Similarly, the base class provides some limited (legacy) seeking support
 * if specifically requested by the subclass, as full-fledged support
130
131
 * should rather be left to upstream demuxer, parser or alike.  This simple
 * approach caters for seeking and duration reporting using estimated input
132
 * bitrates. To enable it, a subclass should call
133
134
 * @gst_video_decoder_set_estimate_rate to enable handling of incoming
 * byte-streams.
135
 *
136
 * The base class provides some support for reverse playback, in particular
137
 * in case incoming data is not packetized or upstream does not provide
138
139
140
141
142
143
 * fragments on keyframe boundaries.  However, the subclass should then be
 * prepared for the parsing and frame processing stage to occur separately
 * (in normal forward processing, the latter immediately follows the former),
 * The subclass also needs to ensure the parsing stage properly marks
 * keyframes, unless it knows the upstream elements will do so properly for
 * incoming data.
144
 *
145
 * The bare minimum that a functional subclass needs to implement is:
146
147
148
 * <itemizedlist>
 *   <listitem><para>Provide pad templates</para></listitem>
 *   <listitem><para>
149
150
 *      Inform the base class of output caps via
 *      @gst_video_decoder_set_output_state
151
152
 *   </para></listitem>
 *   <listitem><para>
153
 *      Parse input data, if it is not considered packetized from upstream
154
155
156
 *      Data will be provided to @parse which should invoke
 *      @gst_video_decoder_add_to_frame and @gst_video_decoder_have_frame to
 *      separate the data belonging to each video frame.
157
158
159
 *   </para></listitem>
 *   <listitem><para>
 *      Accept data in @handle_frame and provide decoded results to
160
 *      @gst_video_decoder_finish_frame, or call @gst_video_decoder_drop_frame.
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
 *   </para></listitem>
 * </itemizedlist>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* TODO
 *
 * * Add a flag/boolean for I-frame-only/image decoders so we can do extra
 *   features, like applying QoS on input (as opposed to after the frame is
 *   decoded).
 * * Add a flag/boolean for decoders that require keyframes, so the base
 *   class can automatically discard non-keyframes before one has arrived
176
 * * Detect reordered frame/timestamps and fix the pts/dts
177
178
179
180
181
182
183
 * * Support for GstIndex (or shall we not care ?)
 * * Calculate actual latency based on input/output timestamp/frame_number
 *   and if it exceeds the recorded one, save it and emit a GST_MESSAGE_LATENCY
 * * Emit latency message when it changes
 *
 */

184
185
186
187
188
/* Implementation notes:
 * The Video Decoder base class operates in 2 primary processing modes, depending
 * on whether forward or reverse playback is requested.
 *
 * Forward playback:
189
190
 *   * Incoming buffer -> @parse() -> add_to_frame()/have_frame() ->
 *     handle_frame() -> push downstream
191
 *
192
193
194
195
 * Reverse playback is more complicated, since it involves gathering incoming
 * data regions as we loop backwards through the upstream data. The processing
 * concept (using incoming buffers as containing one frame each to simplify
 * things) is:
196
197
198
 *
 * Upstream data we want to play:
 *  Buffer encoded order:  1  2  3  4  5  6  7  8  9  EOS
199
 *  Keyframe flag:            K        K
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
 *  Groupings:             AAAAAAA  BBBBBBB  CCCCCCC
 *
 * Input:
 *  Buffer reception order:  7  8  9  4  5  6  1  2  3  EOS
 *  Keyframe flag:                       K        K
 *  Discont flag:            D        D        D
 *
 * - Each Discont marks a discont in the decoding order.
 * - The keyframes mark where we can start decoding.
 *
 * Initially, we prepend incoming buffers to the gather queue. Whenever the
 * discont flag is set on an incoming buffer, the gather queue is flushed out
 * before the new buffer is collected.
 *
 * The above data will be accumulated in the gather queue like this:
 *
 *   gather queue:  9  8  7
 *                        D
 *
 * Whe buffer 4 is received (with a DISCONT), we flush the gather queue like
 * this:
 *
 *   while (gather)
223
224
 *     take head of queue and prepend to parse queue (this reverses the
 *     sequence, so parse queue is 7 -> 8 -> 9)
225
 *
226
227
 *   Next, we process the parse queue, which now contains all un-parsed packets
 *   (including any leftover ones from the previous decode section)
228
229
230
231
 *
 *   for each buffer now in the parse queue:
 *     Call the subclass parse function, prepending each resulting frame to
 *     the parse_gather queue. Buffers which precede the first one that
232
233
 *     produces a parsed frame are retained in the parse queue for
 *     re-processing on the next cycle of parsing.
234
 *
235
236
 *   The parse_gather queue now contains frame objects ready for decoding,
 *   in reverse order.
237
238
239
240
241
242
243
244
245
246
 *   parse_gather: 9 -> 8 -> 7
 *
 *   while (parse_gather)
 *     Take the head of the queue and prepend it to the decode queue
 *     If the frame was a keyframe, process the decode queue
 *   decode is now 7-8-9
 *
 *  Processing the decode queue results in frames with attached output buffers
 *  stored in the 'output_queue' ready for outputting in reverse order.
 *
247
248
 * After we flushed the gather queue and parsed it, we add 4 to the (now empty)
 * gather queue. We get the following situation:
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
 *
 *  gather queue:    4
 *  decode queue:    7  8  9
 *
 * After we received 5 (Keyframe) and 6:
 *
 *  gather queue:    6  5  4
 *  decode queue:    7  8  9
 *
 * When we receive 1 (DISCONT) which triggers a flush of the gather queue:
 *
 *   Copy head of the gather queue (6) to decode queue:
 *
 *    gather queue:    5  4
 *    decode queue:    6  7  8  9
 *
 *   Copy head of the gather queue (5) to decode queue. This is a keyframe so we
 *   can start decoding.
 *
 *    gather queue:    4
 *    decode queue:    5  6  7  8  9
 *
 *   Decode frames in decode queue, store raw decoded data in output queue, we
 *   can take the head of the decode queue and prepend the decoded result in the
 *   output queue:
 *
 *    gather queue:    4
276
 *    decode queue:
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
 *    output queue:    9  8  7  6  5
 *
 *   Now output all the frames in the output queue, picking a frame from the
 *   head of the queue.
 *
 *   Copy head of the gather queue (4) to decode queue, we flushed the gather
 *   queue and can now store input buffer in the gather queue:
 *
 *    gather queue:    1
 *    decode queue:    4
 *
 *  When we receive EOS, the queue looks like:
 *
 *    gather queue:    3  2  1
 *    decode queue:    4
 *
 *  Fill decode queue, first keyframe we copy is 2:
 *
 *    gather queue:    1
 *    decode queue:    2  3  4
 *
 *  Decoded output:
 *
 *    gather queue:    1
301
 *    decode queue:
302
303
304
305
306
 *    output queue:    4  3  2
 *
 *  Leftover buffer 1 cannot be decoded and must be discarded.
 */

307
308
#include "gstvideodecoder.h"
#include "gstvideoutils.h"
309
#include "gstvideoutilsprivate.h"
310

311
#include <gst/video/video.h>
312
#include <gst/video/video-event.h>
313
314
#include <gst/video/gstvideopool.h>
#include <gst/video/gstvideometa.h>
315
316
317
318
319
320
321
322
323
324
325
326
327
#include <string.h>

GST_DEBUG_CATEGORY (videodecoder_debug);
#define GST_CAT_DEFAULT videodecoder_debug

#define GST_VIDEO_DECODER_GET_PRIVATE(obj)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_VIDEO_DECODER, \
        GstVideoDecoderPrivate))

struct _GstVideoDecoderPrivate
{
  /* FIXME introduce a context ? */

328
  GstBufferPool *pool;
329
330
  GstAllocator *allocator;
  GstAllocationParams params;
331

332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  /* parse tracking */
  /* input data */
  GstAdapter *input_adapter;
  /* assembles current frame */
  GstAdapter *output_adapter;

  /* Whether we attempt to convert newsegment from bytes to
   * time using a bitrate estimation */
  gboolean do_estimate_rate;

  /* Whether input is considered packetized or not */
  gboolean packetized;

  /* Error handling */
  gint max_errors;
  gint error_count;
348
349
  gboolean had_output_data;
  gboolean had_input_data;
350

351
  gboolean needs_format;
352
353
  /* input_segment are output_segment identical */
  gboolean in_out_segment_sync;
354

355
356
357
358
359
  /* ... being tracked here;
   * only available during parsing */
  GstVideoCodecFrame *current_frame;
  /* events that should apply to the current frame */
  GList *current_frame_events;
360
361
  /* events that should be pushed before the next frame */
  GList *pending_events;
362
363
364
365
366
367
368
369

  /* relative offset of input data */
  guint64 input_offset;
  /* relative offset of frame */
  guint64 frame_offset;
  /* tracking ts and offsets */
  GList *timestamps;

370
  /* last outgoing ts */
371
  GstClockTime last_timestamp_out;
372
373
  /* incoming pts - dts */
  GstClockTime pts_delta;
374
  gboolean reordered_output;
375
376
377
378
379
380
381
382
383
384

  /* reverse playback */
  /* collect input */
  GList *gather;
  /* to-be-parsed */
  GList *parse;
  /* collected parsed frames */
  GList *parse_gather;
  /* frames to be handled == decoded */
  GList *decode;
385
386
  /* collected output - of buffer objects, not frames */
  GList *output_queued;
387

388
389

  /* base_picture_number is the picture number of the reference picture */
390
  guint64 base_picture_number;
391
392
393
  /* combine with base_picture_number, framerate and calcs to yield (presentation) ts */
  GstClockTime base_timestamp;

394
395
396
397
  /* FIXME : reorder_depth is never set */
  int reorder_depth;
  int distance_from_sync;

398
399
  guint32 system_frame_number;
  guint32 decode_frame_number;
400
401
402

  GList *frames;                /* Protected with OBJECT_LOCK */
  GstVideoCodecState *input_state;
403
  GstVideoCodecState *output_state;     /* OBJECT_LOCK and STREAM_LOCK */
404
405
406
  gboolean output_state_changed;

  /* QoS properties */
407
408
409
  gdouble proportion;           /* OBJECT_LOCK */
  GstClockTime earliest_time;   /* OBJECT_LOCK */
  GstClockTime qos_frame_duration;      /* OBJECT_LOCK */
410
411
412
413
414
415
416
417
418
419
420
  gboolean discont;
  /* qos messages: frames dropped/processed */
  guint dropped;
  guint processed;

  /* Outgoing byte size ? */
  gint64 bytes_out;
  gint64 time;

  gint64 min_latency;
  gint64 max_latency;
421

422
423
424
425
  /* upstream stream tags (global tags are passed through as-is) */
  GstTagList *upstream_tags;

  /* subclass tags */
426
  GstTagList *tags;
427
428
  GstTagMergeMode tags_merge_mode;

429
  gboolean tags_changed;
430
431
432

  /* flags */
  gboolean use_default_pad_acceptcaps;
433
434
};

435
436
437
438
439
static GstElementClass *parent_class = NULL;
static void gst_video_decoder_class_init (GstVideoDecoderClass * klass);
static void gst_video_decoder_init (GstVideoDecoder * dec,
    GstVideoDecoderClass * klass);

440
441
static void gst_video_decoder_finalize (GObject * object);

442
443
444
445
446
447
448
449
450
451
452
453
454
455
static gboolean gst_video_decoder_setcaps (GstVideoDecoder * dec,
    GstCaps * caps);
static gboolean gst_video_decoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_video_decoder_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstFlowReturn gst_video_decoder_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static gboolean gst_video_decoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstStateChangeReturn gst_video_decoder_change_state (GstElement *
    element, GstStateChange transition);
static gboolean gst_video_decoder_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
456
457
static void gst_video_decoder_reset (GstVideoDecoder * decoder, gboolean full,
    gboolean flush_hard);
458

459
460
static GstFlowReturn gst_video_decoder_decode_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame);
461

462
463
static void gst_video_decoder_push_event_list (GstVideoDecoder * decoder,
    GList * events);
464
465
static GstClockTime gst_video_decoder_get_frame_duration (GstVideoDecoder *
    decoder, GstVideoCodecFrame * frame);
466
467
static GstVideoCodecFrame *gst_video_decoder_new_frame (GstVideoDecoder *
    decoder);
468
469
static GstFlowReturn gst_video_decoder_clip_and_push_buf (GstVideoDecoder *
    decoder, GstBuffer * buf);
470
471
static GstFlowReturn gst_video_decoder_flush_parse (GstVideoDecoder * dec,
    gboolean at_eos);
472

473
474
static void gst_video_decoder_clear_queues (GstVideoDecoder * dec);

475
476
477
478
static gboolean gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
    GstEvent * event);
static gboolean gst_video_decoder_src_event_default (GstVideoDecoder * decoder,
    GstEvent * event);
479
480
static gboolean gst_video_decoder_decide_allocation_default (GstVideoDecoder *
    decoder, GstQuery * query);
481
482
static gboolean gst_video_decoder_propose_allocation_default (GstVideoDecoder *
    decoder, GstQuery * query);
483
static gboolean gst_video_decoder_negotiate_default (GstVideoDecoder * decoder);
484
static GstFlowReturn gst_video_decoder_parse_available (GstVideoDecoder * dec,
485
    gboolean at_eos, gboolean new_buffer);
486
487
static gboolean gst_video_decoder_negotiate_unlocked (GstVideoDecoder *
    decoder);
488
489
static gboolean gst_video_decoder_sink_query_default (GstVideoDecoder * decoder,
    GstQuery * query);
490
491
static gboolean gst_video_decoder_src_query_default (GstVideoDecoder * decoder,
    GstQuery * query);
492

493
494
495
static gboolean gst_video_decoder_transform_meta_default (GstVideoDecoder *
    decoder, GstVideoCodecFrame * frame, GstMeta * meta);

496
497
498
499
/* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
 * method to get to the padtemplates */
GType
gst_video_decoder_get_type (void)
500
{
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
  static volatile gsize type = 0;

  if (g_once_init_enter (&type)) {
    GType _type;
    static const GTypeInfo info = {
      sizeof (GstVideoDecoderClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_video_decoder_class_init,
      NULL,
      NULL,
      sizeof (GstVideoDecoder),
      0,
      (GInstanceInitFunc) gst_video_decoder_init,
    };

    _type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstVideoDecoder", &info, G_TYPE_FLAG_ABSTRACT);
    g_once_init_leave (&type, _type);
  }
  return type;
522
523
524
525
526
527
528
529
530
531
532
}

static void
gst_video_decoder_class_init (GstVideoDecoderClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);

533
534
535
536
  GST_DEBUG_CATEGORY_INIT (videodecoder_debug, "videodecoder", 0,
      "Base Video Decoder");

  parent_class = g_type_class_peek_parent (klass);
537
538
539
540
541
542
  g_type_class_add_private (klass, sizeof (GstVideoDecoderPrivate));

  gobject_class->finalize = gst_video_decoder_finalize;

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_video_decoder_change_state);
543
544
545

  klass->sink_event = gst_video_decoder_sink_event_default;
  klass->src_event = gst_video_decoder_src_event_default;
546
  klass->decide_allocation = gst_video_decoder_decide_allocation_default;
547
  klass->propose_allocation = gst_video_decoder_propose_allocation_default;
548
  klass->negotiate = gst_video_decoder_negotiate_default;
549
550
  klass->sink_query = gst_video_decoder_sink_query_default;
  klass->src_query = gst_video_decoder_src_query_default;
551
  klass->transform_meta = gst_video_decoder_transform_meta_default;
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
}

static void
gst_video_decoder_init (GstVideoDecoder * decoder, GstVideoDecoderClass * klass)
{
  GstPadTemplate *pad_template;
  GstPad *pad;

  GST_DEBUG_OBJECT (decoder, "gst_video_decoder_init");

  decoder->priv = GST_VIDEO_DECODER_GET_PRIVATE (decoder);

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
  g_return_if_fail (pad_template != NULL);

  decoder->sinkpad = pad = gst_pad_new_from_template (pad_template, "sink");

  gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_video_decoder_chain));
  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_decoder_sink_event));
  gst_pad_set_query_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_decoder_sink_query));
  gst_element_add_pad (GST_ELEMENT (decoder), decoder->sinkpad);

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
  g_return_if_fail (pad_template != NULL);

  decoder->srcpad = pad = gst_pad_new_from_template (pad_template, "src");

  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_decoder_src_event));
  gst_pad_set_query_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_decoder_src_query));
  gst_element_add_pad (GST_ELEMENT (decoder), decoder->srcpad);

  gst_segment_init (&decoder->input_segment, GST_FORMAT_TIME);
  gst_segment_init (&decoder->output_segment, GST_FORMAT_TIME);

592
  g_rec_mutex_init (&decoder->stream_lock);
593
594
595
596

  decoder->priv->input_adapter = gst_adapter_new ();
  decoder->priv->output_adapter = gst_adapter_new ();
  decoder->priv->packetized = TRUE;
597
  decoder->priv->needs_format = FALSE;
598

599
  decoder->priv->min_latency = 0;
600
  decoder->priv->max_latency = 0;
601

602
  gst_video_decoder_reset (decoder, TRUE, TRUE);
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
}

static gboolean
gst_video_rawvideo_convert (GstVideoCodecState * state,
    GstFormat src_format, gint64 src_value,
    GstFormat * dest_format, gint64 * dest_value)
{
  gboolean res = FALSE;
  guint vidsize;
  guint fps_n, fps_d;

  g_return_val_if_fail (dest_format != NULL, FALSE);
  g_return_val_if_fail (dest_value != NULL, FALSE);

  if (src_format == *dest_format || src_value == 0 || src_value == -1) {
    *dest_value = src_value;
    return TRUE;
  }

  vidsize = GST_VIDEO_INFO_SIZE (&state->info);
  fps_n = GST_VIDEO_INFO_FPS_N (&state->info);
  fps_d = GST_VIDEO_INFO_FPS_D (&state->info);

  if (src_format == GST_FORMAT_BYTES &&
      *dest_format == GST_FORMAT_DEFAULT && vidsize) {
    /* convert bytes to frames */
    *dest_value = gst_util_uint64_scale_int (src_value, 1, vidsize);
    res = TRUE;
  } else if (src_format == GST_FORMAT_DEFAULT &&
      *dest_format == GST_FORMAT_BYTES && vidsize) {
    /* convert bytes to frames */
    *dest_value = src_value * vidsize;
    res = TRUE;
  } else if (src_format == GST_FORMAT_DEFAULT &&
      *dest_format == GST_FORMAT_TIME && fps_n) {
    /* convert frames to time */
    *dest_value = gst_util_uint64_scale (src_value, GST_SECOND * fps_d, fps_n);
    res = TRUE;
  } else if (src_format == GST_FORMAT_TIME &&
      *dest_format == GST_FORMAT_DEFAULT && fps_d) {
    /* convert time to frames */
    *dest_value = gst_util_uint64_scale (src_value, fps_n, GST_SECOND * fps_d);
    res = TRUE;
  } else if (src_format == GST_FORMAT_TIME &&
      *dest_format == GST_FORMAT_BYTES && fps_d && vidsize) {
648
    /* convert time to bytes */
649
    *dest_value = gst_util_uint64_scale (src_value,
650
        fps_n * (guint64) vidsize, GST_SECOND * fps_d);
651
652
653
    res = TRUE;
  } else if (src_format == GST_FORMAT_BYTES &&
      *dest_format == GST_FORMAT_TIME && fps_n && vidsize) {
654
    /* convert bytes to time */
655
    *dest_value = gst_util_uint64_scale (src_value,
656
        GST_SECOND * fps_d, fps_n * (guint64) vidsize);
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
    res = TRUE;
  }

  return res;
}

static gboolean
gst_video_encoded_video_convert (gint64 bytes, gint64 time,
    GstFormat src_format, gint64 src_value, GstFormat * dest_format,
    gint64 * dest_value)
{
  gboolean res = FALSE;

  g_return_val_if_fail (dest_format != NULL, FALSE);
  g_return_val_if_fail (dest_value != NULL, FALSE);

  if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
          src_value == -1)) {
    if (dest_value)
      *dest_value = src_value;
    return TRUE;
  }

  if (bytes <= 0 || time <= 0) {
    GST_DEBUG ("not enough metadata yet to convert");
    goto exit;
  }

  switch (src_format) {
    case GST_FORMAT_BYTES:
      switch (*dest_format) {
        case GST_FORMAT_TIME:
          *dest_value = gst_util_uint64_scale (src_value, time, bytes);
          res = TRUE;
          break;
        default:
          res = FALSE;
      }
      break;
    case GST_FORMAT_TIME:
      switch (*dest_format) {
        case GST_FORMAT_BYTES:
          *dest_value = gst_util_uint64_scale (src_value, bytes, time);
          res = TRUE;
          break;
        default:
          res = FALSE;
      }
      break;
    default:
      GST_DEBUG ("unhandled conversion from %d to %d", src_format,
          *dest_format);
      res = FALSE;
  }

exit:
  return res;
}

static GstVideoCodecState *
_new_input_state (GstCaps * caps)
{
  GstVideoCodecState *state;
  GstStructure *structure;
  const GValue *codec_data;

  state = g_slice_new0 (GstVideoCodecState);
  state->ref_count = 1;
  gst_video_info_init (&state->info);
  if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, caps)))
    goto parse_fail;
  state->caps = gst_caps_ref (caps);

  structure = gst_caps_get_structure (caps, 0);

  codec_data = gst_structure_get_value (structure, "codec_data");
  if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER)
734
    state->codec_data = GST_BUFFER (g_value_dup_boxed (codec_data));
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764

  return state;

parse_fail:
  {
    g_slice_free (GstVideoCodecState, state);
    return NULL;
  }
}

static GstVideoCodecState *
_new_output_state (GstVideoFormat fmt, guint width, guint height,
    GstVideoCodecState * reference)
{
  GstVideoCodecState *state;

  state = g_slice_new0 (GstVideoCodecState);
  state->ref_count = 1;
  gst_video_info_init (&state->info);
  gst_video_info_set_format (&state->info, fmt, width, height);

  if (reference) {
    GstVideoInfo *tgt, *ref;

    tgt = &state->info;
    ref = &reference->info;

    /* Copy over extra fields from reference state */
    tgt->interlace_mode = ref->interlace_mode;
    tgt->flags = ref->flags;
765
766
    /* only copy values that are not unknown so that we don't override the
     * defaults. subclasses should really fill these in when they know. */
767
768
    if (ref->chroma_site)
      tgt->chroma_site = ref->chroma_site;
769
770
771
772
773
774
775
776
    if (ref->colorimetry.range)
      tgt->colorimetry.range = ref->colorimetry.range;
    if (ref->colorimetry.matrix)
      tgt->colorimetry.matrix = ref->colorimetry.matrix;
    if (ref->colorimetry.transfer)
      tgt->colorimetry.transfer = ref->colorimetry.transfer;
    if (ref->colorimetry.primaries)
      tgt->colorimetry.primaries = ref->colorimetry.primaries;
777
778
779
780
781
782
    GST_DEBUG ("reference par %d/%d fps %d/%d",
        ref->par_n, ref->par_d, ref->fps_n, ref->fps_d);
    tgt->par_n = ref->par_n;
    tgt->par_d = ref->par_d;
    tgt->fps_n = ref->fps_n;
    tgt->fps_d = ref->fps_d;
783
784
785
786
787
788
    tgt->views = ref->views;
    if (GST_VIDEO_INFO_MULTIVIEW_MODE (ref) != GST_VIDEO_MULTIVIEW_MODE_NONE) {
      GST_VIDEO_INFO_MULTIVIEW_MODE (tgt) = GST_VIDEO_INFO_MULTIVIEW_MODE (ref);
      GST_VIDEO_INFO_MULTIVIEW_FLAGS (tgt) =
          GST_VIDEO_INFO_MULTIVIEW_FLAGS (ref);
    }
789
790
791
792
793
794
795
796
797
798
  }

  GST_DEBUG ("reference par %d/%d fps %d/%d",
      state->info.par_n, state->info.par_d,
      state->info.fps_n, state->info.fps_d);

  return state;
}

static gboolean
799
gst_video_decoder_setcaps (GstVideoDecoder * decoder, GstCaps * caps)
800
801
802
803
804
805
806
807
808
{
  GstVideoDecoderClass *decoder_class;
  GstVideoCodecState *state;
  gboolean ret = TRUE;

  decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);

  GST_DEBUG_OBJECT (decoder, "setcaps %" GST_PTR_FORMAT, caps);

809
810
811
812
813
814
815
816
817
818
  GST_VIDEO_DECODER_STREAM_LOCK (decoder);

  if (decoder->priv->input_state) {
    GST_DEBUG_OBJECT (decoder,
        "Checking if caps changed old %" GST_PTR_FORMAT " new %" GST_PTR_FORMAT,
        decoder->priv->input_state->caps, caps);
    if (gst_caps_is_equal (decoder->priv->input_state->caps, caps))
      goto caps_not_changed;
  }

819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
  state = _new_input_state (caps);

  if (G_UNLIKELY (state == NULL))
    goto parse_fail;

  if (decoder_class->set_format)
    ret = decoder_class->set_format (decoder, state);

  if (!ret)
    goto refused_format;

  if (decoder->priv->input_state)
    gst_video_codec_state_unref (decoder->priv->input_state);
  decoder->priv->input_state = state;

  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return ret;

838
839
840
841
842
843
caps_not_changed:
  {
    GST_DEBUG_OBJECT (decoder, "Caps did not change - ignore");
    GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
    return TRUE;
  }
844

845
  /* ERRORS */
846
847
848
parse_fail:
  {
    GST_WARNING_OBJECT (decoder, "Failed to parse caps");
849
    GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
    return FALSE;
  }

refused_format:
  {
    GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
    GST_WARNING_OBJECT (decoder, "Subclass refused caps");
    gst_video_codec_state_unref (state);
    return FALSE;
  }
}

static void
gst_video_decoder_finalize (GObject * object)
{
  GstVideoDecoder *decoder;

  decoder = GST_VIDEO_DECODER (object);

  GST_DEBUG_OBJECT (object, "finalize");

871
  g_rec_mutex_clear (&decoder->stream_lock);
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886

  if (decoder->priv->input_adapter) {
    g_object_unref (decoder->priv->input_adapter);
    decoder->priv->input_adapter = NULL;
  }
  if (decoder->priv->output_adapter) {
    g_object_unref (decoder->priv->output_adapter);
    decoder->priv->output_adapter = NULL;
  }

  if (decoder->priv->input_state)
    gst_video_codec_state_unref (decoder->priv->input_state);
  if (decoder->priv->output_state)
    gst_video_codec_state_unref (decoder->priv->output_state);

887
  if (decoder->priv->pool) {
888
889
890
891
892
    gst_object_unref (decoder->priv->pool);
    decoder->priv->pool = NULL;
  }

  if (decoder->priv->allocator) {
Wim Taymans's avatar
Wim Taymans committed
893
    gst_object_unref (decoder->priv->allocator);
894
    decoder->priv->allocator = NULL;
895
896
  }

897
898
899
900
901
902
903
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

/* hard == FLUSH, otherwise discont */
static GstFlowReturn
gst_video_decoder_flush (GstVideoDecoder * dec, gboolean hard)
{
904
  GstVideoDecoderClass *klass = GST_VIDEO_DECODER_GET_CLASS (dec);
905
906
907
908
  GstFlowReturn ret = GST_FLOW_OK;

  GST_LOG_OBJECT (dec, "flush hard %d", hard);

909
910
911
912
913
914
  /* Inform subclass */
  if (klass->reset) {
    GST_FIXME_OBJECT (dec, "GstVideoDecoder::reset() is deprecated");
    klass->reset (dec, hard);
  }

915
  if (klass->flush)
916
    klass->flush (dec);
917

918
  /* and get (re)set for the sequel */
919
  gst_video_decoder_reset (dec, FALSE, hard);
920
921
922
923

  return ret;
}

924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
static GstEvent *
gst_video_decoder_create_merged_tags_event (GstVideoDecoder * dec)
{
  GstTagList *merged_tags;

  GST_LOG_OBJECT (dec, "upstream : %" GST_PTR_FORMAT, dec->priv->upstream_tags);
  GST_LOG_OBJECT (dec, "decoder  : %" GST_PTR_FORMAT, dec->priv->tags);
  GST_LOG_OBJECT (dec, "mode     : %d", dec->priv->tags_merge_mode);

  merged_tags =
      gst_tag_list_merge (dec->priv->upstream_tags, dec->priv->tags,
      dec->priv->tags_merge_mode);

  GST_DEBUG_OBJECT (dec, "merged   : %" GST_PTR_FORMAT, merged_tags);

  if (merged_tags == NULL)
    return NULL;

  if (gst_tag_list_is_empty (merged_tags)) {
    gst_tag_list_unref (merged_tags);
    return NULL;
  }

  return gst_event_new_tag (merged_tags);
}

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
static gboolean
gst_video_decoder_push_event (GstVideoDecoder * decoder, GstEvent * event)
{
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      GstSegment segment;

      gst_event_copy_segment (event, &segment);

      GST_DEBUG_OBJECT (decoder, "segment %" GST_SEGMENT_FORMAT, &segment);

      if (segment.format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (decoder, "received non TIME newsegment");
        break;
      }

967
      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
968
      decoder->output_segment = segment;
969
      decoder->priv->in_out_segment_sync =
970
          gst_segment_is_equal (&decoder->input_segment, &segment);
971
      decoder->priv->last_timestamp_out = GST_CLOCK_TIME_NONE;
972
973
974
975
976
977
978
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
      break;
    }
    default:
      break;
  }

979
980
981
  GST_DEBUG_OBJECT (decoder, "pushing event %s",
      gst_event_type_get_name (GST_EVENT_TYPE (event)));

982
983
984
  return gst_pad_push_event (decoder->srcpad, event);
}

985
static GstFlowReturn
986
987
gst_video_decoder_parse_available (GstVideoDecoder * dec, gboolean at_eos,
    gboolean new_buffer)
988
989
990
991
{
  GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_GET_CLASS (dec);
  GstVideoDecoderPrivate *priv = dec->priv;
  GstFlowReturn ret = GST_FLOW_OK;
992
993
  gsize was_available, available;
  guint inactive = 0;
994
995
996

  available = gst_adapter_available (priv->input_adapter);

997
  while (available || new_buffer) {
998
    new_buffer = FALSE;
999
1000
1001
1002
1003
    /* current frame may have been parsed and handled,
     * so we need to set up a new one when asking subclass to parse */
    if (priv->current_frame == NULL)
      priv->current_frame = gst_video_decoder_new_frame (dec);

1004
    was_available = available;
1005
1006
    ret = decoder_class->parse (dec, priv->current_frame,
        priv->input_adapter, at_eos);
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
    if (ret != GST_FLOW_OK)
      break;

    /* if the subclass returned success (GST_FLOW_OK), it is expected
     * to have collected and submitted a frame, i.e. it should have
     * called gst_video_decoder_have_frame(), or at least consumed a
     * few bytes through gst_video_decoder_add_to_frame().
     *
     * Otherwise, this is an implementation bug, and we error out
     * after 2 failed attempts */
1017
    available = gst_adapter_available (priv->input_adapter);
1018
1019
1020
1021
    if (!priv->current_frame || available != was_available)
      inactive = 0;
    else if (++inactive == 2)
      goto error_inactive;
1022
1023
1024
  }

  return ret;
1025
1026
1027
1028
1029
1030
1031

  /* ERRORS */
error_inactive:
  {
    GST_ERROR_OBJECT (dec, "Failed to consume data. Error in subclass?");
    return GST_FLOW_ERROR;
  }
1032
1033
}

1034
static GstFlowReturn
1035
gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos)
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
{
  GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_GET_CLASS (dec);
  GstVideoDecoderPrivate *priv = dec->priv;
  GstFlowReturn ret = GST_FLOW_OK;

  GST_VIDEO_DECODER_STREAM_LOCK (dec);

  if (dec->input_segment.rate > 0.0) {
    /* Forward mode, if unpacketized, give the child class
     * a final chance to flush out packets */
    if (!priv->packetized) {
1047
      ret = gst_video_decoder_parse_available (dec, TRUE, FALSE);
1048
    }
1049
1050
1051
1052

    if (at_eos) {
      if (decoder_class->finish)
        ret = decoder_class->finish (dec);
Jan Schmidt's avatar
Jan Schmidt committed
1053
1054
1055
1056
1057
1058
    } else {
      if (decoder_class->drain) {
        ret = decoder_class->drain (dec);
      } else {
        GST_FIXME_OBJECT (dec, "Sub-class should implement drain()");
      }
1059
    }
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
  } else {
    /* Reverse playback mode */
    ret = gst_video_decoder_flush_parse (dec, TRUE);
  }

  GST_VIDEO_DECODER_STREAM_UNLOCK (dec);

  return ret;
}

1070
1071
1072
1073
1074
1075
static GList *
_flush_events (GstPad * pad, GList * events)
{
  GList *tmp;

  for (tmp = events; tmp; tmp = tmp->next) {
1076
1077
1078
    if (GST_EVENT_TYPE (tmp->data) != GST_EVENT_EOS &&
        GST_EVENT_TYPE (tmp->data) != GST_EVENT_SEGMENT &&
        GST_EVENT_IS_STICKY (tmp->data)) {
1079
1080
      gst_pad_store_sticky_event (pad, GST_EVENT_CAST (tmp->data));
    }
1081
    gst_event_unref (tmp->data);
1082
1083
1084
1085
1086
1087
  }
  g_list_free (events);

  return NULL;
}

1088
1089
1090
1091
/* Must be called holding the GST_VIDEO_DECODER_STREAM_LOCK */
static gboolean
gst_video_decoder_negotiate_default_caps (GstVideoDecoder * decoder)
{
1092
  GstCaps *caps, *templcaps;
1093
1094
1095
1096
1097
1098
  GstVideoCodecState *state;
  GstVideoInfo info;
  gint i;
  gint caps_size;
  GstStructure *structure;

1099
1100
  templcaps = gst_pad_get_pad_template_caps (decoder->srcpad);
  caps = gst_pad_peer_query_caps (decoder->srcpad, templcaps);
1101
  if (caps)
1102
    gst_caps_unref (templcaps);
1103
  else
1104
    caps = templcaps;
1105
  templcaps = NULL;
1106

1107
1108
1109
  if (!caps || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
    goto caps_error;

1110
1111
  GST_LOG_OBJECT (decoder, "peer caps %" GST_PTR_FORMAT, caps);

1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
  /* before fixating, try to use whatever upstream provided */
  caps = gst_caps_make_writable (caps);
  caps_size = gst_caps_get_size (caps);
  if (decoder->priv->input_state && decoder->priv->input_state->caps) {
    GstCaps *sinkcaps = decoder->priv->input_state->caps;
    GstStructure *structure = gst_caps_get_structure (sinkcaps, 0);
    gint width, height;
    gint par_n, par_d;
    gint fps_n, fps_d;

    if (gst_structure_get_int (structure, "width", &width)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i), "width",
            G_TYPE_INT, width, NULL);
      }
    }

    if (gst_structure_get_int (structure, "height", &height)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i), "height",
            G_TYPE_INT, height, NULL);
      }
    }

    if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i), "framerate",
            GST_TYPE_FRACTION, fps_n, fps_d, NULL);
      }
    }

    if (gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n,
            &par_d)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i),
            "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
      }
    }
  }

  for (i = 0; i < caps_size; i++) {
    structure = gst_caps_get_structure (caps, i);
    /* Random 1280x720@30 for fixation */
    gst_structure_fixate_field_nearest_int (structure, "width", 1280);
    gst_structure_fixate_field_nearest_int (structure, "height", 720);
    gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
1158
1159
1160
1161
1162
1163
1164
    if (gst_structure_has_field (structure, "pixel-aspect-ratio")) {
      gst_structure_fixate_field_nearest_fraction (structure,
          "pixel-aspect-ratio", 1, 1);
    } else {
      gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION,
          1, 1, NULL);
    }
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
  }
  caps = gst_caps_fixate (caps);
  structure = gst_caps_get_structure (caps, 0);

  if (!caps || !gst_video_info_from_caps (&info, caps))
    goto caps_error;

  GST_INFO_OBJECT (decoder,
      "Chose default caps %" GST_PTR_FORMAT " for initial gap", caps);
  state =
      gst_video_decoder_set_output_state (decoder, info.finfo->format,
      info.width, info.height, decoder->priv->input_state);
  gst_video_codec_state_unref (state);
  gst_caps_unref (caps);

  return TRUE;

caps_error:
  {
    if (caps)
      gst_caps_unref (caps);
    return FALSE;
  }
}

1190
static gboolean
1191
1192
gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
    GstEvent * event)
1193
1194
{
  GstVideoDecoderPrivate *priv;
1195
  gboolean ret = FALSE;
1196
  gboolean forward_immediate = FALSE;
1197
1198
1199
1200

  priv = decoder->priv;

  switch (GST_EVENT_TYPE (event)) {
1201
1202
1203
1204
1205
1206
1207
    case GST_EVENT_STREAM_START:
    {
      GstFlowReturn flow_ret = GST_FLOW_OK;

      flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
      ret = (flow_ret == GST_FLOW_OK);

1208
1209
      GST_DEBUG_OBJECT (decoder, "received STREAM_START. Clearing taglist");
      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
1210
1211
1212
1213
1214
1215
      /* Flush upstream tags after a STREAM_START */
      if (priv->upstream_tags) {
        gst_tag_list_unref (priv->upstream_tags);
        priv->upstream_tags = NULL;
        priv->tags_changed = TRUE;
      }
1216
1217
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

1218
1219
1220
1221
1222
1223
1224
      /* Forward STREAM_START immediately. Everything is drained after
       * the STREAM_START event and we can forward this event immediately
       * now without having buffers out of order.
       */
      forward_immediate = TRUE;
      break;
    }
1225
1226
    case GST_EVENT_CAPS:
    {
1227
1228
1229
1230
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_video_decoder_setcaps (decoder, caps);
1231
      gst_event_unref (event);
1232
      event = NULL;
1233
1234
      break;
    }
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
    case GST_EVENT_SEGMENT_DONE:
    {
      GstFlowReturn flow_ret = GST_FLOW_OK;

      flow_ret = gst_video_decoder_drain_out (decoder, TRUE);
      ret = (flow_ret == GST_FLOW_OK);

      /* Forward SEGMENT_DONE immediately. This is required
       * because no buffer or serialized event might come
       * after SEGMENT_DONE and nothing could trigger another
       * _finish_frame() call.
       *
       * The subclass can override this behaviour by overriding
       * the ::sink_event() vfunc and not chaining up to the
       * parent class' ::sink_event() until a later time.
       */
      forward_immediate = TRUE;
      break;
    }
1254
1255
1256
1257
    case GST_EVENT_EOS:
    {
      GstFlowReturn flow_ret = GST_FLOW_OK;

1258
      flow_ret = gst_video_decoder_drain_out (decoder, TRUE);
1259
      ret = (flow_ret == GST_FLOW_OK);
1260
1261
1262
1263
1264
1265
1266
1267

      /* Error out even if EOS was ok when we had input, but no output */
      if (ret && priv->had_input_data && !priv->had_output_data) {
        GST_ELEMENT_ERROR (decoder, STREAM, DECODE,
            ("No valid frames decoded before end of stream"),
            ("no valid frames found"));
      }

1268
1269
1270
1271
1272
1273
1274
1275
      /* Forward EOS immediately. This is required because no
       * buffer or serialized event will come after EOS and
       * nothing could trigger another _finish_frame() call.
       *
       * The subclass can override this behaviour by overriding
       * the ::sink_event() vfunc and not chaining up to the
       * parent class' ::sink_event() until a later time.
       */
1276
      forward_immediate = TRUE;
1277
1278
      break;
    }
Jan Schmidt's avatar
Jan Schmidt committed
1279
1280
1281
    case GST_EVENT_GAP:
    {
      GstFlowReturn flow_ret = GST_FLOW_OK;
1282
      gboolean needs_reconfigure = FALSE;
1283
1284
      GList *events;
      GList *frame_events;
Jan Schmidt's avatar
Jan Schmidt committed
1285
1286
1287

      flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
      ret = (flow_ret == GST_FLOW_OK);
1288

1289
1290
1291
1292
1293
1294
1295
      /* Ensure we have caps before forwarding the event */
      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      if (!decoder->priv->output_state) {
        if (!gst_video_decoder_negotiate_default_caps (decoder)) {
          GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
          GST_ELEMENT_ERROR (decoder, STREAM, FORMAT, (NULL),
              ("Decoder output not negotiated before GAP event."));
1296
1297
          forward_immediate = TRUE;
          break;
1298
        }
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
        needs_reconfigure = TRUE;
      }

      needs_reconfigure = gst_pad_check_reconfigure (decoder->srcpad)
          || needs_reconfigure;
      if (decoder->priv->output_state_changed || needs_reconfigure) {
        if (!gst_video_decoder_negotiate_unlocked (decoder)) {
          GST_WARNING_OBJECT (decoder, "Failed to negotiate with downstream");
          gst_pad_mark_reconfigure (decoder->srcpad);
        }
1309
      }
1310
1311
1312
1313
1314
1315
1316
1317

      GST_DEBUG_OBJECT (decoder, "Pushing all pending serialized events"
          " before the gap");
      events = decoder->priv->pending_events;
      frame_events = decoder->priv->current_frame_events;
      decoder->priv->pending_events = NULL;
      decoder->priv->current_frame_events = NULL;

1318
1319
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

1320
1321
1322
      gst_video_decoder_push_event_list (decoder, events);
      gst_video_decoder_push_event_list (decoder, frame_events);

1323
1324
1325
1326
      /* Forward GAP immediately. Everything is drained after
       * the GAP event and we can forward this event immediately
       * now without having buffers out of order.
       */
Jan Schmidt's avatar
Jan Schmidt committed
1327
1328
1329
      forward_immediate = TRUE;
      break;
    }
Jan Schmidt's avatar
Jan Schmidt committed
1330
    case GST_EVENT_CUSTOM_DOWNSTREAM:
1331
1332
1333
1334
1335
1336
    {
      gboolean in_still;
      GstFlowReturn flow_ret = GST_FLOW_OK;

      if (gst_video_event_parse_still_frame (event, &in_still)) {
        if (in_still) {
Jan Schmidt's avatar
Jan Schmidt committed
1337
          GST_DEBUG_OBJECT (decoder, "draining current data for still-frame");
1338
1339
1340
          flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
          ret = (flow_ret == GST_FLOW_OK);
        }
1341
1342
1343
1344
        /* Forward STILL_FRAME immediately. Everything is drained after
         * the STILL_FRAME event and we can forward this event immediately
         * now without having buffers out of order.
         */
Jan Schmidt's avatar
Jan Schmidt committed
1345
        forward_immediate = TRUE;
1346
      }
Jan Schmidt's avatar
Jan Schmidt committed
1347
      break;
1348
    }
1349
    case GST_EVENT_SEGMENT:
1350
    {
1351
      GstSegment segment;
1352

1353
1354
1355
      gst_event_copy_segment (event, &segment);

      if (segment.format == GST_FORMAT_TIME) {
1356
        GST_DEBUG_OBJECT (decoder,
1357
            "received TIME SEGMENT %" GST_SEGMENT_FORMAT, &segment);
1358
      } else {
1359
        gint64 start;
1360
1361

        GST_DEBUG_OBJECT (decoder,
1362
            "received SEGMENT %" GST_SEGMENT_FORMAT, &segment);
1363
1364
1365
1366

        /* handle newsegment as a result from our legacy simple seeking */
        /* note that initial 0 should convert to 0 in any case */
        if (priv->do_estimate_rate &&
1367
1368
            gst_pad_query_convert (decoder->sinkpad, GST_FORMAT_BYTES,
                segment.start, GST_FORMAT_TIME, &start)) {
1369
1370
1371
1372
1373
1374
          /* best attempt convert */
          /* as these are only estimates, stop is kept open-ended to avoid
           * premature cutting */
          GST_DEBUG_OBJECT (decoder,
              "converted to TIME start %" GST_TIME_FORMAT,
              GST_TIME_ARGS (start));
1375
1376
1377
          segment.start = start;
          segment.stop = GST_CLOCK_TIME_NONE;
          segment.time = start;
1378
1379
          /* replace event */
          gst_event_unref (event);
1380
          event = gst_event_new_segment (&segment);
1381
1382
1383
1384
1385
        } else {
          goto newseg_wrong_format;
        }
      }

1386
1387
      GST_VIDEO_DECODER_STREAM_LOCK (decoder);

1388
1389
      priv->base_timestamp = GST_CLOCK_TIME_NONE;
      priv->base_picture_number = 0;
1390

1391
      decoder->input_segment = segment;
1392
      decoder->priv->in_out_segment_sync = FALSE;
1393
1394
1395
1396
1397
1398

      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
    {
1399
1400
      GList *l;

1401
      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
1402
1403
1404
1405
1406
1407
1408
1409
      for (l = priv->frames; l; l = l->next) {
        GstVideoCodecFrame *frame = l->data;

        frame->events = _flush_events (decoder->srcpad, frame->events);
      }
      priv->current_frame_events = _flush_events (decoder->srcpad,
          decoder->priv->current_frame_events);

1410
1411
1412
      /* well, this is kind of worse than a DISCONT */
      gst_video_decoder_flush (decoder, TRUE);
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
1413
1414
1415
1416
      /* Forward FLUSH_STOP immediately. This is required because it is
       * expected to be forwarded immediately and no buffers are queued
       * anyway.
       */
1417
      forward_immediate = TRUE;
1418
      break;
1419
    }
1420
1421
1422
1423
1424
1425
1426
    case GST_EVENT_TAG:
    {
      GstTagList *tags;

      gst_event_parse_tag (event, &tags);

      if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM) {
1427
1428
1429
1430
1431
1432
1433
        GST_VIDEO_DECODER_STREAM_LOCK (decoder);
        if (priv->upstream_tags != tags) {
          if (priv->upstream_tags)
            gst_tag_list_unref (priv->upstream_tags);
          priv->upstream_tags = gst_tag_list_ref (tags);
          GST_INFO_OBJECT (decoder, "upstream tags: %" GST_PTR_FORMAT, tags);
        }
1434
        gst_event_unref (event);
1435
1436
        event = gst_video_decoder_create_merged_tags_event (decoder);
        GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
1437
1438
        if (!event)
          ret = TRUE;