2b832ea9d710a48b93d7aa6eaf3cfc758d77f7fe
[platform/core/multimedia/libmm-streamrecorder.git] / src / include / mm_streamrecorder_gstcommon.h
1 /*
2  * libmm-streamrecorder
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyuntae Kim <ht1211.kim@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #ifndef __MM_STREAMRECORDER_GSTCOMMON_H__
23 #define __MM_STREAMRECORDER_GSTCOMMON_H__
24
25 /*=======================================================================================
26 | INCLUDE FILES                                                                         |
27 ========================================================================================*/
28 #include <mm_types.h>
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 /*=======================================================================================
35 | GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                        |
36 ========================================================================================*/
37
38 /*=======================================================================================
39 | MACRO DEFINITIONS                                                                     |
40 ========================================================================================*/
41
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); \
47         } \
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; \
54         } else { \
55                 g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
56         }
57
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); \
62         } \
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; \
69         } else { \
70                 g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmstreamrecorder_element_release_noti/*NULL*/, sub_context); \
71         }
72
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); \
77         } \
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; \
83         } else { \
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; \
88         } \
89         elist = g_list_append(elist, &(element[eid]));
90
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); \
95         } \
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); \
99         } else { \
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])); \
104         }
105
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); \
110         } \
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; \
117         } else{ \
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); \
120         }
121
122 /* GStreamer element remove macro */
123 #define _MMSTREAMRECORDER_ELEMENT_REMOVE(element, eid) \
124         if (element[eid].gst != NULL) { \
125                 gst_object_unref(element[eid].gst); \
126         }
127
128 #define _MM_GST_ELEMENT_LINK_MANY       gst_element_link_many
129 #define _MM_GST_ELEMENT_LINK            gst_element_link
130 #define _MM_GST_PAD_LINK                gst_pad_link
131
132 #define _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, if_fail_goto)\
133 {\
134         GstPadLinkReturn ret = _MM_GST_PAD_LINK(srcpad, sinkpad);\
135         if (ret != GST_PAD_LINK_OK) {\
136                 GstObject *src_parent = gst_pad_get_parent(srcpad);\
137                 GstObject *sink_parent = gst_pad_get_parent(sinkpad);\
138                 char *src_name = NULL;\
139                 char *sink_name = NULL;\
140                 g_object_get((GObject *)src_parent, "name", &src_name, NULL);\
141                 g_object_get((GObject *)sink_parent, "name", &sink_name, NULL);\
142                 _mmstreamrec_dbg_err("src[%s] - sink[%s] link failed", src_name, sink_name);\
143                 gst_object_unref(src_parent); src_parent = NULL;\
144                 gst_object_unref(sink_parent); sink_parent = NULL;\
145                 if (src_name) {\
146                         free(src_name); src_name = NULL;\
147                 }\
148                 if (sink_name) {\
149                         free(sink_name); sink_name = NULL;\
150                 }\
151                 gst_object_unref(srcpad); srcpad = NULL;\
152                 gst_object_unref(sinkpad); sinkpad = NULL;\
153                 err = MM_ERROR_STREAMRECORDER_GST_LINK;\
154                 goto if_fail_goto;\
155         }\
156         gst_object_unref(srcpad); srcpad = NULL;\
157         gst_object_unref(sinkpad); sinkpad = NULL;\
158 }
159
160 #define _MM_GST_PAD_UNLINK_UNREF( srcpad, sinkpad) \
161         if (srcpad && sinkpad) { \
162                 gst_pad_unlink(srcpad, sinkpad); \
163         } else { \
164                 _mmstreamrec_dbg_warn("some pad(srcpad:%p,sinkpad:%p) is NULL", srcpad, sinkpad); \
165         } \
166         if (srcpad) { \
167                 gst_object_unref(srcpad); srcpad = NULL; \
168         } \
169         if (sinkpad) { \
170                 gst_object_unref(sinkpad); sinkpad = NULL; \
171         }
172
173 /*=======================================================================================
174 | ENUM DEFINITIONS                                                                      |
175 ========================================================================================*/
176
177 /**
178 * Encodebin profile
179 */
180 typedef enum _MMStreamRecorderEncodebinProfile {
181         MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO = 0,      /**< Video recording profile */
182         MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO,          /**< Audio recording profile */
183         MM_STREAMRECORDER_ENCBIN_PROFILE_IMAGE,          /**< Image capture profile */
184         MM_STREAMRECORDER_ENCBIN_PROFILE_NUM
185 } MMStreamRecorderEncodebinProfile;
186
187 #define __MMSTREAMRECORDER_SET_GST_STATE_TIMEOUT     5
188
189 /*=======================================================================================
190 | STRUCTURE DEFINITIONS                                                                 |
191 ========================================================================================*/
192 /**
193  * Element name table.
194  * @note if name is NULL, not supported.
195  */
196 typedef struct {
197         unsigned int prof_id;   /**< id of mmstreamrecorder_profile_attrs_id */
198         unsigned int id;        /**< id of value id */
199         char *name;             /**< gstreamer element name*/
200 } _MMStreamRecorderElementName;
201
202 /**
203  * MMstreamrecorder Gstreamer Element
204  */
205 typedef struct {
206         unsigned int id;        /**< Gstreamer piplinem element name */
207         GstElement *gst;        /**< Gstreamer element */
208 } _MMStreamRecorderGstElement;
209
210 /*=======================================================================================
211 | CONSTANT DEFINITIONS                                                                  |
212 ========================================================================================*/
213
214 /*=======================================================================================
215 | STATIC VARIABLES                                                                      |
216 ========================================================================================*/
217
218 /*=======================================================================================
219 | EXTERN GLOBAL VARIABLE                                                                |
220 ========================================================================================*/
221
222 /*=======================================================================================
223 | GLOBAL FUNCTION PROTOTYPES                                                            |
224 ========================================================================================*/
225
226 gboolean _mmstreamrecorder_gstreamer_init();
227
228 /* etc */
229 int _mmstreamrecorder_get_eos_message(MMHandleType handle);
230 void _mmstreamrecorder_remove_element_handle(MMHandleType handle, void *element, int first_elem, int last_elem);
231 gboolean _mmstreamrecorder_add_elements_to_bin(GstBin *bin, GList *element_list);
232 gboolean _mmstreamrecorder_link_elements(GList *element_list);
233
234 /**
235  * This function sets gstreamer element status.
236  * If the gstreamer fails to set status or returns asynchronous mode,
237  * this function waits for state changed until timeout expired.
238  *
239  * @param[in]   pipeline        Pointer of pipeline
240  * @param[in]   target_state    newly setting status
241  * @return      This function returns zero on success, or negative value with error code.
242  * @remarks
243  * @see
244  *
245  */
246 int _mmstreamrecorder_gst_set_state(MMHandleType handle, GstElement *pipeline, GstState target_state);
247 GstCaps *gst_set_videosrcpad_caps(gint srcfmt, gint width, gint height, gint rate, gint scale);
248 GstCaps *gst_set_audiosrcpad_caps(gint samplerate, gint channel, gint depth, gint width, gint datatype);
249
250 #ifdef __cplusplus
251 }
252 #endif
253 #endif /* __MM_STREAMRECORDER_GSTCOMMON_H__ */