GstPad *playsinkpad;
GstPad *encodebinpad;
GstPad *blocked_pad;
+ gulong probe_id;
} OutputChain;
G_DEFINE_TYPE (GESTimelinePipeline, ges_timeline_pipeline, GST_TYPE_PIPELINE);
GST_DEBUG ("Smart Render mode, setting input caps");
ocaps = gst_encoding_profile_get_input_caps (prof);
if (track->type == GES_TRACK_TYPE_AUDIO)
- rcaps = gst_caps_from_string ("audio/x-raw-int;audio/x-raw-float");
+ rcaps = gst_caps_new_empty_simple ("audio/x-raw");
else
- rcaps = gst_caps_from_string ("video/x-raw-yuv;video/x-raw-rgb");
+ rcaps = gst_caps_new_empty_simple ("video/x-raw");
gst_caps_append (ocaps, rcaps);
ges_track_set_caps (track, ocaps);
} else {
/* Raw preview or rendering mode */
if (track->type == GES_TRACK_TYPE_VIDEO)
- caps = gst_caps_from_string ("video/x-raw-yuv;video/x-raw-rgb");
+ caps = gst_caps_new_empty_simple ("video/x-raw");
else if (track->type == GES_TRACK_TYPE_AUDIO)
- gst_caps_from_string ("audio/x-raw-int;audio/x-raw-float");
+ caps = gst_caps_new_empty_simple ("audio/x-raw");
if (caps) {
ges_track_set_caps (track, caps);
ret = GST_STATE_CHANGE_FAILURE;
goto done;
}
- if (self->
- priv->mode & (TIMELINE_MODE_RENDER | TIMELINE_MODE_SMART_RENDER))
+ if (self->priv->
+ mode & (TIMELINE_MODE_RENDER | TIMELINE_MODE_SMART_RENDER))
GST_DEBUG ("rendering => Updating pipeline caps");
if (!ges_timeline_pipeline_update_caps (self)) {
GST_ERROR_OBJECT (element, "Error setting the caps for rendering");
GstIterator *pads;
gboolean done = FALSE;
GstCaps *srccaps;
+ GValue paditem = { 0, };
if (G_UNLIKELY (pad == NULL))
goto no_pad;
pads = gst_element_iterate_sink_pads (element);
else
pads = gst_element_iterate_src_pads (element);
- srccaps = gst_pad_get_caps_reffed (pad);
+ srccaps = gst_pad_query_caps (pad, NULL);
GST_DEBUG ("srccaps %" GST_PTR_FORMAT, srccaps);
while (!done) {
- gpointer padptr;
-
- switch (gst_iterator_next (pads, &padptr)) {
+ switch (gst_iterator_next (pads, &paditem)) {
case GST_ITERATOR_OK:
{
- GstPad *testpad = (GstPad *) padptr;
+ GstPad *testpad = g_value_get_object (&paditem);
- if (gst_pad_is_linked (testpad)) {
- gst_object_unref (testpad);
- } else {
- GstCaps *sinkcaps = gst_pad_get_caps_reffed (testpad);
+ if (!gst_pad_is_linked (testpad)) {
+ GstCaps *sinkcaps = gst_pad_query_caps (testpad, NULL);
GST_DEBUG ("sinkccaps %" GST_PTR_FORMAT, sinkcaps);
if (gst_caps_can_intersect (srccaps, sinkcaps)) {
- res = testpad;
+ res = gst_object_ref (testpad);
done = TRUE;
- } else
- gst_object_unref (testpad);
+ }
gst_caps_unref (sinkcaps);
}
+ g_value_reset (&paditem);
}
break;
case GST_ITERATOR_DONE:
break;
}
}
+ g_value_reset (&paditem);
gst_iterator_free (pads);
gst_caps_unref (srccaps);
}
}
-static void
-pad_blocked (GstPad * pad, gboolean blocked, gpointer user_data)
+static GstPadProbeReturn
+pad_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
/* no nothing */
- GST_DEBUG_OBJECT (pad, "blocked callback, blocked: %d", blocked);
+ GST_DEBUG_OBJECT (pad, "blocked callback, blocked");
+ return GST_PAD_PROBE_OK;
}
static void
OutputChain *chain;
GESTrack *track;
GstPad *sinkpad;
+ GstCaps *caps;
gboolean reconfigured = FALSE;
+ caps = gst_pad_query_caps (pad, NULL);
+
GST_DEBUG_OBJECT (self, "new pad %s:%s , caps:%" GST_PTR_FORMAT,
- GST_DEBUG_PAD_NAME (pad), GST_PAD_CAPS (pad));
+ GST_DEBUG_PAD_NAME (pad), caps);
- if (G_UNLIKELY (!(track =
- ges_timeline_get_track_for_pad (self->priv->timeline, pad)))) {
+ gst_caps_unref (caps);
+
+ track = ges_timeline_get_track_for_pad (self->priv->timeline, pad);
+
+ if (G_UNLIKELY (!track)) {
GST_WARNING_OBJECT (self, "Couldn't find coresponding track !");
return;
}
goto error;
}
chain->blocked_pad = tmppad;
- GST_DEBUG ("blocking pad %" GST_PTR_FORMAT, tmppad);
- gst_pad_set_blocked_async (tmppad, TRUE, pad_blocked, NULL);
+ GST_DEBUG_OBJECT (tmppad, "blocking pad");
+ chain->probe_id = gst_pad_add_probe (tmppad, GST_PAD_PROBE_TYPE_BLOCK,
+ pad_blocked, NULL, NULL);
GST_DEBUG ("Reconfiguring playsink");
sinkpad = get_compatible_unlinked_pad (self->priv->encodebin, pad);
if (sinkpad == NULL) {
- GstCaps *caps = gst_pad_get_caps_reffed (pad);
+ GstCaps *caps = gst_pad_query_caps (pad, NULL);
+
/* If no compatible static pad is available, request a pad */
g_signal_emit_by_name (self->priv->encodebin, "request-pad", caps,
&sinkpad);
gst_caps_unref (caps);
+
if (G_UNLIKELY (sinkpad == NULL)) {
GST_ERROR_OBJECT (self, "Couldn't get a pad from encodebin !");
goto error;
}
if (chain->blocked_pad) {
- GST_DEBUG ("unblocking pad %" GST_PTR_FORMAT, chain->blocked_pad);
- gst_pad_set_blocked_async (chain->blocked_pad, FALSE, pad_blocked, NULL);
+ GST_DEBUG_OBJECT (chain->blocked_pad, "unblocking pad");
+ gst_pad_remove_probe (chain->blocked_pad, chain->probe_id);
gst_object_unref (chain->blocked_pad);
chain->blocked_pad = NULL;
+ chain->probe_id = 0;
}
/* Unlike/remove tee */
OutputChain *chain = (OutputChain *) tmp->data;
if (chain->blocked_pad) {
- GST_DEBUG ("unblocking pad %" GST_PTR_FORMAT, chain->blocked_pad);
- gst_pad_set_blocked_async (chain->blocked_pad, FALSE, pad_blocked, NULL);
+ GST_DEBUG_OBJECT (chain->blocked_pad, "unblocking pad");
+ gst_pad_remove_probe (chain->blocked_pad, chain->probe_id);
+ chain->probe_id = 0;
+ /* do we need to unref and NULL the pad here? */
}
}
}
}
/**
- * ges_timeline_pipeline_get_thumbnail_buffer:
+ * ges_timeline_pipeline_get_thumbnail:
* @self: a #GESTimelinePipeline in %GST_STATE_PLAYING or %GST_STATE_PAUSED
* @caps: (transfer none): caps specifying current format. Use %GST_CAPS_ANY
* for native size.
*
- * Returns a #GstBuffer with the currently playing in the format specified by
- * caps. The caller should unref the #gst_buffer_unref when finished. If ANY
+ * Returns a #GstSample with the currently playing image in the format specified by
+ * caps. The caller should free the sample with #gst_sample_unref when finished. If ANY
* caps are specified, the information will be returned in the whatever format
* is currently used by the sink. This information can be retrieve from caps
* associated with the buffer.
*
- * Returns: (transfer full): a #GstBuffer or %NULL
+ * Returns: (transfer full): a #GstSample or %NULL
*/
-GstBuffer *
-ges_timeline_pipeline_get_thumbnail_buffer (GESTimelinePipeline * self,
- GstCaps * caps)
+GstSample *
+ges_timeline_pipeline_get_thumbnail (GESTimelinePipeline * self, GstCaps * caps)
{
GstElement *sink;
- GstBuffer *buf;
sink = self->priv->playsink;
+
if (!sink) {
GST_WARNING ("thumbnailing can only be done if we have a playsink");
return NULL;
}
- buf = ges_play_sink_convert_frame (sink, caps);
-
- return buf;
+ return ges_play_sink_convert_frame (sink, caps);
}
/**
*
* Returns: %TRUE if the thumbnail was properly save, else %FALSE.
*/
-
+/* FIXME 0.11: save_thumbnail should have a GError parameter */
gboolean
ges_timeline_pipeline_save_thumbnail (GESTimelinePipeline * self, int width, int
height, const gchar * format, const gchar * location)
{
+ GstMapInfo map_info;
GstBuffer *b;
- FILE *fp;
+ GstSample *sample;
GstCaps *caps;
gboolean res = TRUE;
if (height > 1)
gst_caps_set_simple (caps, "height", G_TYPE_INT, height, NULL);
- if (!(b = ges_timeline_pipeline_get_thumbnail_buffer (self, caps))) {
+ if (!(sample = ges_timeline_pipeline_get_thumbnail (self, caps))) {
gst_caps_unref (caps);
return res;
}
- /* FIXME : Use standard glib methods */
- fp = fopen (location, "w+");
- if (!fwrite (GST_BUFFER_DATA (b), GST_BUFFER_SIZE (b), 1, fp) || ferror (fp)) {
- res = FALSE;
+ b = gst_sample_get_buffer (sample);
+ if (gst_buffer_map (b, &map_info, GST_MAP_READ)) {
+ GError *err = NULL;
+
+ if (!g_file_set_contents (location, (const char *) map_info.data,
+ map_info.size, &err)) {
+ GST_WARNING ("Could not save thumbnail: %s", err->message);
+ g_error_free (err);
+ res = FALSE;
+ }
}
- fclose (fp);
gst_caps_unref (caps);
+ gst_buffer_unmap (b, &map_info);
gst_buffer_unref (b);
+ gst_sample_unref (sample);
+
return res;
}
* @width: the requested width or -1 for native size
* @height: the requested height or -1 for native size
*
- * A convenience method for ges_timeline_pipeline_get_thumbnail_raw which
+ * A convenience method for @ges_timeline_pipeline_get_thumbnail which
* returns a buffer in 24-bit RGB, optionally scaled to the specified width
* and height. If -1 is specified for either dimension, it will be left at
* native size. You can retreive this information from the caps associated
* with the buffer.
*
- * The caller is responsible for unreffing the returned buffer with
- * #gst_buffer_unref.
+ * The caller is responsible for unreffing the returned sample with
+ * #gst_sample_unref.
*
- * Returns: (transfer full): a #GstBuffer or %NULL
+ * Returns: (transfer full): a #GstSample or %NULL
*/
-GstBuffer *
+GstSample *
ges_timeline_pipeline_get_thumbnail_rgb24 (GESTimelinePipeline * self,
gint width, gint height)
{
- GstBuffer *ret;
+ GstSample *ret;
GstCaps *caps;
- caps = gst_caps_from_string ("video/x-raw-rgb,bpp=(int)24," "depth=(int)24");
+ caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING,
+ "RGB", NULL);
if (width != -1)
gst_caps_set_simple (caps, "width", G_TYPE_INT, (gint) width, NULL);
if (height != -1)
gst_caps_set_simple (caps, "height", G_TYPE_INT, (gint) height, NULL);
- ret = ges_timeline_pipeline_get_thumbnail_buffer (self, caps);
+ ret = ges_timeline_pipeline_get_thumbnail (self, caps);
gst_caps_unref (caps);
return ret;
}