62
62
* gst_camerabin_preview_create_pipeline:
63
* @element: #GstCameraBin element
63
64
* @caps: pointer to the caps used in pipeline
65
* @src_filter: source filter element
65
67
* Create a preview converter pipeline that outputs the format defined in
68
* Returns: New pipeline, or NULL if error occured.
70
* Returns: New pipeline data structure, or NULL if error occured.
71
gst_camerabin_preview_create_pipeline (GstCameraBin * camera, GstCaps * caps,
72
GstCameraBinPreviewPipelineData *
73
gst_camerabin_preview_create_pipeline (GstElement * element, GstCaps * caps,
72
74
GstElement * src_filter)
74
GstElement *pipe, *src, *csp, *filter, *vscale, *sink;
76
GstElement *csp = NULL, *vscale = NULL;
75
77
GError *error = NULL;
78
GstCameraBinPreviewPipelineData *data;
77
g_return_val_if_fail (caps != NULL, FALSE);
80
g_return_val_if_fail (caps != NULL, NULL);
79
82
GST_DEBUG ("creating elements");
81
if (!create_element ("appsrc", "prev_src", &src, &error) ||
82
!create_element ("videoscale", NULL, &vscale, &error) ||
83
!create_element ("ffmpegcolorspace", NULL, &csp, &error) ||
84
!create_element ("capsfilter", NULL, &filter, &error) ||
85
!create_element ("fakesink", "prev_sink", &sink, &error))
84
data = g_new (GstCameraBinPreviewPipelineData, 1);
88
86
/* We have multiple pipelines created by using this function, so we can't
89
87
* give a name to them. Another way would to ensure the uniqueness of the
91
pipe = gst_pipeline_new (NULL);
89
data->pipeline = gst_pipeline_new (NULL);
93
if (!create_element ("appsrc", "prev_src", &data->appsrc, &error) ||
94
!create_element ("videoscale", NULL, &vscale, &error) ||
95
!create_element ("ffmpegcolorspace", NULL, &csp, &error) ||
96
!create_element ("capsfilter", NULL, &data->capsfilter, &error) ||
97
!create_element ("fakesink", "prev_sink", &data->appsink, &error))
95
100
GST_DEBUG ("adding elements");
96
gst_bin_add_many (GST_BIN (pipe), src, csp, filter, vscale, sink, NULL);
101
gst_bin_add_many (GST_BIN (data->pipeline), data->appsrc, csp,
102
data->capsfilter, vscale, data->appsink, NULL);
98
gst_bin_add (GST_BIN (pipe), src_filter);
104
gst_bin_add (GST_BIN (data->pipeline), src_filter);
107
data->element = element;
101
109
GST_DEBUG ("preview format is: %" GST_PTR_FORMAT, caps);
103
g_object_set (filter, "caps", caps, NULL);
104
g_object_set (sink, "preroll-queue-len", 1, "signal-handoffs", TRUE, NULL);
111
g_object_set (data->capsfilter, "caps", caps, NULL);
112
g_object_set (data->appsink, "preroll-queue-len", 1, "signal-handoffs", TRUE,
105
114
g_object_set (vscale, "method", 0, NULL);
107
/* FIXME: linking is still way too expensive, profile this properly */
108
116
GST_DEBUG ("linking src->vscale");
109
if (!gst_element_link_pads_full (src, "src", vscale, "sink",
110
GST_PAD_LINK_CHECK_CAPS))
117
if (!gst_element_link_pads (data->appsrc, "src", vscale, "sink"))
113
120
if (src_filter) {
114
GST_DEBUG ("linking vscale->filter");
115
if (!gst_element_link_pads_full (vscale, "src", src_filter, "sink",
116
GST_PAD_LINK_CHECK_CAPS)) {
121
GST_DEBUG ("linking vscale->src_filter");
122
if (!gst_element_link_pads (vscale, "src", src_filter, "sink")) {
119
125
GST_DEBUG ("linking filter->csp");
120
if (!gst_element_link_pads_full (src_filter, "src", csp, "sink",
121
GST_PAD_LINK_CHECK_CAPS)) {
126
if (!gst_element_link_pads (src_filter, "src", csp, "sink")) {
125
130
GST_DEBUG ("linking vscale->csp");
126
if (!gst_element_link_pads_full (vscale, "src", csp, "sink",
127
GST_PAD_LINK_CHECK_CAPS))
131
if (!gst_element_link_pads (vscale, "src", csp, "sink"))
131
135
GST_DEBUG ("linking csp->capsfilter");
132
if (!gst_element_link_pads_full (csp, "src", filter, "sink",
133
GST_PAD_LINK_CHECK_CAPS))
136
if (!gst_element_link_pads (csp, "src", data->capsfilter, "sink"))
136
139
GST_DEBUG ("linking capsfilter->sink");
137
if (!gst_element_link_pads_full (filter, "src", sink, "sink",
138
GST_PAD_LINK_CHECK_CAPS))
146
g_warning ("Could not make preview pipeline: %s", error->message);
140
if (!gst_element_link_pads (data->capsfilter, "src", data->appsink, "sink"))
147
GST_WARNING ("Preview pipeline element creation failed: %s",
147
149
g_error_free (error);
152
g_warning ("Could not make preview pipeline: %s",
153
"no pipeline (unknown error)");
152
gst_object_unref (csp);
154
gst_object_unref (vscale);
156
gst_object_unref (data->appsrc);
157
if (data->capsfilter)
158
gst_object_unref (data->capsfilter);
160
gst_object_unref (data->appsink);
163
GST_WARNING ("Could not create preview pipeline");
164
gst_camerabin_preview_destroy_pipeline (data);
160
171
* gst_camerabin_preview_destroy_pipeline:
161
* @camera: camerabin object
162
* @pipeline: the pipeline to be destroyed
172
* @data: the pipeline data to be destroyed
164
174
* Destroy preview converter pipeline.
167
gst_camerabin_preview_destroy_pipeline (GstCameraBin * camera,
168
GstElement * pipeline)
177
gst_camerabin_preview_destroy_pipeline (GstCameraBinPreviewPipelineData * data)
170
g_return_if_fail (pipeline != NULL);
172
gst_element_set_state (pipeline, GST_STATE_NULL);
173
gst_object_unref (pipeline);
179
if (data->pipeline) {
180
gst_element_set_state (data->pipeline, GST_STATE_NULL);
181
gst_object_unref (data->pipeline);
178
188
* gst_camerabin_preview_convert:
179
* @camera: camerabin object
180
* @pipeline: preview pipeline to use
189
* @data: preview pipeline data to use
181
190
* @buf: #GstBuffer that contains the frame to be converted
183
192
* Create a preview image of the given frame.
305
315
* Returns: True if the event was handled
308
gst_camerabin_preview_send_event (GstCameraBin * camera, GstElement * pipeline,
318
gst_camerabin_preview_send_event (GstCameraBinPreviewPipelineData * data,
312
gboolean ret = FALSE;
314
src = gst_bin_get_by_name (GST_BIN (pipeline), "prev_src");
323
src = gst_bin_get_by_name (GST_BIN (data->pipeline), "prev_src");
316
325
GST_WARNING ("Preview pipeline doesn't have src element, can't push event");
317
326
gst_event_unref (evt);
319
GST_DEBUG_OBJECT (camera, "Pushing event %p to preview pipeline", evt);
320
ret = gst_element_send_event (src, evt);
321
gst_object_unref (src);
330
GST_DEBUG_OBJECT (data->element, "Pushing event %p to preview pipeline", evt);
332
return gst_element_send_event (src, evt);
336
* gst_camerabin_preview_set_caps:
337
* @data: preview pipeline data to use
338
* @caps: New #GstCaps to be set for the pipeline
340
* Sets new caps for the preview pipeline
343
gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * data,
346
GstState state, pending;
347
GstStateChangeReturn ret;
349
g_return_if_fail (data->pipeline != NULL);
350
g_return_if_fail (caps != NULL);
352
ret = gst_element_get_state (data->pipeline, &state, &pending, 0);
353
if (ret == GST_STATE_CHANGE_FAILURE) {
354
/* make it try again */
355
state = GST_STATE_PLAYING;
356
pending = GST_STATE_VOID_PENDING;
359
gst_element_set_state (data->pipeline, GST_STATE_NULL);
360
g_object_set (data->capsfilter, "caps", caps, NULL);
361
if (pending != GST_STATE_VOID_PENDING)
363
gst_element_set_state (data->pipeline, state);