4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hyuntae Kim <ht1211.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #ifndef __MM_STREAMRECORDER_GSTCOMMON_H__
23 #define __MM_STREAMRECORDER_GSTCOMMON_H__
25 /*=======================================================================================
27 ========================================================================================*/
34 /*=======================================================================================
35 | GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER |
36 ========================================================================================*/
38 /*=======================================================================================
40 ========================================================================================*/
42 /* gstreamer element creation macro */
43 #define _MMSTREAMRECORDER_PIPELINE_MAKE(sub_context, element, eid, name /*char* */, err) \
44 if (element[eid].gst != NULL) { \
45 _mmstreamrec_dbg_err("The element(Pipeline) is existed. element_id=[%d], name=[%s]", eid, name); \
46 gst_object_unref(element[eid].gst); \
48 element[eid].id = eid; \
49 element[eid].gst = gst_pipeline_new(name); \
50 if (element[eid].gst == NULL) { \
51 _mmstreamrec_dbg_err("Pipeline creation fail. element_id=[%d], name=[%s]", eid, name); \
52 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; \
53 goto pipeline_creation_error; \
55 g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
58 #define _MMSTREAMRECORDER_BIN_MAKE(sub_context, element, eid, name /*char* */, err) \
59 if (element[eid].gst != NULL) { \
60 _mmstreamrec_dbg_err("The element(Bin) is existed. element_id=[%d], name=[%s]", eid, name); \
61 gst_object_unref(element[eid].gst); \
63 element[eid].id = eid; \
64 element[eid].gst = gst_bin_new(name); \
65 if (element[eid].gst == NULL) { \
66 _mmstreamrec_dbg_err("Bin creation fail. element_id=[%d], name=[%s]\n", eid, name); \
67 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; \
68 goto pipeline_creation_error; \
70 g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
73 #define _MMSTREAMRECORDER_ELEMENT_MAKE(sub_context, element, eid, name /*char* */, nickname /*char* */, elist, err) \
74 if (element[eid].gst != NULL) { \
75 _mmstreamrec_dbg_err("The element is existed. element_id=[%d], name=[%s]", eid, name); \
76 gst_object_unref(element[eid].gst); \
78 element[eid].gst = gst_element_factory_make(name, nickname); \
79 if (element[eid].gst == NULL) { \
80 _mmstreamrec_dbg_err("Element creation fail. element_id=[%d], name=[%s]", eid, name); \
81 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; \
82 goto pipeline_creation_error; \
84 _mmstreamrec_dbg_err("Element creation done. element_id=[%d], name=[%s]", eid, name); \
85 element[eid].id = eid; \
86 g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
87 err = MM_ERROR_NONE; \
89 elist = g_list_append(elist, &(element[eid]));
91 #define _MMSTREAMRECORDER_ELEMENT_MAKE_IGNORE_ERROR(sub_context, element, eid, name /*char* */, nickname /*char* */, elist) \
92 if (element[eid].gst != NULL) { \
93 _mmstreamrec_dbg_err("The element is existed. element_id=[%d], name=[%s]", eid, name); \
94 gst_object_unref(element[eid].gst); \
96 element[eid].gst = gst_element_factory_make(name, nickname); \
97 if (element[eid].gst == NULL) { \
98 _mmstreamrec_dbg_err("Element creation fail. element_id=[%d], name=[%s], but keep going...", eid, name); \
100 _mmstreamrec_dbg_err("Element creation done. element_id=[%d], name=[%s]", eid, name); \
101 element[eid].id = eid; \
102 g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
103 elist = g_list_append(elist, &(element[eid])); \
106 #define _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sub_context, eid, name /*char* */, err) \
107 if (sub_context->encode_element[eid].gst != NULL) { \
108 _mmstreamrec_dbg_err("The element is existed. element_id=[%d], name=[%s]", eid, name); \
109 gst_object_unref(sub_context->encode_element[eid].gst); \
111 sub_context->encode_element[eid].id = eid; \
112 g_object_get(G_OBJECT(sub_context->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst), name, &(sub_context->encode_element[eid].gst), NULL); \
113 if (sub_context->encode_element[eid].gst == NULL) { \
114 _mmstreamrec_dbg_err("Encode Element get fail. element_id=[%d], name=[%s]", eid, name); \
115 err = MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; \
116 goto pipeline_creation_error; \
118 gst_object_unref(sub_context->encode_element[eid].gst); \
119 g_object_weak_ref(G_OBJECT(sub_context->encode_element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
122 /* GStreamer element remove macro */
123 #define _MMSTREAMRECORDER_ELEMENT_REMOVE(element, eid) \
125 if (element[eid].gst != NULL) { \
126 gst_object_unref(element[eid].gst); \
130 #define _MM_GST_ELEMENT_LINK_MANY gst_element_link_many
131 #define _MM_GST_ELEMENT_LINK gst_element_link
132 #define _MM_GST_PAD_LINK gst_pad_link
134 #define _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, if_fail_goto)\
136 GstPadLinkReturn ret = _MM_GST_PAD_LINK(srcpad, sinkpad);\
137 if (ret != GST_PAD_LINK_OK) {\
138 GstObject *src_parent = gst_pad_get_parent(srcpad);\
139 GstObject *sink_parent = gst_pad_get_parent(sinkpad);\
140 char *src_name = NULL;\
141 char *sink_name = NULL;\
142 g_object_get((GObject *)src_parent, "name", &src_name, NULL);\
143 g_object_get((GObject *)sink_parent, "name", &sink_name, NULL);\
144 _mmstreamrec_dbg_err("src[%s] - sink[%s] link failed", src_name, sink_name);\
145 gst_object_unref(src_parent); src_parent = NULL;\
146 gst_object_unref(sink_parent); sink_parent = NULL;\
148 free(src_name); src_name = NULL;\
151 free(sink_name); sink_name = NULL;\
153 gst_object_unref(srcpad); srcpad = NULL;\
154 gst_object_unref(sinkpad); sinkpad = NULL;\
155 err = MM_ERROR_STREAMRECORDER_GST_LINK;\
158 gst_object_unref(srcpad); srcpad = NULL;\
159 gst_object_unref(sinkpad); sinkpad = NULL;\
162 #define _MM_GST_PAD_UNLINK_UNREF(srcpad, sinkpad) \
163 if (srcpad && sinkpad) { \
164 gst_pad_unlink(srcpad, sinkpad); \
166 _mmstreamrec_dbg_warn("some pad(srcpad:%p,sinkpad:%p) is NULL", srcpad, sinkpad); \
169 gst_object_unref(srcpad); srcpad = NULL; \
172 gst_object_unref(sinkpad); sinkpad = NULL; \
175 /*=======================================================================================
177 ========================================================================================*/
182 typedef enum _MMStreamRecorderEncodebinProfile {
183 MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO = 0, /**< Video recording profile */
184 MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO, /**< Audio recording profile */
185 MM_STREAMRECORDER_ENCBIN_PROFILE_IMAGE, /**< Image capture profile */
186 MM_STREAMRECORDER_ENCBIN_PROFILE_NUM
187 } MMStreamRecorderEncodebinProfile;
189 #define __MMSTREAMRECORDER_SET_GST_STATE_TIMEOUT 5
191 /*=======================================================================================
192 | STRUCTURE DEFINITIONS |
193 ========================================================================================*/
195 * Element name table.
196 * @note if name is NULL, not supported.
199 unsigned int prof_id; /**< id of mmstreamrecorder_profile_attrs_id */
200 unsigned int id; /**< id of value id */
201 char *name; /**< gstreamer element name*/
202 } _MMStreamRecorderElementName;
205 * MMstreamrecorder Gstreamer Element
208 unsigned int id; /**< Gstreamer piplinem element name */
209 GstElement *gst; /**< Gstreamer element */
210 } _MMStreamRecorderGstElement;
212 /*=======================================================================================
213 | CONSTANT DEFINITIONS |
214 ========================================================================================*/
216 /*=======================================================================================
218 ========================================================================================*/
220 /*=======================================================================================
221 | EXTERN GLOBAL VARIABLE |
222 ========================================================================================*/
224 /*=======================================================================================
225 | GLOBAL FUNCTION PROTOTYPES |
226 ========================================================================================*/
228 gboolean _mmstreamrecorder_gstreamer_init();
231 int _mmstreamrecorder_get_eos_message(MMHandleType handle);
232 void _mmstreamrecorder_remove_element_handle(MMHandleType handle, void *element, int first_elem, int last_elem);
233 gboolean _mmstreamrecorder_add_elements_to_bin(GstBin *bin, GList *element_list);
234 gboolean _mmstreamrecorder_link_elements(GList *element_list);
237 * This function sets gstreamer element status.
238 * If the gstreamer fails to set status or returns asynchronous mode,
239 * this function waits for state changed until timeout expired.
241 * @param[in] pipeline Pointer of pipeline
242 * @param[in] target_state newly setting status
243 * @return This function returns zero on success, or negative value with error code.
248 int _mmstreamrecorder_gst_set_state(MMHandleType handle, GstElement *pipeline, GstState target_state);
249 GstCaps *gst_set_videosrcpad_caps(gint srcfmt, gint width, gint height, gint rate, gint scale);
250 GstCaps *gst_set_audiosrcpad_caps(gint samplerate, gint channel, gint depth, gint width, gint datatype);
255 #endif /* __MM_STREAMRECORDER_GSTCOMMON_H__ */