mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 21:51:09 +00:00
Merge branch 'master' into 0.11
Conflicts: gst-libs/gst/audio/gstaudioencoder.c gst-libs/gst/pbutils/gstdiscoverer.c
This commit is contained in:
commit
e44dd9db8f
6 changed files with 303 additions and 14 deletions
|
@ -177,6 +177,8 @@ enum
|
||||||
#define DEFAULT_LATENCY 0
|
#define DEFAULT_LATENCY 0
|
||||||
#define DEFAULT_TOLERANCE 0
|
#define DEFAULT_TOLERANCE 0
|
||||||
#define DEFAULT_PLC FALSE
|
#define DEFAULT_PLC FALSE
|
||||||
|
#define DEFAULT_DRAINABLE TRUE
|
||||||
|
#define DEFAULT_NEEDS_FORMAT FALSE
|
||||||
|
|
||||||
typedef struct _GstAudioDecoderContext
|
typedef struct _GstAudioDecoderContext
|
||||||
{
|
{
|
||||||
|
@ -258,6 +260,8 @@ struct _GstAudioDecoderPrivate
|
||||||
GstClockTime latency;
|
GstClockTime latency;
|
||||||
GstClockTime tolerance;
|
GstClockTime tolerance;
|
||||||
gboolean plc;
|
gboolean plc;
|
||||||
|
gboolean drainable;
|
||||||
|
gboolean needs_format;
|
||||||
|
|
||||||
/* pending serialized sink events, will be sent from finish_frame() */
|
/* pending serialized sink events, will be sent from finish_frame() */
|
||||||
GList *pending_events;
|
GList *pending_events;
|
||||||
|
@ -420,6 +424,8 @@ gst_audio_decoder_init (GstAudioDecoder * dec, GstAudioDecoderClass * klass)
|
||||||
dec->priv->latency = DEFAULT_LATENCY;
|
dec->priv->latency = DEFAULT_LATENCY;
|
||||||
dec->priv->tolerance = DEFAULT_TOLERANCE;
|
dec->priv->tolerance = DEFAULT_TOLERANCE;
|
||||||
dec->priv->plc = DEFAULT_PLC;
|
dec->priv->plc = DEFAULT_PLC;
|
||||||
|
dec->priv->drainable = DEFAULT_DRAINABLE;
|
||||||
|
dec->priv->needs_format = DEFAULT_NEEDS_FORMAT;
|
||||||
|
|
||||||
/* init state */
|
/* init state */
|
||||||
gst_audio_decoder_reset (dec, TRUE);
|
gst_audio_decoder_reset (dec, TRUE);
|
||||||
|
@ -1049,6 +1055,7 @@ gst_audio_decoder_push_buffers (GstAudioDecoder * dec, gboolean force)
|
||||||
break;
|
break;
|
||||||
} else if (ret == GST_FLOW_OK) {
|
} else if (ret == GST_FLOW_OK) {
|
||||||
GST_LOG_OBJECT (dec, "frame at offset %d of length %d", offset, len);
|
GST_LOG_OBJECT (dec, "frame at offset %d of length %d", offset, len);
|
||||||
|
g_assert (len);
|
||||||
g_assert (offset + len <= av);
|
g_assert (offset + len <= av);
|
||||||
priv->sync_flush = 0;
|
priv->sync_flush = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1072,6 +1079,10 @@ gst_audio_decoder_push_buffers (GstAudioDecoder * dec, gboolean force)
|
||||||
} else {
|
} else {
|
||||||
if (!force)
|
if (!force)
|
||||||
break;
|
break;
|
||||||
|
if (!priv->drainable) {
|
||||||
|
priv->drained = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1392,6 +1403,9 @@ gst_audio_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
||||||
|
|
||||||
dec = GST_AUDIO_DECODER (parent);
|
dec = GST_AUDIO_DECODER (parent);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!gst_pad_has_current_caps (pad) && dec->priv->needs_format))
|
||||||
|
goto not_negotiated;
|
||||||
|
|
||||||
GST_LOG_OBJECT (dec,
|
GST_LOG_OBJECT (dec,
|
||||||
"received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
|
"received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
|
||||||
", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
|
", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
|
||||||
|
@ -1429,6 +1443,15 @@ gst_audio_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
||||||
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
|
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
not_negotiated:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
|
||||||
|
("decoder not initialized"));
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* perform upstream byte <-> time conversion (duration, seeking)
|
/* perform upstream byte <-> time conversion (duration, seeking)
|
||||||
|
@ -2476,3 +2499,105 @@ gst_audio_decoder_get_tolerance (GstAudioDecoder * dec)
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_audio_decoder_set_drainable:
|
||||||
|
* @enc: a #GstAudioDecoder
|
||||||
|
* @enabled: new state
|
||||||
|
*
|
||||||
|
* Configures decoder drain handling. If drainable, subclass might
|
||||||
|
* be handed a NULL buffer to have it return any leftover decoded data.
|
||||||
|
* Otherwise, it is not considered so capable and will only ever be passed
|
||||||
|
* real data.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_audio_decoder_set_drainable (GstAudioDecoder * dec, gboolean enabled)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (dec);
|
||||||
|
dec->priv->drainable = enabled;
|
||||||
|
GST_OBJECT_UNLOCK (dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_audio_decoder_get_drainable:
|
||||||
|
* @enc: a #GstAudioDecoder
|
||||||
|
*
|
||||||
|
* Queries decoder drain handling.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if drainable handling is enabled.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_audio_decoder_get_drainable (GstAudioDecoder * dec)
|
||||||
|
{
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (dec);
|
||||||
|
result = dec->priv->drainable;
|
||||||
|
GST_OBJECT_UNLOCK (dec);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_audio_decoder_set_needs_format:
|
||||||
|
* @enc: a #GstAudioDecoder
|
||||||
|
* @enabled: new state
|
||||||
|
*
|
||||||
|
* Configures decoder format needs. If enabled, subclass needs to be
|
||||||
|
* negotiated with format caps before it can process any data. It will then
|
||||||
|
* never be handed any data before it has been configured.
|
||||||
|
* Otherwise, it might be handed data without having been configured and
|
||||||
|
* is then expected being able to do so either by default
|
||||||
|
* or based on the input data.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_audio_decoder_set_needs_format (GstAudioDecoder * dec, gboolean enabled)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (dec);
|
||||||
|
dec->priv->needs_format = enabled;
|
||||||
|
GST_OBJECT_UNLOCK (dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_audio_decoder_get_needs_format:
|
||||||
|
* @enc: a #GstAudioDecoder
|
||||||
|
*
|
||||||
|
* Queries decoder required format handling.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if required format handling is enabled.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_audio_decoder_get_needs_format (GstAudioDecoder * dec)
|
||||||
|
{
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (dec);
|
||||||
|
result = dec->priv->needs_format;
|
||||||
|
GST_OBJECT_UNLOCK (dec);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -296,6 +296,16 @@ void gst_audio_decoder_set_tolerance (GstAudioDecoder * dec,
|
||||||
|
|
||||||
gint64 gst_audio_decoder_get_tolerance (GstAudioDecoder * dec);
|
gint64 gst_audio_decoder_get_tolerance (GstAudioDecoder * dec);
|
||||||
|
|
||||||
|
void gst_audio_decoder_set_drainable (GstAudioDecoder * dec,
|
||||||
|
gboolean enabled);
|
||||||
|
|
||||||
|
gboolean gst_audio_decoder_get_drainable (GstAudioDecoder * dec);
|
||||||
|
|
||||||
|
void gst_audio_decoder_set_needs_format (GstAudioDecoder * dec,
|
||||||
|
gboolean enabled);
|
||||||
|
|
||||||
|
gboolean gst_audio_decoder_get_needs_format (GstAudioDecoder * dec);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* _GST_AUDIO_DECODER_H_ */
|
#endif /* _GST_AUDIO_DECODER_H_ */
|
||||||
|
|
|
@ -180,6 +180,8 @@ enum
|
||||||
#define DEFAULT_GRANULE FALSE
|
#define DEFAULT_GRANULE FALSE
|
||||||
#define DEFAULT_HARD_RESYNC FALSE
|
#define DEFAULT_HARD_RESYNC FALSE
|
||||||
#define DEFAULT_TOLERANCE 40000000
|
#define DEFAULT_TOLERANCE 40000000
|
||||||
|
#define DEFAULT_HARD_MIN FALSE
|
||||||
|
#define DEFAULT_DRAINABLE TRUE
|
||||||
|
|
||||||
typedef struct _GstAudioEncoderContext
|
typedef struct _GstAudioEncoderContext
|
||||||
{
|
{
|
||||||
|
@ -239,6 +241,8 @@ struct _GstAudioEncoderPrivate
|
||||||
gboolean perfect_ts;
|
gboolean perfect_ts;
|
||||||
gboolean hard_resync;
|
gboolean hard_resync;
|
||||||
gboolean granule;
|
gboolean granule;
|
||||||
|
gboolean hard_min;
|
||||||
|
gboolean drainable;
|
||||||
|
|
||||||
/* pending tags */
|
/* pending tags */
|
||||||
GstTagList *tags;
|
GstTagList *tags;
|
||||||
|
@ -396,6 +400,8 @@ gst_audio_encoder_init (GstAudioEncoder * enc, GstAudioEncoderClass * bclass)
|
||||||
enc->priv->perfect_ts = DEFAULT_PERFECT_TS;
|
enc->priv->perfect_ts = DEFAULT_PERFECT_TS;
|
||||||
enc->priv->hard_resync = DEFAULT_HARD_RESYNC;
|
enc->priv->hard_resync = DEFAULT_HARD_RESYNC;
|
||||||
enc->priv->tolerance = DEFAULT_TOLERANCE;
|
enc->priv->tolerance = DEFAULT_TOLERANCE;
|
||||||
|
enc->priv->hard_min = DEFAULT_HARD_MIN;
|
||||||
|
enc->priv->drainable = DEFAULT_DRAINABLE;
|
||||||
|
|
||||||
/* init state */
|
/* init state */
|
||||||
gst_audio_encoder_reset (enc, TRUE);
|
gst_audio_encoder_reset (enc, TRUE);
|
||||||
|
@ -769,13 +775,17 @@ gst_audio_encoder_push_buffers (GstAudioEncoder * enc, gboolean force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need) {
|
priv->got_data = FALSE;
|
||||||
|
if (G_LIKELY (need)) {
|
||||||
const guint8 *data;
|
const guint8 *data;
|
||||||
|
|
||||||
data = gst_adapter_map (priv->adapter, priv->offset + need);
|
data = gst_adapter_map (priv->adapter, priv->offset + need);
|
||||||
buf =
|
buf =
|
||||||
gst_buffer_new_wrapped_full ((gpointer) data, NULL, priv->offset,
|
gst_buffer_new_wrapped_full ((gpointer) data, NULL, priv->offset,
|
||||||
need);
|
need);
|
||||||
|
} else if (!priv->drainable) {
|
||||||
|
GST_DEBUG_OBJECT (enc, "non-drainable and no more data");
|
||||||
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (enc, "providing subclass with %d bytes at offset %d",
|
GST_LOG_OBJECT (enc, "providing subclass with %d bytes at offset %d",
|
||||||
|
@ -786,14 +796,21 @@ gst_audio_encoder_push_buffers (GstAudioEncoder * enc, gboolean force)
|
||||||
priv->offset += need;
|
priv->offset += need;
|
||||||
priv->samples_in += need / ctx->info.bpf;
|
priv->samples_in += need / ctx->info.bpf;
|
||||||
|
|
||||||
priv->got_data = FALSE;
|
/* subclass might not want to be bothered with leftover data,
|
||||||
ret = klass->handle_frame (enc, buf);
|
* so take care of that here if so, otherwise pass along */
|
||||||
|
if (G_UNLIKELY (priv->force && priv->hard_min && buf)) {
|
||||||
|
GST_DEBUG_OBJECT (enc, "bypassing subclass with leftover");
|
||||||
|
ret = gst_audio_encoder_finish_frame (enc, NULL, -1);
|
||||||
|
} else {
|
||||||
|
ret = klass->handle_frame (enc, buf);
|
||||||
|
}
|
||||||
|
|
||||||
if (G_LIKELY (buf)) {
|
if (G_LIKELY (buf)) {
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
gst_adapter_unmap (priv->adapter);
|
gst_adapter_unmap (priv->adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finish:
|
||||||
/* no data to feed, no leftover provided, then bail out */
|
/* no data to feed, no leftover provided, then bail out */
|
||||||
if (G_UNLIKELY (!buf && !priv->got_data)) {
|
if (G_UNLIKELY (!buf && !priv->got_data)) {
|
||||||
priv->drained = TRUE;
|
priv->drained = TRUE;
|
||||||
|
@ -2135,6 +2152,106 @@ gst_audio_encoder_get_tolerance (GstAudioEncoder * enc)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_audio_encoder_set_hard_min:
|
||||||
|
* @enc: a #GstAudioEncoder
|
||||||
|
* @enabled: new state
|
||||||
|
*
|
||||||
|
* Configures encoder hard minimum handling. If enabled, subclass
|
||||||
|
* will never be handed less samples than it configured, which otherwise
|
||||||
|
* might occur near end-of-data handling. Instead, the leftover samples
|
||||||
|
* will simply be discarded.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_audio_encoder_set_hard_min (GstAudioEncoder * enc, gboolean enabled)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (enc);
|
||||||
|
enc->priv->hard_min = enabled;
|
||||||
|
GST_OBJECT_UNLOCK (enc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_audio_encoder_get_hard_min:
|
||||||
|
* @enc: a #GstAudioEncoder
|
||||||
|
*
|
||||||
|
* Queries encoder hard minimum handling.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if hard minimum handling is enabled.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_audio_encoder_get_hard_min (GstAudioEncoder * enc)
|
||||||
|
{
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (enc);
|
||||||
|
result = enc->priv->hard_min;
|
||||||
|
GST_OBJECT_UNLOCK (enc);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_audio_encoder_set_drainable:
|
||||||
|
* @enc: a #GstAudioEncoder
|
||||||
|
* @enabled: new state
|
||||||
|
*
|
||||||
|
* Configures encoder drain handling. If drainable, subclass might
|
||||||
|
* be handed a NULL buffer to have it return any leftover encoded data.
|
||||||
|
* Otherwise, it is not considered so capable and will only ever be passed
|
||||||
|
* real data.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_audio_encoder_set_drainable (GstAudioEncoder * enc, gboolean enabled)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (enc);
|
||||||
|
enc->priv->drainable = enabled;
|
||||||
|
GST_OBJECT_UNLOCK (enc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_audio_encoder_get_drainable:
|
||||||
|
* @enc: a #GstAudioEncoder
|
||||||
|
*
|
||||||
|
* Queries encoder drain handling.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if drainable handling is enabled.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_audio_encoder_get_drainable (GstAudioEncoder * enc)
|
||||||
|
{
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (enc);
|
||||||
|
result = enc->priv->drainable;
|
||||||
|
GST_OBJECT_UNLOCK (enc);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_audio_encoder_merge_tags:
|
* gst_audio_encoder_merge_tags:
|
||||||
* @enc: a #GstAudioEncoder
|
* @enc: a #GstAudioEncoder
|
||||||
|
|
|
@ -250,6 +250,16 @@ void gst_audio_encoder_set_tolerance (GstAudioEncoder * enc,
|
||||||
|
|
||||||
gint64 gst_audio_encoder_get_tolerance (GstAudioEncoder * enc);
|
gint64 gst_audio_encoder_get_tolerance (GstAudioEncoder * enc);
|
||||||
|
|
||||||
|
void gst_audio_encoder_set_hard_min (GstAudioEncoder * enc,
|
||||||
|
gboolean enabled);
|
||||||
|
|
||||||
|
gboolean gst_audio_encoder_get_hard_min (GstAudioEncoder * enc);
|
||||||
|
|
||||||
|
void gst_audio_encoder_set_drainable (GstAudioEncoder * enc,
|
||||||
|
gboolean enabled);
|
||||||
|
|
||||||
|
gboolean gst_audio_encoder_get_drainable (GstAudioEncoder * enc);
|
||||||
|
|
||||||
void gst_audio_encoder_merge_tags (GstAudioEncoder * enc,
|
void gst_audio_encoder_merge_tags (GstAudioEncoder * enc,
|
||||||
const GstTagList * tags, GstTagMergeMode mode);
|
const GstTagList * tags, GstTagMergeMode mode);
|
||||||
|
|
||||||
|
|
|
@ -1024,6 +1024,31 @@ discoverer_collect (GstDiscoverer * dc)
|
||||||
if (gst_element_query_duration (pipeline, GST_FORMAT_TIME, &dur)) {
|
if (gst_element_query_duration (pipeline, GST_FORMAT_TIME, &dur)) {
|
||||||
GST_DEBUG ("Got duration %" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
|
GST_DEBUG ("Got duration %" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
|
||||||
dc->priv->current_info->duration = (guint64) dur;
|
dc->priv->current_info->duration = (guint64) dur;
|
||||||
|
} else {
|
||||||
|
GstStateChangeReturn sret;
|
||||||
|
|
||||||
|
/* Some parsers may not even return a rough estimate right away, e.g.
|
||||||
|
* because they've only processed a single frame so far, so if we
|
||||||
|
* didn't get a duration the first time, spin a bit and try again.
|
||||||
|
* Ugly, but still better than making parsers or other elements return
|
||||||
|
* completely bogus values. We need some API extensions to solve this
|
||||||
|
* better. */
|
||||||
|
GST_INFO ("No duration yet, try a bit harder..");
|
||||||
|
sret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||||
|
if (sret != GST_STATE_CHANGE_FAILURE) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; ++i) {
|
||||||
|
g_usleep (G_USEC_PER_SEC / 20);
|
||||||
|
if (gst_element_query_duration (pipeline, GST_FORMAT_TIME, &dur)
|
||||||
|
&& dur > 0) {
|
||||||
|
GST_DEBUG ("Got duration %" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
|
||||||
|
dc->priv->current_info->duration = (guint64) dur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gst_element_set_state (pipeline, GST_STATE_PAUSED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc->priv->seeking_query) {
|
if (dc->priv->seeking_query) {
|
||||||
|
|
|
@ -175,13 +175,15 @@
|
||||||
* <refsect2>
|
* <refsect2>
|
||||||
* <title>Specifying which CD/DVD device to use</title>
|
* <title>Specifying which CD/DVD device to use</title>
|
||||||
* The device to use for CDs/DVDs needs to be set on the source element
|
* The device to use for CDs/DVDs needs to be set on the source element
|
||||||
* playbin creates before it is opened. The only way to do this at the moment
|
* playbin creates before it is opened. The most generic way of doing this
|
||||||
* is to connect to playbin's "notify::source" signal, which will be emitted
|
* is to connect to playbin's "source-setup" (or "notify::source") signal,
|
||||||
* by playbin when it has created the source element for a particular URI.
|
* which will be emitted by playbin2 when it has created the source element
|
||||||
* In the signal callback you can check if the source element has a "device"
|
* for a particular URI. In the signal callback you can check if the source
|
||||||
* property and set it appropriately. In future ways might be added to specify
|
* element has a "device" property and set it appropriately. In some cases
|
||||||
* the device as part of the URI, but at the time of writing this is not
|
* the device can also be set as part of the URI, but it depends on the
|
||||||
* possible yet.
|
* elements involved if this will work or not. For example, for DVD menu
|
||||||
|
* playback, the following syntax might work (if the resindvd plugin is used):
|
||||||
|
* dvd://[/path/to/device]
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
* <refsect2>
|
* <refsect2>
|
||||||
* <title>Handling redirects</title>
|
* <title>Handling redirects</title>
|
||||||
|
@ -196,19 +198,19 @@
|
||||||
* <refsect2>
|
* <refsect2>
|
||||||
* <title>Examples</title>
|
* <title>Examples</title>
|
||||||
* |[
|
* |[
|
||||||
* gst-launch -v playbin uri=file:///path/to/somefile.avi
|
* gst-launch -v playbin2 uri=file:///path/to/somefile.avi
|
||||||
* ]| This will play back the given AVI video file, given that the video and
|
* ]| This will play back the given AVI video file, given that the video and
|
||||||
* audio decoders required to decode the content are installed. Since no
|
* audio decoders required to decode the content are installed. Since no
|
||||||
* special audio sink or video sink is supplied (not possible via gst-launch),
|
* special audio sink or video sink is supplied (not possible via gst-launch),
|
||||||
* playbin will try to find a suitable audio and video sink automatically
|
* playbin will try to find a suitable audio and video sink automatically
|
||||||
* using the autoaudiosink and autovideosink elements.
|
* using the autoaudiosink and autovideosink elements.
|
||||||
* |[
|
* |[
|
||||||
* gst-launch -v playbin uri=cdda://4
|
* gst-launch -v playbin2 uri=cdda://4
|
||||||
* ]| This will play back track 4 on an audio CD in your disc drive (assuming
|
* ]| This will play back track 4 on an audio CD in your disc drive (assuming
|
||||||
* the drive is detected automatically by the plugin).
|
* the drive is detected automatically by the plugin).
|
||||||
* |[
|
* |[
|
||||||
* gst-launch -v playbin uri=dvd://1
|
* gst-launch -v playbin2 uri=dvd://
|
||||||
* ]| This will play back title 1 of a DVD in your disc drive (assuming
|
* ]| This will play back the DVD in your disc drive (assuming
|
||||||
* the drive is detected automatically by the plugin).
|
* the drive is detected automatically by the plugin).
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue