mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +00:00
Merge branch 'master' into 0.11
This commit is contained in:
commit
a00927ad03
9 changed files with 179 additions and 10 deletions
|
@ -2084,6 +2084,7 @@ GstEncodingProfile
|
||||||
gst_encoding_profile_unref
|
gst_encoding_profile_unref
|
||||||
gst_encoding_profile_ref
|
gst_encoding_profile_ref
|
||||||
gst_encoding_profile_find
|
gst_encoding_profile_find
|
||||||
|
gst_encoding_profile_from_discoverer
|
||||||
gst_encoding_profile_get_name
|
gst_encoding_profile_get_name
|
||||||
gst_encoding_profile_get_description
|
gst_encoding_profile_get_description
|
||||||
gst_encoding_profile_get_format
|
gst_encoding_profile_get_format
|
||||||
|
|
|
@ -200,37 +200,63 @@ gst_alsasrc_get_timestamp (GstAlsaSrc * src)
|
||||||
snd_htimestamp_t tstamp;
|
snd_htimestamp_t tstamp;
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
snd_pcm_uframes_t availmax;
|
snd_pcm_uframes_t availmax;
|
||||||
|
gint64 offset;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "Getting alsa timestamp!");
|
GST_DEBUG_OBJECT (src, "Getting alsa timestamp!");
|
||||||
|
|
||||||
if (!src) {
|
if (!src) {
|
||||||
GST_ERROR_OBJECT (src, "No alsa handle created yet !");
|
GST_ERROR_OBJECT (src, "No alsa handle created yet !");
|
||||||
return 0;
|
return GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snd_pcm_status_malloc (&status) != 0) {
|
if (snd_pcm_status_malloc (&status) != 0) {
|
||||||
GST_ERROR_OBJECT (src, "snd_pcm_status_malloc failed");
|
GST_ERROR_OBJECT (src, "snd_pcm_status_malloc failed");
|
||||||
|
return GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snd_pcm_status (src->handle, status) != 0) {
|
if (snd_pcm_status (src->handle, status) != 0) {
|
||||||
GST_ERROR_OBJECT (src, "snd_pcm_status failed");
|
GST_ERROR_OBJECT (src, "snd_pcm_status failed");
|
||||||
|
snd_pcm_status_free (status);
|
||||||
|
return GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get high resolution time stamp from driver */
|
/* get high resolution time stamp from driver */
|
||||||
snd_pcm_status_get_htstamp (status, &tstamp);
|
snd_pcm_status_get_htstamp (status, &tstamp);
|
||||||
timestamp = GST_TIMESPEC_TO_TIME (tstamp);
|
timestamp = GST_TIMESPEC_TO_TIME (tstamp);
|
||||||
|
GST_DEBUG_OBJECT (src, "Base ts: %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (timestamp));
|
||||||
|
if (timestamp == 0) {
|
||||||
|
/* This timestamp is supposed to represent the last sample, so 0 (which
|
||||||
|
can be returned on some ALSA setups (such as mine)) must mean that it
|
||||||
|
is invalid, unless there's just one sample, but we'll ignore that. */
|
||||||
|
GST_WARNING_OBJECT (src,
|
||||||
|
"No timestamp returned from snd_pcm_status_get_htstamp");
|
||||||
|
return GST_CLOCK_TIME_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Max available frames sets the depth of the buffer */
|
/* Max available frames sets the depth of the buffer */
|
||||||
availmax = snd_pcm_status_get_avail_max (status);
|
availmax = snd_pcm_status_get_avail_max (status);
|
||||||
|
|
||||||
/* Compensate the fact that the timestamp references the last sample */
|
/* Compensate the fact that the timestamp references the last sample */
|
||||||
timestamp -= gst_util_uint64_scale_int (availmax * 2, GST_SECOND, src->rate);
|
offset = -gst_util_uint64_scale_int (availmax * 2, GST_SECOND, src->rate);
|
||||||
/* Compensate for the delay until the package is available */
|
/* Compensate for the delay until the package is available */
|
||||||
timestamp += gst_util_uint64_scale_int (snd_pcm_status_get_delay (status),
|
offset += gst_util_uint64_scale_int (snd_pcm_status_get_delay (status),
|
||||||
GST_SECOND, src->rate);
|
GST_SECOND, src->rate);
|
||||||
|
|
||||||
snd_pcm_status_free (status);
|
snd_pcm_status_free (status);
|
||||||
|
|
||||||
|
/* just in case, should not happen */
|
||||||
|
if (-offset > timestamp)
|
||||||
|
timestamp = 0;
|
||||||
|
else
|
||||||
|
timestamp -= offset;
|
||||||
|
|
||||||
|
/* Take first ts into account */
|
||||||
|
if (src->first_alsa_ts == GST_CLOCK_TIME_NONE) {
|
||||||
|
src->first_alsa_ts = timestamp;
|
||||||
|
}
|
||||||
|
timestamp -= src->first_alsa_ts;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "ALSA timestamp : %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (src, "ALSA timestamp : %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (timestamp));
|
GST_TIME_ARGS (timestamp));
|
||||||
return timestamp;
|
return timestamp;
|
||||||
|
@ -330,8 +356,10 @@ gst_alsasrc_create (GstBaseSrc * bsrc, guint64 offset, guint length,
|
||||||
ret =
|
ret =
|
||||||
GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, outbuf);
|
GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, outbuf);
|
||||||
if (asrc->driver_timestamps == TRUE && *outbuf) {
|
if (asrc->driver_timestamps == TRUE && *outbuf) {
|
||||||
GST_BUFFER_TIMESTAMP (*outbuf) =
|
GstClockTime ts = gst_alsasrc_get_timestamp (asrc);
|
||||||
gst_alsasrc_get_timestamp ((GstAlsaSrc *) bsrc);
|
if (GST_CLOCK_TIME_IS_VALID (ts)) {
|
||||||
|
GST_BUFFER_TIMESTAMP (*outbuf) = ts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -345,6 +373,7 @@ gst_alsasrc_init (GstAlsaSrc * alsasrc)
|
||||||
alsasrc->device = g_strdup (DEFAULT_PROP_DEVICE);
|
alsasrc->device = g_strdup (DEFAULT_PROP_DEVICE);
|
||||||
alsasrc->cached_caps = NULL;
|
alsasrc->cached_caps = NULL;
|
||||||
alsasrc->driver_timestamps = FALSE;
|
alsasrc->driver_timestamps = FALSE;
|
||||||
|
alsasrc->first_alsa_ts = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
alsasrc->alsa_lock = g_mutex_new ();
|
alsasrc->alsa_lock = g_mutex_new ();
|
||||||
}
|
}
|
||||||
|
@ -974,6 +1003,7 @@ gst_alsasrc_reset (GstAudioSrc * asrc)
|
||||||
GST_DEBUG_OBJECT (alsa, "prepare");
|
GST_DEBUG_OBJECT (alsa, "prepare");
|
||||||
CHECK (snd_pcm_prepare (alsa->handle), prepare_error);
|
CHECK (snd_pcm_prepare (alsa->handle), prepare_error);
|
||||||
GST_DEBUG_OBJECT (alsa, "reset done");
|
GST_DEBUG_OBJECT (alsa, "reset done");
|
||||||
|
alsa->first_alsa_ts = GST_CLOCK_TIME_NONE;
|
||||||
GST_ALSA_SRC_UNLOCK (asrc);
|
GST_ALSA_SRC_UNLOCK (asrc);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -65,6 +65,7 @@ struct _GstAlsaSrc {
|
||||||
guint channels;
|
guint channels;
|
||||||
gint bpf;
|
gint bpf;
|
||||||
gboolean driver_timestamps;
|
gboolean driver_timestamps;
|
||||||
|
GstClockTime first_alsa_ts;
|
||||||
|
|
||||||
guint buffer_time;
|
guint buffer_time;
|
||||||
guint period_time;
|
guint period_time;
|
||||||
|
|
|
@ -965,3 +965,73 @@ gst_encoding_profile_deserialize_valfunc (GValue * value, const gchar * s)
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_encoding_profile_from_discoverer:
|
||||||
|
* @info: (transfer none): The #GstDiscovererInfo to read from
|
||||||
|
*
|
||||||
|
* Creates a #GstEncodingProfile matching the formats from the given
|
||||||
|
* #GstEncodingProfile. Streams other than audio or video (eg,
|
||||||
|
* subtitles), are currently ignored.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): The new #GstEncodingProfile or %NULL.
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
GstEncodingProfile *
|
||||||
|
gst_encoding_profile_from_discoverer (GstDiscovererInfo * info)
|
||||||
|
{
|
||||||
|
GstEncodingContainerProfile *profile;
|
||||||
|
GstDiscovererStreamInfo *sinfo;
|
||||||
|
GList *streams, *stream;
|
||||||
|
GstCaps *caps = NULL;
|
||||||
|
|
||||||
|
if (!info || gst_discoverer_info_get_result (info) != GST_DISCOVERER_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sinfo = gst_discoverer_info_get_stream_info (info);
|
||||||
|
if (!sinfo)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
caps = gst_discoverer_stream_info_get_caps (sinfo);
|
||||||
|
GST_LOG ("Container: %" GST_PTR_FORMAT "\n", caps);
|
||||||
|
profile =
|
||||||
|
gst_encoding_container_profile_new ("auto-generated",
|
||||||
|
"Automatically generated from GstDiscovererInfo", caps, NULL);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
if (!profile) {
|
||||||
|
GST_ERROR ("Failed to create container profile from caps %" GST_PTR_FORMAT,
|
||||||
|
caps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
streams =
|
||||||
|
gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
|
||||||
|
(sinfo));
|
||||||
|
for (stream = streams; stream; stream = stream->next) {
|
||||||
|
GstEncodingProfile *sprofile = NULL;
|
||||||
|
sinfo = (GstDiscovererStreamInfo *) stream->data;
|
||||||
|
caps = gst_discoverer_stream_info_get_caps (sinfo);
|
||||||
|
GST_LOG ("Stream: %" GST_PTR_FORMAT "\n", caps);
|
||||||
|
if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) {
|
||||||
|
sprofile =
|
||||||
|
(GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL,
|
||||||
|
NULL, 0);
|
||||||
|
} else if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) {
|
||||||
|
sprofile =
|
||||||
|
(GstEncodingProfile *) gst_encoding_video_profile_new (caps, NULL,
|
||||||
|
NULL, 0);
|
||||||
|
} else {
|
||||||
|
/* subtitles or other ? ignore for now */
|
||||||
|
}
|
||||||
|
if (sprofile)
|
||||||
|
gst_encoding_container_profile_add_profile (profile, sprofile);
|
||||||
|
else
|
||||||
|
GST_ERROR ("Failed to create stream profile from caps %" GST_PTR_FORMAT,
|
||||||
|
caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
}
|
||||||
|
gst_discoverer_stream_info_list_free (streams);
|
||||||
|
|
||||||
|
return (GstEncodingProfile *) profile;
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#include <gst/pbutils/pbutils-enumtypes.h>
|
#include <gst/pbutils/pbutils-enumtypes.h>
|
||||||
|
#include <gst/pbutils/gstdiscoverer.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstEncodingProfile:
|
* GstEncodingProfile:
|
||||||
|
@ -182,6 +183,9 @@ void gst_encoding_video_profile_set_pass (GstEncodingVideoProfi
|
||||||
guint pass);
|
guint pass);
|
||||||
void gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile *prof,
|
void gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile *prof,
|
||||||
gboolean variableframerate);
|
gboolean variableframerate);
|
||||||
|
|
||||||
|
GstEncodingProfile * gst_encoding_profile_from_discoverer (GstDiscovererInfo *info);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_PROFILE_H__ */
|
#endif /* __GST_PROFILE_H__ */
|
||||||
|
|
|
@ -216,8 +216,8 @@ enum
|
||||||
* and buffers in this case. */
|
* and buffers in this case. */
|
||||||
#define AUTO_PREROLL_SIZE_BYTES 2 * 1024 * 1024
|
#define AUTO_PREROLL_SIZE_BYTES 2 * 1024 * 1024
|
||||||
#define AUTO_PREROLL_SIZE_BUFFERS 0
|
#define AUTO_PREROLL_SIZE_BUFFERS 0
|
||||||
#define AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME 0
|
#define AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME 10 * GST_SECOND
|
||||||
#define AUTO_PREROLL_SEEKABLE_SIZE_TIME 10 * GST_SECOND
|
#define AUTO_PREROLL_SEEKABLE_SIZE_TIME 0
|
||||||
|
|
||||||
/* whan playing, keep a max of 2MB of data but try to keep the number of buffers
|
/* whan playing, keep a max of 2MB of data but try to keep the number of buffers
|
||||||
* as low as possible (try to aim for 5 buffers) */
|
* as low as possible (try to aim for 5 buffers) */
|
||||||
|
|
|
@ -3229,10 +3229,50 @@ autoplug_select_cb (GstElement * decodebin, GstPad * pad,
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playbin, "checking factory %s", GST_OBJECT_NAME (factory));
|
GST_DEBUG_OBJECT (playbin, "checking factory %s", GST_OBJECT_NAME (factory));
|
||||||
|
|
||||||
/* if it's not a sink, we just make decodebin try it */
|
/* if it's not a sink, we make sure the element is compatible with
|
||||||
|
* the fixed sink */
|
||||||
if (!gst_element_factory_list_is_type (factory,
|
if (!gst_element_factory_list_is_type (factory,
|
||||||
GST_ELEMENT_FACTORY_TYPE_SINK))
|
GST_ELEMENT_FACTORY_TYPE_SINK)) {
|
||||||
return GST_AUTOPLUG_SELECT_TRY;
|
gboolean isvideodec = gst_element_factory_list_is_type (factory,
|
||||||
|
GST_ELEMENT_FACTORY_TYPE_DECODER |
|
||||||
|
GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
|
||||||
|
GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE);
|
||||||
|
gboolean isaudiodec = gst_element_factory_list_is_type (factory,
|
||||||
|
GST_ELEMENT_FACTORY_TYPE_DECODER |
|
||||||
|
GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO);
|
||||||
|
|
||||||
|
/* If it is a decoder and we have a fixed sink for the media
|
||||||
|
* type it outputs, check that the decoder is compatible with this sink */
|
||||||
|
if ((isvideodec && group->video_sink) || (isaudiodec && group->audio_sink)) {
|
||||||
|
gboolean compatible = TRUE;
|
||||||
|
GstPad *sinkpad;
|
||||||
|
GstCaps *caps;
|
||||||
|
GstElement *sink;
|
||||||
|
|
||||||
|
if (isaudiodec)
|
||||||
|
sink = group->audio_sink;
|
||||||
|
else
|
||||||
|
sink = group->video_sink;
|
||||||
|
|
||||||
|
if ((sinkpad = gst_element_get_static_pad (sink, "sink"))) {
|
||||||
|
caps = gst_pad_get_caps_reffed (sinkpad);
|
||||||
|
|
||||||
|
compatible = gst_element_factory_can_src_any_caps (factory, caps);
|
||||||
|
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compatible)
|
||||||
|
return GST_AUTOPLUG_SELECT_TRY;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (playbin, "%s not compatible with the fixed sink",
|
||||||
|
GST_PLUGIN_FEATURE_NAME (factory));
|
||||||
|
|
||||||
|
return GST_AUTOPLUG_SELECT_SKIP;
|
||||||
|
} else
|
||||||
|
return GST_AUTOPLUG_SELECT_TRY;
|
||||||
|
}
|
||||||
|
|
||||||
/* it's a sink, see if an instance of it actually works */
|
/* it's a sink, see if an instance of it actually works */
|
||||||
GST_DEBUG_OBJECT (playbin, "we found a sink");
|
GST_DEBUG_OBJECT (playbin, "we found a sink");
|
||||||
|
|
|
@ -254,6 +254,7 @@ enum
|
||||||
PROP_VIS_PLUGIN,
|
PROP_VIS_PLUGIN,
|
||||||
PROP_FRAME,
|
PROP_FRAME,
|
||||||
PROP_AV_OFFSET,
|
PROP_AV_OFFSET,
|
||||||
|
PROP_VIDEO_SINK,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -409,6 +410,19 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
|
||||||
G_MININT64, G_MAXINT64, 0,
|
G_MININT64, G_MAXINT64, 0,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstPlaySink:video-sink:
|
||||||
|
*
|
||||||
|
* Set the used video sink element. NULL will use the default sink. playsink
|
||||||
|
* must be in %GST_STATE_NULL
|
||||||
|
*
|
||||||
|
* Since: 0.10.36
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_klass, PROP_VIDEO_SINK,
|
||||||
|
g_param_spec_object ("video-sink", "Video Sink",
|
||||||
|
"the video output element to use (NULL = default sink)",
|
||||||
|
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_signal_new ("reconfigure", G_TYPE_FROM_CLASS (klass),
|
g_signal_new ("reconfigure", G_TYPE_FROM_CLASS (klass),
|
||||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstPlaySinkClass,
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstPlaySinkClass,
|
||||||
reconfigure), NULL, NULL, gst_marshal_BOOLEAN__VOID, G_TYPE_BOOLEAN,
|
reconfigure), NULL, NULL, gst_marshal_BOOLEAN__VOID, G_TYPE_BOOLEAN,
|
||||||
|
@ -3610,6 +3624,10 @@ gst_play_sink_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_AV_OFFSET:
|
case PROP_AV_OFFSET:
|
||||||
gst_play_sink_set_av_offset (playsink, g_value_get_int64 (value));
|
gst_play_sink_set_av_offset (playsink, g_value_get_int64 (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_VIDEO_SINK:
|
||||||
|
gst_play_sink_set_sink (playsink, GST_PLAY_SINK_TYPE_VIDEO,
|
||||||
|
g_value_get_object (value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
|
||||||
break;
|
break;
|
||||||
|
@ -3648,6 +3666,10 @@ gst_play_sink_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_AV_OFFSET:
|
case PROP_AV_OFFSET:
|
||||||
g_value_set_int64 (value, gst_play_sink_get_av_offset (playsink));
|
g_value_set_int64 (value, gst_play_sink_get_av_offset (playsink));
|
||||||
break;
|
break;
|
||||||
|
case PROP_VIDEO_SINK:
|
||||||
|
g_value_take_object (value, gst_play_sink_get_sink (playsink,
|
||||||
|
GST_PLAY_SINK_TYPE_VIDEO));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -73,6 +73,7 @@ EXPORTS
|
||||||
gst_encoding_list_all_targets
|
gst_encoding_list_all_targets
|
||||||
gst_encoding_list_available_categories
|
gst_encoding_list_available_categories
|
||||||
gst_encoding_profile_find
|
gst_encoding_profile_find
|
||||||
|
gst_encoding_profile_from_discoverer
|
||||||
gst_encoding_profile_get_description
|
gst_encoding_profile_get_description
|
||||||
gst_encoding_profile_get_format
|
gst_encoding_profile_get_format
|
||||||
gst_encoding_profile_get_input_caps
|
gst_encoding_profile_get_input_caps
|
||||||
|
|
Loading…
Reference in a new issue