gstbasesrc.c 88.1 KB
Newer Older
1
2
/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3
 *               2000,2005 Wim Taymans <wim@fluendo.com>
4
 *
5
 * gstbasesrc.c:
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * 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
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

23
24
25
/**
 * SECTION:gstbasesrc
 * @short_description: Base class for getrange based source elements
26
 * @see_also: #GstPushSrc, #GstBaseTransform, #GstBaseSink
27
 *
28
29
30
31
32
33
34
35
 * This is a generice base class for source elements. The following
 * types of sources are supported:
 * <itemizedlist>
 *   <listitem><para>random access sources like files</para></listitem>
 *   <listitem><para>seekable sources</para></listitem>
 *   <listitem><para>live sources</para></listitem>
 * </itemizedlist>
 *
36
 * The source can be configured to operate in any #GstFormat with the
Wim Taymans's avatar
Wim Taymans committed
37
38
 * gst_base_src_set_format() method. The currently set format determines
 * the format of the internal #GstSegment and any #GST_EVENT_NEWSEGMENT
39
 * events. The default format for #GstBaseSrc is #GST_FORMAT_BYTES.
40
 *
41
 * #GstBaseSrc always supports push mode scheduling. If the following
42
43
 * conditions are met, it also supports pull mode scheduling:
 * <itemizedlist>
44
 *   <listitem><para>The format is set to #GST_FORMAT_BYTES (default).</para>
45
 *   </listitem>
46
 *   <listitem><para>#GstBaseSrc::is_seekable returns %TRUE.</para>
47
 *   </listitem>
48
 * </itemizedlist>
Wim Taymans's avatar
Wim Taymans committed
49
50
51
52
 *
 * Since 0.10.9, any #GstBaseSrc can enable pull based scheduling at any
 * time by overriding #GstBaseSrc::check_get_range so that it returns %TRUE.
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
53
 * If all the conditions are met for operating in pull mode, #GstBaseSrc is
Wim Taymans's avatar
Wim Taymans committed
54
 * automatically seekable in push mode as well. The following conditions must
55
 * be met to make the element seekable in push mode when the format is not
56
 * #GST_FORMAT_BYTES:
57
 * <itemizedlist>
58
 *   <listitem><para>
59
 *     #GstBaseSrc::is_seekable returns %TRUE.
60
61
 *   </para></listitem>
 *   <listitem><para>
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
62
 *     #GstBaseSrc::query can convert all supported seek formats to the
63
64
65
 *     internal format as set with gst_base_src_set_format().
 *   </para></listitem>
 *   <listitem><para>
66
 *     #GstBaseSrc::do_seek is implemented, performs the seek and returns %TRUE.
67
 *   </para></listitem>
68
 * </itemizedlist>
Wim Taymans's avatar
Wim Taymans committed
69
 *
70
71
72
73
74
75
 * When the element does not meet the requirements to operate in pull mode,
 * the offset and length in the #GstBaseSrc::create method should be ignored.
 * It is recommended to subclass #GstPushSrc instead, in this situation. If the
 * element can operate in pull mode but only with specific offsets and
 * lengths, it is allowed to generate an error when the wrong values are passed
 * to the #GstBaseSrc::create function.
Wim Taymans's avatar
Wim Taymans committed
76
 *
77
78
79
80
 * #GstBaseSrc has support for live sources. Live sources are sources that when
 * paused discard data, such as audio or video capture devices. A typical live
 * source also produces data at a fixed rate and thus provides a clock to publish
 * this rate.
81
 * Use gst_base_src_set_live() to activate the live source mode.
Wim Taymans's avatar
Wim Taymans committed
82
83
 *
 * A live source does not produce data in the PAUSED state. This means that the
84
 * #GstBaseSrc::create method will not be called in PAUSED but only in PLAYING.
85
 * To signal the pipeline that the element will not produce data, the return
86
 * value from the READY to PAUSED state will be #GST_STATE_CHANGE_NO_PREROLL.
Wim Taymans's avatar
Wim Taymans committed
87
88
 *
 * A typical live source will timestamp the buffers it creates with the
89
 * current running time of the pipeline. This is one reason why a live source
Wim Taymans's avatar
Wim Taymans committed
90
91
92
 * can only produce data in the PLAYING state, when the clock is actually
 * distributed and running.
 *
93
 * Live sources that synchronize and block on the clock (an audio source, for
94
95
 * example) can since 0.10.12 use gst_base_src_wait_playing() when the ::create
 * function was interrupted by a state change to PAUSED.
Wim Taymans's avatar
Wim Taymans committed
96
97
 *
 * The #GstBaseSrc::get_times method can be used to implement pseudo-live
98
 * sources.
Wim Taymans's avatar
Wim Taymans committed
99
 * It only makes sense to implement the ::get_times function if the source is
100
101
102
103
104
 * a live source. The ::get_times function should return timestamps starting
 * from 0, as if it were a non-live source. The base class will make sure that
 * the timestamps are transformed into the current running_time.
 * The base source will then wait for the calculated running_time before pushing
 * out the buffer.
Wim Taymans's avatar
Wim Taymans committed
105
 *
106
107
108
 * For live sources, the base class will by default report a latency of 0.
 * For pseudo live sources, the base class will by default measure the difference
 * between the first buffer timestamp and the start time of get_times and will
Wim Taymans's avatar
Wim Taymans committed
109
 * report this value as the latency.
110
111
 * Subclasses should override the query function when this behaviour is not
 * acceptable.
Wim Taymans's avatar
Wim Taymans committed
112
113
114
 *
 * There is only support in #GstBaseSrc for exactly one source pad, which
 * should be named "src". A source implementation (subclass of #GstBaseSrc)
115
 * should install a pad template in its class_init function, like so:
116
117
 * <programlisting>
 * static void
118
 * my_element_class_init (GstMyElementClass *klass)
119
 * {
120
 *   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
121
122
123
124
125
126
127
128
 *   // srctemplate should be a #GstStaticPadTemplate with direction
 *   // #GST_PAD_SRC and name "src"
 *   gst_element_class_add_pad_template (gstelement_class,
 *       gst_static_pad_template_get (&amp;srctemplate));
 *   // see #GstElementDetails
 *   gst_element_class_set_details (gstelement_class, &amp;details);
 * }
 * </programlisting>
129
130
 *
 * <refsect2>
131
132
133
134
 * <title>Controlled shutdown of live sources in applications</title>
 * <para>
 * Applications that record from a live source may want to stop recording
 * in a controlled way, so that the recording is stopped, but the data
135
 * already in the pipeline is processed to the end (remember that many live
136
137
138
139
140
 * sources would go on recording forever otherwise). For that to happen the
 * application needs to make the source stop recording and send an EOS
 * event down the pipeline. The application would then wait for an
 * EOS message posted on the pipeline's bus to know when all data has
 * been processed and the pipeline can safely be stopped.
Wim Taymans's avatar
Wim Taymans committed
141
 *
142
 * Since GStreamer 0.10.16 an application may send an EOS event to a source
143
144
 * element to make it perform the EOS logic (send EOS event downstream or post a
 * #GST_MESSAGE_SEGMENT_DONE on the bus). This can typically be done
145
 * with the gst_element_send_event() function on the element or its parent bin.
Wim Taymans's avatar
Wim Taymans committed
146
 *
147
148
149
 * After the EOS has been sent to the element, the application should wait for
 * an EOS message to be posted on the pipeline's bus. Once this EOS message is
 * received, it may safely shut down the entire pipeline.
Wim Taymans's avatar
Wim Taymans committed
150
 *
151
152
 * The old behaviour for controlled shutdown introduced since GStreamer 0.10.3
 * is still available but deprecated as it is dangerous and less flexible.
Wim Taymans's avatar
Wim Taymans committed
153
 *
154
 * Last reviewed on 2007-12-19 (0.10.16)
155
156
 * </para>
 * </refsect2>
157
 */
