Merge branch 'master' into 0.11

This commit is contained in:
Wim Taymans 2011-10-04 17:58:49 +02:00
commit a00927ad03
9 changed files with 179 additions and 10 deletions

View file

@ -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

View file

@ -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;

View file

@ -65,6 +65,7 @@ struct _GstAlsaSrc {
guint channels;
gint bpf;
gboolean driver_timestamps;
GstClockTime first_alsa_ts;
guint buffer_time;
guint period_time;

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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) */

View file

@ -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");

View file

@ -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;

View file

@ -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