ges: Update for 0.11 changes

* Changes with controller API
* Use new GstSample for screenshot API
This commit is contained in:
Edward Hervey 2011-12-30 17:15:07 +01:00
parent 8f4c533c93
commit febf62f2b9
9 changed files with 68 additions and 133 deletions

View file

@ -51,13 +51,13 @@ register_ges_pipeline_flags (GType * id)
{
static const GFlagsValue values[] = {
{C_ENUM (TIMELINE_MODE_PREVIEW_AUDIO), "TIMELINE_MODE_PREVIEW_AUDIO",
"audio_preview"},
"audio_preview"},
{C_ENUM (TIMELINE_MODE_PREVIEW_VIDEO), "TIMELINE_MODE_PREVIEW_VIDEO",
"video_preview"},
"video_preview"},
{C_ENUM (TIMELINE_MODE_PREVIEW), "TIMELINE_MODE_PREVIEW", "full_preview"},
{C_ENUM (TIMELINE_MODE_RENDER), "TIMELINE_MODE_RENDER", "render"},
{C_ENUM (TIMELINE_MODE_SMART_RENDER), "TIMELINE_MODE_SMART_RENDER",
"smart_render"},
"smart_render"},
{0, NULL, NULL}
};

View file

@ -23,29 +23,12 @@
#include "ges-screenshot.h"
#include "ges-internal.h"
GstBuffer *
GstSample *
ges_play_sink_convert_frame (GstElement * playsink, GstCaps * caps)
{
GstBuffer *result;
GstSample *sample = NULL;
g_object_get (G_OBJECT (playsink), "frame", (GstMiniObject *) & result, NULL);
g_signal_emit_by_name (playsink, "convert-sample", caps, &sample);
GST_DEBUG ("got buffer %p from playsink", result);
if (result != NULL && caps != NULL) {
GstBuffer *temp;
GError *err = NULL;
/* FIXME : Need to get the input buffer caps */
temp = gst_video_convert_frame (result, NULL, caps, 25 * GST_SECOND, &err);
gst_buffer_unref (result);
if (temp == NULL && err) {
/* I'm really uncertain whether we should make playsink post an error
* on the bus or not. It's not like it's a critical issue regarding
* playsink behaviour. */
GST_ERROR ("Error converting frame: %s", err->message);
}
result = temp;
}
return result;
return sample;
}

View file

@ -25,7 +25,7 @@
G_BEGIN_DECLS
GstBuffer *
GstSample *
ges_play_sink_convert_frame (GstElement * playsink, GstCaps * caps);
G_END_DECLS

View file