158
159
160
161
162

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

163
164
165
#include <stdlib.h>
#include <string.h>

166
#include "gstbasesrc.h"
Wim Taymans's avatar
Wim Taymans committed
167
#include "gsttypefindhelper.h"
168
#include <gst/gstmarshal.h>
169
#include <gst/gst-i18n-lib.h>
170

171
172
GST_DEBUG_CATEGORY_STATIC (gst_base_src_debug);
#define GST_CAT_DEFAULT gst_base_src_debug
173

174
175
176
177
178
179
180
#define GST_LIVE_GET_LOCK(elem)               (GST_BASE_SRC_CAST(elem)->live_lock)
#define GST_LIVE_LOCK(elem)                   g_mutex_lock(GST_LIVE_GET_LOCK(elem))
#define GST_LIVE_TRYLOCK(elem)                g_mutex_trylock(GST_LIVE_GET_LOCK(elem))
#define GST_LIVE_UNLOCK(elem)                 g_mutex_unlock(GST_LIVE_GET_LOCK(elem))
#define GST_LIVE_GET_COND(elem)               (GST_BASE_SRC_CAST(elem)->live_cond)
#define GST_LIVE_WAIT(elem)                   g_cond_wait (GST_LIVE_GET_COND (elem), GST_LIVE_GET_LOCK (elem))
#define GST_LIVE_TIMED_WAIT(elem, timeval)    g_cond_timed_wait (GST_LIVE_GET_COND (elem), GST_LIVE_GET_LOCK (elem),\
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
181
                                                                                timeval)
