mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-27 03:23:16 +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_ref
|
||||
gst_encoding_profile_find
|
||||
gst_encoding_profile_from_discoverer
|
||||
gst_encoding_profile_get_name
|
||||
gst_encoding_profile_get_description
|
||||
gst_encoding_profile_get_format
|
||||
|
|
|
@ -200,37 +200,63 @@ gst_alsasrc_get_timestamp (GstAlsaSrc * src)
|
|||
snd_htimestamp_t tstamp;
|
||||
GstClockTime timestamp;
|
||||
snd_pcm_uframes_t availmax;
|
||||
gint64 offset;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "Getting alsa timestamp!");
|
||||
|
||||
if (!src) {
|
||||
GST_ERROR_OBJECT (src, "No alsa handle created yet !");
|
||||
return 0;
|
||||
return GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
if (snd_pcm_status_malloc (&status) != 0) {
|
||||
GST_ERROR_OBJECT (src, "snd_pcm_status_malloc failed");
|
||||
return GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
if (snd_pcm_status (src->handle, status) != 0) {
|
||||
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 */
|
||||
snd_pcm_status_get_htstamp (status, &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 */
|
||||
availmax = snd_pcm_status_get_avail_max (status);
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
|
||||
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_TIME_ARGS (timestamp));
|
||||
return timestamp;
|
||||
|
@ -330,8 +356,10 @@ gst_alsasrc_create (GstBaseSrc * bsrc, guint64 offset, guint length,
|
|||
ret =
|
||||
GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, outbuf);
|
||||
if (asrc->driver_timestamps == TRUE && *outbuf) {
|
||||
GST_BUFFER_TIMESTAMP (*outbuf) =
|
||||
gst_alsasrc_get_timestamp ((GstAlsaSrc *) bsrc);
|
||||
GstClockTime ts = gst_alsasrc_get_timestamp (asrc);
|
||||
if (GST_CLOCK_TIME_IS_VALID (ts)) {
|
||||
GST_BUFFER_TIMESTAMP (*outbuf) = ts;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -345,6 +373,7 @@ gst_alsasrc_init (GstAlsaSrc * alsasrc)
|
|||
alsasrc->device = g_strdup (DEFAULT_PROP_DEVICE);
|
||||
alsasrc->cached_caps = NULL;
|
||||
alsasrc->driver_timestamps = FALSE;
|
||||
alsasrc->first_alsa_ts = GST_CLOCK_TIME_NONE;
|
||||
|
||||
alsasrc->alsa_lock = g_mutex_new ();
|
||||
}
|
||||
|
@ -974,6 +1003,7 @@ gst_alsasrc_reset (GstAudioSrc * asrc)
|
|||
GST_DEBUG_OBJECT (alsa, "prepare");
|
||||
CHECK (snd_pcm_prepare (alsa->handle), prepare_error);
|
||||
GST_DEBUG_OBJECT (alsa, "reset done");
|
||||
alsa->first_alsa_ts = GST_CLOCK_TIME_NONE;
|
||||
GST_ALSA_SRC_UNLOCK (asrc);
|
||||
|
||||
return;
|
||||
|
|
|
@ -65,6 +65,7 @@ struct _GstAlsaSrc {
|
|||
guint channels;
|
||||
gint bpf;
|
||||
gboolean driver_timestamps;
|
||||
GstClockTime first_alsa_ts;
|
||||
|
||||
guint buffer_time;
|
||||
guint period_time;
|
||||
|
|
|
@ -965,3 +965,73 @@ gst_encoding_profile_deserialize_valfunc (GValue * value, const gchar * s)
|
|||
|
||||
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
|
||||
|
||||
#include <gst/pbutils/pbutils-enumtypes.h>
|
||||
#include <gst/pbutils/gstdiscoverer.h>
|
||||
|
||||
/**
|
||||
* GstEncodingProfile:
|
||||
|
@ -182,6 +183,9 @@ void gst_encoding_video_profile_set_pass (GstEncodingVideoProfi
|
|||
guint pass);
|
||||
void gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile *prof,
|
||||
gboolean variableframerate);
|
||||
|
||||
GstEncodingProfile * gst_encoding_profile_from_discoverer (GstDiscovererInfo *info);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_PROFILE_H__ */
|
||||
|
|
|
@ -216,8 +216,8 @@ enum
|
|||
* and buffers in this case. */
|
||||
#define AUTO_PREROLL_SIZE_BYTES 2 * 1024 * 1024
|
||||
#define AUTO_PREROLL_SIZE_BUFFERS 0
|
||||
#define AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME 0
|
||||
#define AUTO_PREROLL_SEEKABLE_SIZE_TIME 10 * GST_SECOND
|
||||
#define AUTO_PREROLL_NOT_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
|
||||
* 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));
|
||||
|
||||
/* 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,
|
||||
GST_ELEMENT_FACTORY_TYPE_SINK))
|
||||
return GST_AUTOPLUG_SELECT_TRY;
|
||||
GST_ELEMENT_FACTORY_TYPE_SINK)) {
|
||||
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 */
|
||||
GST_DEBUG_OBJECT (playbin, "we found a sink");
|
||||
|
|
|
@ -254,6 +254,7 @@ enum
|
|||
PROP_VIS_PLUGIN,
|
||||
PROP_FRAME,
|
||||
PROP_AV_OFFSET,
|
||||
PROP_VIDEO_SINK,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
|
@ -409,6 +410,19 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
|
|||
G_MININT64, G_MAXINT64, 0,
|
||||
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_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstPlaySinkClass,
|
||||
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:
|
||||
gst_play_sink_set_av_offset (playsink, g_value_get_int64 (value));
|
||||
break;
|
||||
case PROP_VIDEO_SINK:
|
||||
gst_play_sink_set_sink (playsink, GST_PLAY_SINK_TYPE_VIDEO,
|
||||
g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
|
||||
break;
|
||||
|
@ -3648,6 +3666,10 @@ gst_play_sink_get_property (GObject * object, guint prop_id,
|
|||
case PROP_AV_OFFSET:
|
||||
g_value_set_int64 (value, gst_play_sink_get_av_offset (playsink));
|
||||
break;
|
||||
case PROP_VIDEO_SINK:
|
||||
g_value_take_object (value, gst_play_sink_get_sink (playsink,
|
||||
GST_PLAY_SINK_TYPE_VIDEO));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
|
||||
break;
|
||||
|
|
|
@ -73,6 +73,7 @@ EXPORTS
|
|||
gst_encoding_list_all_targets
|
||||
gst_encoding_list_available_categories
|
||||
gst_encoding_profile_find
|
||||
gst_encoding_profile_from_discoverer
|
||||
gst_encoding_profile_get_description
|
||||
gst_encoding_profile_get_format
|
||||
gst_encoding_profile_get_input_caps
|
||||
|
|
Loading…
Reference in a new issue