@ -226,7 +226,7 @@ ges_timeline_pipeline_update_caps (GESTimelinePipeline * self)
if (track->type == GES_TRACK_TYPE_VIDEO)
caps = gst_caps_from_string ("video/x-raw-yuv;video/x-raw-rgb");
else if (track->type == GES_TRACK_TYPE_AUDIO)
gst_caps_from_string ("audio/x-raw-int;audio/x-raw-float");
caps = gst_caps_from_string ("audio/x-raw-int;audio/x-raw-float");
if (caps) {
ges_track_set_caps (track, caps);
@ -265,8 +265,8 @@ ges_timeline_pipeline_change_state (GstElement * element,
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");
@ -334,7 +334,7 @@ get_compatible_unlinked_pad (GstElement * element, GstPad * pad)
pads = gst_element_iterate_sink_pads (element);
else
pads = gst_element_iterate_src_pads (element);
srccaps = gst_pad_get_caps (pad, NULL);
srccaps = gst_pad_query_caps (pad, NULL);
GST_DEBUG ("srccaps %" GST_PTR_FORMAT, srccaps);
@ -345,7 +345,7 @@ get_compatible_unlinked_pad (GstElement * element, GstPad * pad)
GstPad *testpad = g_value_get_object (&paditem);
if (!gst_pad_is_linked (testpad)) {
GstCaps *sinkcaps = gst_pad_get_caps (testpad, NULL);
GstCaps *sinkcaps = gst_pad_query_caps (testpad, NULL);
GST_DEBUG ("sinkccaps %" GST_PTR_FORMAT, sinkcaps);
@ -389,7 +389,7 @@ pad_added_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
GstCaps *caps;
gboolean reconfigured = FALSE;
caps = gst_pad_get_caps (pad, NULL);
caps = gst_pad_query_caps (pad, NULL);
GST_DEBUG_OBJECT (self, "new pad %s:%s , caps:%" GST_PTR_FORMAT,
GST_DEBUG_PAD_NAME (pad), caps);
@ -492,7 +492,7 @@ pad_added_cb (GstElement * timeline, GstPad * pad, GESTimelinePipeline * self)
sinkpad = get_compatible_unlinked_pad (self->priv->encodebin, pad);
if (sinkpad == NULL) {
GstCaps *caps = gst_pad_get_caps (pad, NULL);
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,
@ -767,36 +767,33 @@ ges_timeline_pipeline_set_mode (GESTimelinePipeline * pipeline,
}
/**
* 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);
}
/**
@ -818,6 +815,7 @@ ges_timeline_pipeline_save_thumbnail (GESTimelinePipeline * self, int width, int
height, const gchar * format, const gchar * location)
{
GstBuffer *b;
GstSample *sample;
FILE *fp;
GstCaps *caps;
gboolean res = TRUE;
@ -832,11 +830,12 @@ ges_timeline_pipeline_save_thumbnail (GESTimelinePipeline * self, int width, int
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;
}
b = gst_sample_get_buffer (sample);
data = gst_buffer_map (b, &size, NULL, GST_MAP_READ);
/* FIXME : Use standard glib methods */
@ -849,6 +848,7 @@ ges_timeline_pipeline_save_thumbnail (GESTimelinePipeline * self, int width, int
gst_caps_unref (caps);
gst_buffer_unmap (b, data, size);
gst_buffer_unref (b);
gst_sample_unref (sample);
return res;
}
@ -859,23 +859,23 @@ ges_timeline_pipeline_save_thumbnail (GESTimelinePipeline * self, int width, int
* @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");
@ -886,7 +886,7 @@ ges_timeline_pipeline_get_thumbnail_rgb24 (GESTimelinePipeline * self,
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;
}

View file

@ -88,10 +88,10 @@ gboolean ges_timeline_pipeline_set_render_settings (GESTimelinePipeline *pipelin
gboolean ges_timeline_pipeline_set_mode (GESTimelinePipeline *pipeline,
GESPipelineFlags mode);
GstBuffer *
ges_timeline_pipeline_get_thumbnail_buffer(GESTimelinePipeline *self, GstCaps *caps);
GstSample *
ges_timeline_pipeline_get_thumbnail(GESTimelinePipeline *self, GstCaps *caps);
GstBuffer *
GstSample *
ges_timeline_pipeline_get_thumbnail_rgb24(GESTimelinePipeline *self,
gint width, gint height);

View file

@ -34,10 +34,8 @@ struct _GESTrackAudioTransitionPrivate
{
/* these enable volume interpolation. Unlike video, both inputs are adjusted
* simultaneously */
GstController *a_controller;
GstInterpolationControlSource *a_control_source;
GstController *b_controller;
GstInterpolationControlSource *b_control_source;
};
@ -94,12 +92,6 @@ ges_track_audio_transition_init (GESTrackAudioTransition * self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
GES_TYPE_TRACK_AUDIO_TRANSITION, GESTrackAudioTransitionPrivate);
self->priv->a_controller = NULL;
self->priv->a_control_source = NULL;
self->priv->b_controller = NULL;
self->priv->b_control_source = NULL;
}
static void
@ -109,17 +101,13 @@ ges_track_audio_transition_dispose (GObject * object)
self = GES_TRACK_AUDIO_TRANSITION (object);
if (self->priv->a_controller) {
g_object_unref (self->priv->a_controller);
self->priv->a_controller = NULL;
if (self->priv->a_control_source) {
if (self->priv->a_control_source)
gst_object_unref (self->priv->a_control_source);
self->priv->a_control_source = NULL;
}
if (self->priv->b_controller) {
g_object_unref (self->priv->b_controller);
self->priv->b_controller = NULL;
if (self->priv->b_control_source) {
if (self->priv->b_control_source)
gst_object_unref (self->priv->b_control_source);
self->priv->b_control_source = NULL;
@ -159,6 +147,7 @@ link_element_to_mixer_with_volume (GstBin * bin, GstElement * element,
GstElement * mixer)
{
GstElement *volume = gst_element_factory_make ("volume", NULL);
gst_bin_add (bin, volume);
if (!fast_element_link (element, volume) ||
@ -178,7 +167,6 @@ ges_track_audio_transition_create_element (GESTrackObject * object)
const gchar *propname = "volume";
GstElement *mixer = NULL;
GstPad *sinka_target, *sinkb_target, *src_target, *sinka, *sinkb, *src;
GstController *acontroller, *bcontroller;
GstInterpolationControlSource *acontrol_source, *bcontrol_source;
self = GES_TRACK_AUDIO_TRANSITION (object);
@ -221,29 +209,16 @@ ges_track_audio_transition_create_element (GESTrackObject * object)
gst_object_unref (sinkb_target);
gst_object_unref (src_target);
//g_object_set(atarget, propname, (gdouble) 0, NULL);
//g_object_set(btarget, propname, (gdouble) 0, NULL);
acontroller = gst_object_control_properties (atarget, propname, NULL);
bcontroller = gst_object_control_properties (btarget, propname, NULL);
g_assert (acontroller && bcontroller);
acontrol_source = gst_interpolation_control_source_new ();
gst_controller_set_control_source (acontroller,
propname, GST_CONTROL_SOURCE (acontrol_source));
gst_interpolation_control_source_set_interpolation_mode (acontrol_source,
GST_INTERPOLATE_LINEAR);
gst_object_set_control_source (GST_OBJECT (atarget), propname,
GST_CONTROL_SOURCE (acontrol_source));
g_object_set (acontrol_source, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
bcontrol_source = gst_interpolation_control_source_new ();
gst_controller_set_control_source (bcontroller,
propname, GST_CONTROL_SOURCE (bcontrol_source));
gst_interpolation_control_source_set_interpolation_mode (bcontrol_source,
GST_INTERPOLATE_LINEAR);
gst_object_set_control_source (GST_OBJECT (btarget), propname,
GST_CONTROL_SOURCE (bcontrol_source));
g_object_set (acontrol_source, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
self->priv->a_controller = acontroller;
self->priv->b_controller = bcontroller;
self->priv->a_control_source = acontrol_source;
self->priv->b_control_source = bcontrol_source;
@ -256,36 +231,29 @@ ges_track_audio_transition_duration_changed (GESTrackObject * object,
{
GESTrackAudioTransition *self;
GstElement *gnlobj = ges_track_object_get_gnlobject (object);
GValue zero = { 0, };
GValue one = { 0, };
GstTimedValueControlSource *ta, *tb;
self = GES_TRACK_AUDIO_TRANSITION (object);
GST_LOG ("updating controller: gnlobj (%p) acontroller(%p) bcontroller(%p)",
gnlobj, self->priv->a_controller, self->priv->b_controller);
GST_LOG ("updating controller: gnlobj (%p)", gnlobj);
if (G_UNLIKELY ((!gnlobj || !self->priv->a_control_source ||
!self->priv->b_control_source)))
return;
GST_INFO ("duration: %" G_GUINT64_FORMAT, duration);
g_value_init (&zero, G_TYPE_DOUBLE);
g_value_init (&one, G_TYPE_DOUBLE);
g_value_set_double (&zero, 0.0);
g_value_set_double (&one, 1.0);
GST_LOG ("setting values on controller");
ta = GST_TIMED_VALUE_CONTROL_SOURCE (self->priv->a_control_source);
tb = GST_TIMED_VALUE_CONTROL_SOURCE (self->priv->b_control_source);
gst_interpolation_control_source_unset_all (self->priv->a_control_source);
gst_interpolation_control_source_set (self->priv->a_control_source, 0, &one);
gst_interpolation_control_source_set (self->priv->a_control_source,
duration, &zero);
gst_timed_value_control_source_unset_all (ta);
gst_timed_value_control_source_set (ta, 0, 1.0);
gst_timed_value_control_source_set (ta, duration, 0.0);
gst_interpolation_control_source_unset_all (self->priv->b_control_source);
gst_interpolation_control_source_set (self->priv->b_control_source, 0, &zero);
gst_interpolation_control_source_set (self->priv->b_control_source, duration,
&one);
gst_timed_value_control_source_unset_all (tb);
gst_timed_value_control_source_set (tb, 0, 0.0);
gst_timed_value_control_source_set (tb, duration, 1.0);
GST_LOG ("done updating controller");
}

View file

@ -23,7 +23,6 @@
#include <glib-object.h>
#include <gst/gst.h>
#include <gst/controller/gstcontroller.h>
#include <gst/controller/gstinterpolationcontrolsource.h>
#include <ges/ges-types.h>
#include <ges/ges-track-operation.h>

View file

@ -34,7 +34,6 @@ struct _GESTrackVideoTransitionPrivate
GESVideoStandardTransitionType type;
/* these enable video interpolation */
GstController *controller;
GstInterpolationControlSource *control_source;
/* so we can support changing between wipes */
@ -106,7 +105,6 @@ ges_track_video_transition_init (GESTrackVideoTransition * self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
GES_TYPE_TRACK_VIDEO_TRANSITION, GESTrackVideoTransitionPrivate);
self->priv->controller = NULL;
self->priv->control_source = NULL;
self->priv->smpte = NULL;
self->priv->mixer = NULL;
@ -127,9 +125,7 @@ ges_track_video_transition_dispose (GObject * object)
GST_LOG ("mixer: %p smpte: %p sinka: %p sinkb: %p",
priv->mixer, priv->smpte, priv->sinka, priv->sinkb);
if (priv->controller) {
g_object_unref (priv->controller);
priv->controller = NULL;
if (priv->control_source) {
if (priv->control_source)
gst_object_unref (priv->control_source);
priv->control_source = NULL;
@ -185,7 +181,7 @@ on_caps_set (GstPad * srca_pad, GParamSpec * pspec, GstElement * capsfilt)
{
GstCaps *orig_caps;
orig_caps = gst_pad_get_caps (srca_pad, NULL);
orig_caps = gst_pad_query_caps (srca_pad, NULL);
if (orig_caps) {
gint width, height;
@ -214,7 +210,6 @@ ges_track_video_transition_create_element (GESTrackObject * object)
GstElement *mixer = NULL;
GstPad *sinka_target, *sinkb_target, *src_target, *sinka, *sinkb, *src,
*srca_pad;
GstController *controller;
GstInterpolationControlSource *control_source;
GESTrackVideoTransition *self;
GESTrackVideoTransitionPrivate *priv;
@ -239,6 +234,7 @@ ges_track_video_transition_create_element (GESTrackObject * object)
mixer = gst_element_factory_make ("videomixer2", NULL);
if (mixer == NULL)
mixer = gst_element_factory_make ("videomixer", NULL);
g_assert (mixer);
g_object_set (G_OBJECT (mixer), "background", 1, NULL);
gst_bin_add (GST_BIN (topbin), mixer);
@ -298,15 +294,11 @@ ges_track_video_transition_create_element (GESTrackObject * object)
g_object_set (target, propname, (gfloat) 0.0, NULL);
controller = gst_object_control_properties (target, propname, NULL);
control_source = gst_interpolation_control_source_new ();
gst_controller_set_control_source (controller,
propname, GST_CONTROL_SOURCE (control_source));
gst_interpolation_control_source_set_interpolation_mode (control_source,
GST_INTERPOLATE_LINEAR);
gst_object_set_control_source (GST_OBJECT (target), propname,
GST_CONTROL_SOURCE (control_source));
g_object_set (control_source, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
priv->controller = controller;
priv->control_source = control_source;
return topbin;
@ -354,29 +346,24 @@ static void
ges_track_video_transition_duration_changed (GESTrackObject * object,
guint64 duration)
{
GValue start_value = { 0, };
GValue end_value = { 0, };
GstElement *gnlobj = ges_track_object_get_gnlobject (object);
GESTrackVideoTransition *self = GES_TRACK_VIDEO_TRANSITION (object);
GESTrackVideoTransitionPrivate *priv = self->priv;
GstTimedValueControlSource *ts;
GST_LOG ("updating controller");
if (G_UNLIKELY (!gnlobj || !priv->control_source))
return;
GST_INFO ("duration: %" G_GUINT64_FORMAT, duration);
g_value_init (&start_value, G_TYPE_DOUBLE);
g_value_init (&end_value, G_TYPE_DOUBLE);
g_value_set_double (&start_value, priv->start_value);
g_value_set_double (&end_value, priv->end_value);
ts = GST_TIMED_VALUE_CONTROL_SOURCE (priv->control_source);
GST_INFO ("duration: %" G_GUINT64_FORMAT, duration);
GST_LOG ("setting values on controller");
gst_interpolation_control_source_unset_all (priv->control_source);
gst_interpolation_control_source_set (priv->control_source, 0, &start_value);
gst_interpolation_control_source_set (priv->control_source,
duration, &end_value);
gst_timed_value_control_source_unset_all (ts);
gst_timed_value_control_source_set (ts, 0, priv->start_value);
gst_timed_value_control_source_set (ts, duration, priv->end_value);
GST_LOG ("done updating controller");
}

View file

@ -19,7 +19,6 @@
*/
#include <ges/ges.h>
#include <gst/controller/gstcontroller.h>
#include "ges-internal.h"
#define GES_GNONLIN_VERSION_NEEDED_MAJOR 0
@ -63,7 +62,6 @@ ges_init (void)
/* initialize debugging category */
GST_DEBUG_CATEGORY_INIT (_ges_debug, "ges", GST_DEBUG_FG_YELLOW,
"GStreamer Editing Services");
gst_controller_init (NULL, NULL);
/* register timeline object classes with the system */