182
183
184
#define GST_LIVE_SIGNAL(elem)                 g_cond_signal (GST_LIVE_GET_COND (elem));
#define GST_LIVE_BROADCAST(elem)              g_cond_broadcast (GST_LIVE_GET_COND (elem));

185
186
187
188
189
190
191
/* BaseSrc signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

192
193
#define DEFAULT_BLOCKSIZE       4096
#define DEFAULT_NUM_BUFFERS     -1
Wim Taymans's avatar
Wim Taymans committed
194
195
#define DEFAULT_TYPEFIND        FALSE
#define DEFAULT_DO_TIMESTAMP    FALSE
196

197
198
enum
{
199
200
  PROP_0,
  PROP_BLOCKSIZE,
201
  PROP_NUM_BUFFERS,
202
  PROP_TYPEFIND,
203
  PROP_DO_TIMESTAMP
204
205
};

206
207
208
209
210
211
212
#define GST_BASE_SRC_GET_PRIVATE(obj)  \
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_SRC, GstBaseSrcPrivate))

struct _GstBaseSrcPrivate
{
  gboolean last_sent_eos;       /* last thing we did was send an EOS (we set this
                                 * to avoid the sending of two EOS in some cases) */
213
  gboolean discont;
214
  gboolean flushing;
215
216
217
218

  /* two segments to be sent in the streaming thread with STREAM_LOCK */
  GstEvent *close_segment;
  GstEvent *start_segment;
219

220
221
  /* if EOS is pending (atomic) */
  gint pending_eos;
222

223
224
225
  /* startup latency is the time it takes between going to PLAYING and producing
   * the first BUFFER with running_time 0. This value is included in the latency
   * reporting. */
226
227
228
229
  GstClockTime latency;
  /* timestamp offset, this is the offset add to the values of gst_times for
   * pseudo live sources */
  GstClockTimeDiff ts_offset;
230
231

  gboolean do_timestamp;
232
233
234

  /* stream sequence number */
  guint32 seqnum;
235
236
237

  /* pending tags to be pushed in the data stream */
  GList *pending_tags;
238
239
};

240
241
static GstElementClass *parent_class = NULL;

242
static void gst_base_src_base_init (gpointer g_class);
243
244
static void gst_base_src_class_init (GstBaseSrcClass * klass);
static void gst_base_src_init (GstBaseSrc * src, gpointer g_class);
245
246
static void gst_base_src_finalize (GObject * object);

247
248

GType
249
gst_base_src_get_type (void)
250
{
251
  static volatile gsize base_src_type = 0;
252

253
254
  if (g_once_init_enter (&base_src_type)) {
    GType _type;
255
    static const GTypeInfo base_src_info = {
256
      sizeof (GstBaseSrcClass),
257
      (GBaseInitFunc) gst_base_src_base_init,
258
      NULL,
259
      (GClassInitFunc) gst_base_src_class_init,
260
261
262
263
      NULL,
      NULL,
      sizeof (GstBaseSrc),
      0,
264
      (GInstanceInitFunc) gst_base_src_init,
265
266
    };

267
    _type = g_type_register_static (GST_TYPE_ELEMENT,
268
        "GstBaseSrc", &base_src_info, G_TYPE_FLAG_ABSTRACT);
269
    g_once_init_leave (&base_src_type, _type);
270
  }
271
  return base_src_type;
272
}
273

274
275
static GstCaps *gst_base_src_getcaps (GstPad * pad);
static gboolean gst_base_src_setcaps (GstPad * pad, GstCaps * caps);
276
static void gst_base_src_fixate (GstPad * pad, GstCaps * caps);
277

278
279
280
static gboolean gst_base_src_activate_push (GstPad * pad, gboolean active);
static gboolean gst_base_src_activate_pull (GstPad * pad, gboolean active);
static void gst_base_src_set_property (GObject * object, guint prop_id,
281
    const GValue * value, GParamSpec * pspec);
282
static void gst_base_src_get_property (GObject * object, guint prop_id,
283
    GValue * value, GParamSpec * pspec);
284
static gboolean gst_base_src_event_handler (GstPad * pad, GstEvent * event);
285
static gboolean gst_base_src_send_event (GstElement * elem, GstEvent * event);
286
static gboolean gst_base_src_default_event (GstBaseSrc * src, GstEvent * event);
287
static const GstQueryType *gst_base_src_get_query_types (GstElement * element);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
288

289
static gboolean gst_base_src_query (GstPad * pad, GstQuery * query);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
290

291
static gboolean gst_base_src_default_negotiate (GstBaseSrc * basesrc);
292
293
294
static gboolean gst_base_src_default_do_seek (GstBaseSrc * src,
    GstSegment * segment);
static gboolean gst_base_src_default_query (GstBaseSrc * src, GstQuery * query);
295
296
static gboolean gst_base_src_default_prepare_seek_segment (GstBaseSrc * src,
    GstEvent * event, GstSegment * segment);
297

298
static gboolean gst_base_src_set_flushing (GstBaseSrc * basesrc,
299
    gboolean flushing, gboolean live_play, gboolean unlock, gboolean * playing);
300
301
static gboolean gst_base_src_start (GstBaseSrc * basesrc);
static gboolean gst_base_src_stop (GstBaseSrc * basesrc);
302

303
304
static GstStateChangeReturn gst_base_src_change_state (GstElement * element,
    GstStateChange transition);
305

306
static void gst_base_src_loop (GstPad * pad);
307
308
static gboolean gst_base_src_pad_check_get_range (GstPad * pad);
static gboolean gst_base_src_default_check_get_range (GstBaseSrc * bsrc);
309
310
311
static GstFlowReturn gst_base_src_pad_get_range (GstPad * pad, guint64 offset,
    guint length, GstBuffer ** buf);
static GstFlowReturn gst_base_src_get_range (GstBaseSrc * src, guint64 offset,
312
    guint length, GstBuffer ** buf);
313
static gboolean gst_base_src_seekable (GstBaseSrc * src);
314

315
316
317
318
319
320
static void
gst_base_src_base_init (gpointer g_class)
{
  GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
}

321
static void
322
gst_base_src_class_init (GstBaseSrcClass * klass)
323
324
325
326
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

327
328
  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
329

330
331
  g_type_class_add_private (klass, sizeof (GstBaseSrcPrivate));

332
  parent_class = g_type_class_peek_parent (klass);
333

334
  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_base_src_finalize);
335
336
  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_base_src_set_property);
  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_base_src_get_property);
337

338
  g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
339
      g_param_spec_ulong ("blocksize", "Block size",
340
          "Size in bytes to read per buffer (-1 = default)", 0, G_MAXULONG,
341
          DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
342
  g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
343
      g_param_spec_int ("num-buffers", "num-buffers",
344
345
346
          "Number of buffers to output before sending EOS (-1 = unlimited)",
          -1, G_MAXINT, DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE |
          G_PARAM_STATIC_STRINGS));
347
  g_object_class_install_property (gobject_class, PROP_TYPEFIND,
348
349
      g_param_spec_boolean ("typefind", "Typefind",
          "Run typefind before negotiating", DEFAULT_TYPEFIND,
350
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
351
352
353
  g_object_class_install_property (gobject_class, PROP_DO_TIMESTAMP,
      g_param_spec_boolean ("do-timestamp", "Do timestamp",
          "Apply current stream time to buffers", DEFAULT_DO_TIMESTAMP,
354
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
355

356
357
  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_base_src_change_state);
358
  gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_base_src_send_event);
359
360
  gstelement_class->get_query_types =
      GST_DEBUG_FUNCPTR (gst_base_src_get_query_types);
361

362
363
364
365
  klass->negotiate = GST_DEBUG_FUNCPTR (gst_base_src_default_negotiate);
  klass->event = GST_DEBUG_FUNCPTR (gst_base_src_default_event);
  klass->do_seek = GST_DEBUG_FUNCPTR (gst_base_src_default_do_seek);
  klass->query = GST_DEBUG_FUNCPTR (gst_base_src_default_query);
366
367
  klass->check_get_range =
      GST_DEBUG_FUNCPTR (gst_base_src_default_check_get_range);
368
369
  klass->prepare_seek_segment =
      GST_DEBUG_FUNCPTR (gst_base_src_default_prepare_seek_segment);
370
371
372
}

static void
373
gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
374
375
376
377
{
  GstPad *pad;
  GstPadTemplate *pad_template;

378
379
  basesrc->priv = GST_BASE_SRC_GET_PRIVATE (basesrc);

380
381
382
  basesrc->is_live = FALSE;
  basesrc->live_lock = g_mutex_new ();
  basesrc->live_cond = g_cond_new ();
383
384
  basesrc->num_buffers = DEFAULT_NUM_BUFFERS;
  basesrc->num_buffers_left = -1;
385

386
387
388
  basesrc->can_activate_push = TRUE;
  basesrc->pad_mode = GST_ACTIVATE_NONE;

389
390
391
392
  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
  g_return_if_fail (pad_template != NULL);

393
  GST_DEBUG_OBJECT (basesrc, "creating src pad");
394
395
  pad = gst_pad_new_from_template (pad_template, "src");

396
  GST_DEBUG_OBJECT (basesrc, "setting functions on src pad");
397
398
399
400
401
402
403
404
  gst_pad_set_activatepush_function (pad,
      GST_DEBUG_FUNCPTR (gst_base_src_activate_push));
  gst_pad_set_activatepull_function (pad,
      GST_DEBUG_FUNCPTR (gst_base_src_activate_pull));
  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_base_src_event_handler));
  gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_query));
  gst_pad_set_checkgetrange_function (pad,
405
      GST_DEBUG_FUNCPTR (gst_base_src_pad_check_get_range));
406
  gst_pad_set_getrange_function (pad,
407
      GST_DEBUG_FUNCPTR (gst_base_src_pad_get_range));
408
409
  gst_pad_set_getcaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_getcaps));
  gst_pad_set_setcaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_setcaps));
410
411
  gst_pad_set_fixatecaps_function (pad,
      GST_DEBUG_FUNCPTR (gst_base_src_fixate));
412

413
  /* hold pointer to pad */
414
  basesrc->srcpad = pad;
415
  GST_DEBUG_OBJECT (basesrc, "adding src pad");
416
417
418
  gst_element_add_pad (GST_ELEMENT (basesrc), pad);

  basesrc->blocksize = DEFAULT_BLOCKSIZE;
Wim Taymans's avatar
Wim Taymans committed
419
  basesrc->clock_id = NULL;
420
421
  /* we operate in BYTES by default */
  gst_base_src_set_format (basesrc, GST_FORMAT_BYTES);
422
  basesrc->data.ABI.typefind = DEFAULT_TYPEFIND;
423
  basesrc->priv->do_timestamp = DEFAULT_DO_TIMESTAMP;
424

425
  GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
426
427

  GST_DEBUG_OBJECT (basesrc, "init done");
428
429
}

430
431
432
433
static void
gst_base_src_finalize (GObject * object)
{
  GstBaseSrc *basesrc;
434
  GstEvent **event_p;
435
436
437
438
439

  basesrc = GST_BASE_SRC (object);

  g_mutex_free (basesrc->live_lock);
  g_cond_free (basesrc->live_cond);
440
441

  event_p = &basesrc->data.ABI.pending_seek;
442
  gst_event_replace (event_p, NULL);
443

444
445
446
447
448
  if (basesrc->priv->pending_tags) {
    g_list_foreach (basesrc->priv->pending_tags, (GFunc) gst_event_unref, NULL);
    g_list_free (basesrc->priv->pending_tags);
  }

449
450
451
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
/**
 * gst_base_src_wait_playing:
 * @src: the src
 *
 * If the #GstBaseSrcClass::create method performs its own synchronisation against
 * the clock it must unblock when going from PLAYING to the PAUSED state and call
 * this method before continuing to produce the remaining data.
 *
 * This function will block until a state change to PLAYING happens (in which
 * case this function returns #GST_FLOW_OK) or the processing must be stopped due
 * to a state change to READY or a FLUSH event (in which case this function
 * returns #GST_FLOW_WRONG_STATE).
 *
 * Since: 0.10.12
 *
 * Returns: #GST_FLOW_OK if @src is PLAYING and processing can
 * continue. Any other return value should be returned from the create vmethod.
 */
GstFlowReturn
gst_base_src_wait_playing (GstBaseSrc * src)
{
473
474
  g_return_val_if_fail (GST_IS_BASE_SRC (src), GST_FLOW_ERROR);

475
  /* block until the state changes, or we get a flush, or something */
476
477
478
479
480
  GST_DEBUG_OBJECT (src, "live source waiting for running state");
  GST_LIVE_WAIT (src);
  if (src->priv->flushing)
    goto flushing;
  GST_DEBUG_OBJECT (src, "live source unlocked");
481
482
483
484
485
486

  return GST_FLOW_OK;

  /* ERRORS */
flushing:
  {
487
    GST_DEBUG_OBJECT (src, "we are flushing");
488
489
490
491
    return GST_FLOW_WRONG_STATE;
  }
}

492
493
494
495
496
/**
 * gst_base_src_set_live:
 * @src: base source instance
 * @live: new live-mode
 *
497
 * If the element listens to a live source, @live should
Wim Taymans's avatar
Wim Taymans committed
498
 * be set to %TRUE.
499
500
501
 *
 * A live source will not produce data in the PAUSED state and
 * will therefore not be able to participate in the PREROLL phase
Wim Taymans's avatar
Wim Taymans committed
502
 * of a pipeline. To signal this fact to the application and the
503
504
 * pipeline, the state change return value of the live source will
 * be GST_STATE_CHANGE_NO_PREROLL.
505
 */
506
void
507
gst_base_src_set_live (GstBaseSrc * src, gboolean live)
508
{
509
510
  g_return_if_fail (GST_IS_BASE_SRC (src));

511
  GST_OBJECT_LOCK (src);
512
  src->is_live = live;
513
  GST_OBJECT_UNLOCK (src);
514
515
}

516
/**
517
 * gst_base_src_is_live:
518
519
520
521
522
523
 * @src: base source instance
 *
 * Check if an element is in live mode.
 *
 * Returns: %TRUE if element is in live mode.
 */
524
gboolean
525
gst_base_src_is_live (GstBaseSrc * src)
526
527
528
{
  gboolean result;

529
530
  g_return_val_if_fail (GST_IS_BASE_SRC (src), FALSE);

531
  GST_OBJECT_LOCK (src);
532
  result = src->is_live;
533
  GST_OBJECT_UNLOCK (src);
534
535
536
537

  return result;
}

538
539
540
541
542
543
544
545
546
547
/**
 * gst_base_src_set_format:
 * @src: base source instance
 * @format: the format to use
 *
 * Sets the default format of the source. This will be the format used
 * for sending NEW_SEGMENT events and for performing seeks.
 *
 * If a format of GST_FORMAT_BYTES is set, the element will be able to
 * operate in pull mode if the #GstBaseSrc::is_seekable returns TRUE.
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
548
 *
549
 * Since: 0.10.1
550
551
552
553
 */
void
gst_base_src_set_format (GstBaseSrc * src, GstFormat format)
{
554
555
  g_return_if_fail (GST_IS_BASE_SRC (src));

556
557
558
  gst_segment_init (&src->segment, format);
}

559
560
561
562
563
564
565
566
/**
 * gst_base_src_query_latency:
 * @src: the source
 * @live: if the source is live
 * @min_latency: the min latency of the source
 * @max_latency: the max latency of the source
 *
 * Query the source for the latency parameters. @live will be TRUE when @src is
567
568
 * configured as a live source. @min_latency will be set to the difference
 * between the running time and the timestamp of the first buffer.
569
570
 * @max_latency is always the undefined value of -1.
 *
Wim Taymans's avatar
Wim Taymans committed
571
 * This function is mostly used by subclasses.
572
573
574
575
576
577
578
579
580
 *
 * Returns: TRUE if the query succeeded.
 *
 * Since: 0.10.13
 */
gboolean
gst_base_src_query_latency (GstBaseSrc * src, gboolean * live,
    GstClockTime * min_latency, GstClockTime * max_latency)
{
581
582
  GstClockTime min;

583
584
  g_return_val_if_fail (GST_IS_BASE_SRC (src), FALSE);

585
  GST_OBJECT_LOCK (src);
586
587
  if (live)
    *live = src->is_live;
588
589
590
591

  /* if we have a startup latency, report this one, else report 0. Subclasses
   * are supposed to override the query function if they want something
   * else. */
592
593
  if (src->priv->latency != -1)
    min = src->priv->latency;
594
595
596
  else
    min = 0;

597
  if (min_latency)
598
    *min_latency = min;
599
600
  if (max_latency)
    *max_latency = -1;
601
602
603
604

  GST_LOG_OBJECT (src, "latency: live %d, min %" GST_TIME_FORMAT
      ", max %" GST_TIME_FORMAT, src->is_live, GST_TIME_ARGS (min),
      GST_TIME_ARGS (-1));
605
  GST_OBJECT_UNLOCK (src);
606
607
608
609

  return TRUE;
}

610
611
612
613
614
/**
 * gst_base_src_set_blocksize:
 * @src: the source
 * @blocksize: the new blocksize in bytes
 *
615
616
 * Set the number of bytes that @src will push out with each buffer. When
 * @blocksize is set to -1, a default length will be used.
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
648
649
650
651
652
653
654
 *
 * Since: 0.10.22
 */
void
gst_base_src_set_blocksize (GstBaseSrc * src, gulong blocksize)
{
  g_return_if_fail (GST_IS_BASE_SRC (src));

  GST_OBJECT_LOCK (src);
  src->blocksize = blocksize;
  GST_OBJECT_UNLOCK (src);
}

/**
 * gst_base_src_get_blocksize:
 * @src: the source
 *
 * Get the number of bytes that @src will push out with each buffer.
 *
 * Returns: the number of bytes pushed with each buffer.
 *
 * Since: 0.10.22
 */
gulong
gst_base_src_get_blocksize (GstBaseSrc * src)
{
  gulong res;

  g_return_val_if_fail (GST_IS_BASE_SRC (src), 0);

  GST_OBJECT_LOCK (src);
  res = src->blocksize;
  GST_OBJECT_UNLOCK (src);

  return res;
}


655
656
657
658
659
660
661
662
663
664
665
666
667
668
/**
 * gst_base_src_set_do_timestamp:
 * @src: the source
 * @timestamp: enable or disable timestamping
 *
 * Configure @src to automatically timestamp outgoing buffers based on the
 * current running_time of the pipeline. This property is mostly useful for live
 * sources.
 *
 * Since: 0.10.15
 */
void
gst_base_src_set_do_timestamp (GstBaseSrc * src, gboolean timestamp)
{
669
670
  g_return_if_fail (GST_IS_BASE_SRC (src));

671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  GST_OBJECT_LOCK (src);
  src->priv->do_timestamp = timestamp;
  GST_OBJECT_UNLOCK (src);
}

/**
 * gst_base_src_get_do_timestamp:
 * @src: the source
 *
 * Query if @src timestamps outgoing buffers based on the current running_time.
 *
 * Returns: %TRUE if the base class will automatically timestamp outgoing buffers.
 *
 * Since: 0.10.15
 */
gboolean
gst_base_src_get_do_timestamp (GstBaseSrc * src)
{
  gboolean res;

691
692
  g_return_val_if_fail (GST_IS_BASE_SRC (src), FALSE);

693
694
695
696
697
698
699
  GST_OBJECT_LOCK (src);
  res = src->priv->do_timestamp;
  GST_OBJECT_UNLOCK (src);

  return res;
}

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
734
735
736
737
738
739
static gboolean
gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
{
  GstBaseSrcClass *bclass;
  GstBaseSrc *bsrc;
  gboolean res = TRUE;

  bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
  bclass = GST_BASE_SRC_GET_CLASS (bsrc);

  if (bclass->set_caps)
    res = bclass->set_caps (bsrc, caps);

  return res;
}

static GstCaps *
gst_base_src_getcaps (GstPad * pad)
{
  GstBaseSrcClass *bclass;
  GstBaseSrc *bsrc;
  GstCaps *caps = NULL;

  bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
  bclass = GST_BASE_SRC_GET_CLASS (bsrc);
  if (bclass->get_caps)
    caps = bclass->get_caps (bsrc);

  if (caps == NULL) {
    GstPadTemplate *pad_template;

    pad_template =
        gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
    if (pad_template != NULL) {
      caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
    }
  }
  return caps;
}

740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
static void
gst_base_src_fixate (GstPad * pad, GstCaps * caps)
{
  GstBaseSrcClass *bclass;
  GstBaseSrc *bsrc;

  bsrc = GST_BASE_SRC (gst_pad_get_parent (pad));
  bclass = GST_BASE_SRC_GET_CLASS (bsrc);

  if (bclass->fixate)
    bclass->fixate (bsrc, caps);

  gst_object_unref (bsrc);
}

755
static gboolean
756
gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
757
{
758
  gboolean res;
759

Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
760
  switch (GST_QUERY_TYPE (query)) {
761
    case GST_QUERY_POSITION:
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
762
763
764
    {
      GstFormat format;

Wim Taymans's avatar
Wim Taymans committed
765
      gst_query_parse_position (query, &format, NULL);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
766
      switch (format) {
767
        case GST_FORMAT_PERCENT:
768
        {
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
          gint64 percent;
          gint64 position;
          gint64 duration;

          position = src->segment.last_stop;
          duration = src->segment.duration;

          if (position != -1 && duration != -1) {
            if (position < duration)
              percent = gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX, position,
                  duration);
            else
              percent = GST_FORMAT_PERCENT_MAX;
          } else
            percent = -1;

          gst_query_set_position (query, GST_FORMAT_PERCENT, percent);
786
787
788
          res = TRUE;
          break;
        }
Wim Taymans's avatar
Wim Taymans committed
789
        default:
790
791
792
793
794
795
796
797
798
799
800
801
802
803
        {
          gint64 position;

          position = src->segment.last_stop;

          if (position != -1) {
            /* convert to requested format */
            res =
                gst_pad_query_convert (src->srcpad, src->segment.format,
                position, &format, &position);
          } else
            res = TRUE;

          gst_query_set_position (query, format, position);
804
          break;
805
        }
Wim Taymans's avatar
Wim Taymans committed
806
      }
807
      break;
Wim Taymans's avatar
Wim Taymans committed
808
809
810
811
812
813
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;

      gst_query_parse_duration (query, &format, NULL);
Wim Taymans's avatar
Wim Taymans committed
814
815
816

      GST_DEBUG_OBJECT (src, "duration query in format %s",
          gst_format_get_name (format));
817

Wim Taymans's avatar
Wim Taymans committed
818
819
820
821
      switch (format) {
        case GST_FORMAT_PERCENT:
          gst_query_set_duration (query, GST_FORMAT_PERCENT,
              GST_FORMAT_PERCENT_MAX);
822
823
          res = TRUE;
          break;
824
        default:
825
826
827
        {
          gint64 duration;

828
          /* this is the duration as configured by the subclass. */
829
830
831
          duration = src->segment.duration;

          if (duration != -1) {
832
833
            /* convert to requested format, if this fails, we have a duration
             * but we cannot answer the query, we must return FALSE. */
834
835
836
837
            res =
                gst_pad_query_convert (src->srcpad, src->segment.format,
                duration, &format, &duration);
          } else {
838
839
840
841
            /* The subclass did not configure a duration, we assume that the
             * media has an unknown duration then and we return TRUE to report
             * this. Note that this is not the same as returning FALSE, which
             * means that we cannot report the duration at all. */
842
843
844
            res = TRUE;
          }
          gst_query_set_duration (query, format, duration);
845
          break;
846
        }
847
      }
848
      break;
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
849
850
851
    }

    case GST_QUERY_SEEKING:
852
    {
853
854
855
856
857
858
      GstFormat format;

      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      if (format == src->segment.format) {
        gst_query_set_seeking (query, src->segment.format,
            gst_base_src_seekable (src), 0, src->segment.duration);
859
        res = TRUE;
860
      } else {
861
862
863
864
865
        /* FIXME 0.11: return TRUE + seekable=FALSE for SEEKING query here */
        /* Don't reply to the query to make up for demuxers which don't
         * handle the SEEKING query yet. Players like Totem will fall back
         * to the duration when the SEEKING query isn't answered. */
        res = FALSE;
866
      }
867
      break;
868
    }
869
870
871
872
    case GST_QUERY_SEGMENT:
    {
      gint64 start, stop;

873
      /* no end segment configured, current duration then */
874
      if ((stop = src->segment.stop) == -1)
875
876
        stop = src->segment.duration;
      start = src->segment.start;
877

878
879
880
881
882
883
884
885
      /* adjust to stream time */
      if (src->segment.time != -1) {
        start -= src->segment.time;
        if (stop != -1)
          stop -= src->segment.time;
      }
      gst_query_set_segment (query, src->segment.rate, src->segment.format,
          start, stop);
886
887
888
889
      res = TRUE;
      break;
    }

Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
890
    case GST_QUERY_FORMATS:
891
    {
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
892
893
      gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
          GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
894
895
      res = TRUE;
      break;
896
    }
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
897
    case GST_QUERY_CONVERT:
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);

      /* we can only convert between equal formats... */
      if (src_fmt == dest_fmt) {
        dest_val = src_val;
        res = TRUE;
      } else
        res = FALSE;

      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
914
    case GST_QUERY_LATENCY:
915
916
917
918
919
920
921
    {
      GstClockTime min, max;
      gboolean live;

      /* Subclasses should override and implement something usefull */
      res = gst_base_src_query_latency (src, &live, &min, &max);

922
923
924
925
      GST_LOG_OBJECT (src, "report latency: live %d, min %" GST_TIME_FORMAT
          ", max %" GST_TIME_FORMAT, live, GST_TIME_ARGS (min),
          GST_TIME_ARGS (max));

926
      gst_query_set_latency (query, live, min, max);
927
      break;
928
    }
929
930
    case GST_QUERY_JITTER:
    case GST_QUERY_RATE:
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
      res = FALSE;
      break;
    case GST_QUERY_BUFFERING:
    {
      GstFormat format;
      gint64 start, stop, estimated;

      gst_query_parse_buffering_range (query, &format, NULL, NULL, NULL);

      GST_DEBUG_OBJECT (src, "buffering query in format %s",
          gst_format_get_name (format));

      if (src->random_access) {
        estimated = 0;
        start = 0;
        if (format == GST_FORMAT_PERCENT)
          stop = GST_FORMAT_PERCENT_MAX;
        else
          stop = src->segment.duration;
      } else {
        estimated = -1;
        start = -1;
        stop = -1;
      }
      /* convert to required format. When the conversion fails, we can't answer
       * the query. When the value is unknown, we can don't perform conversion
       * but report TRUE. */
      if (format != GST_FORMAT_PERCENT && stop != -1) {
        res = gst_pad_query_convert (src->srcpad, src->segment.format,
            stop, &format, &stop);
      } else {
        res = TRUE;
      }
      if (res && format != GST_FORMAT_PERCENT && start != -1)
        res = gst_pad_query_convert (src->srcpad, src->segment.format,
            start, &format, &start);

      gst_query_set_buffering_range (query, format, start, stop, estimated);
      break;
    }
971
    default:
972
      res = FALSE;
973
      break;
974
  }
Wim Taymans's avatar
Wim Taymans committed
975
976
  GST_DEBUG_OBJECT (src, "query %s returns %d", GST_QUERY_TYPE_NAME (query),
      res);
977
  return res;
978
979
}

980
static gboolean
981
gst_base_src_query (GstPad * pad, GstQuery * query)
982
{
983
  GstBaseSrc *src;
984
985
986
  GstBaseSrcClass *bclass;
  gboolean result = FALSE;

987
988
  src = GST_BASE_SRC (gst_pad_get_parent (pad));

989
990
  bclass = GST_BASE_SRC_GET_CLASS (src);

991
992
993
994
995
996
  if (bclass->query)
    result = bclass->query (src, query);
  else
    result = gst_pad_query_default (pad, query);

  gst_object_unref (src);
997
998
999
1000

  return result;
}

For faster browsing, not all history is shown. View entire blame