fix double free
[platform/core/multimedia/libmm-streamrecorder.git] / src / include / mm_streamrecorder_gstdispatch.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_GSTDISPATCH_H__
23 #define __MM_STREAMRECORDER_GSTDISPATCH_H__
24
25 /*=======================================================================================
26 | INCLUDE FILES                                                                         |
27 ========================================================================================*/
28 #include "mm_streamrecorder_util.h"
29 #include <gst/gst.h>
30 #include <gst/gstutils.h>
31 #include <gst/gstpad.h>
32 #include <mm_types.h>
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 /*=======================================================================================
39 | GLOBAL DEFINITIONS AND DECLARATIONS FOR STREAMRECORDER                                        |
40 ========================================================================================*/
41
42 /*=======================================================================================
43 | MACRO DEFINITIONS                                                                     |
44 ========================================================================================*/
45
46 #define MMSTREAMRECORDER_ADD_BUFFER_PROBE(x_pad, x_category, x_callback, x_hstreamrecorder) \
47 do { \
48         MMStreamRecorderHandlerItem *item = NULL; \
49         item = (MMStreamRecorderHandlerItem *)g_malloc(sizeof(MMStreamRecorderHandlerItem)); \
50         if (!item) {\
51                 _mmstreamrec_dbg_err("Cannot connect buffer probe [malloc fail] \n"); \
52         } else if (x_category == 0 || !(x_category & _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL)) { \
53                 _mmstreamrec_dbg_err("Invalid handler category : %x \n", x_category); \
54         } else { \
55                 item->object = G_OBJECT(x_pad); \
56                 item->category = x_category; \
57                 item->handler_id = gst_pad_add_probe(x_pad, GST_PAD_PROBE_TYPE_BUFFER, x_callback, x_hstreamrecorder, NULL); \
58                 x_hstreamrecorder->buffer_probes = g_list_append(x_hstreamrecorder->buffer_probes, item); \
59                 _mmstreamrec_dbg_log("Adding buffer probe on [%s:%s] - [ID : %lu], [Category : %x] ", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category); \
60         } \
61 } while (0)
62
63 #define MMSTREAMRECORDER_ADD_EVENT_PROBE(x_pad, x_category, x_callback, x_hstreamrecorder) \
64 do { \
65         MMStreamRecorderHandlerItem *item = NULL; \
66         item = (MMStreamRecorderHandlerItem *) g_malloc(sizeof(MMStreamRecorderHandlerItem)); \
67         if (!item) { \
68                 _mmstreamrec_dbg_err("Cannot connect buffer probe [malloc fail] \n"); \
69         } \
70         else if (x_category == 0 || !(x_category & _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL)) { \
71                 _mmstreamrec_dbg_err("Invalid handler category : %x \n", x_category); \
72         } else { \
73                 item->object = G_OBJECT(x_pad); \
74                 item->category = x_category; \
75                 item->handler_id = gst_pad_add_probe(x_pad, GST_PAD_PROBE_TYPE_EVENT_BOTH, x_callback, x_hstreamrecorder, NULL); \
76                 x_hstreamrecorder->event_probes = g_list_append(x_hstreamrecorder->event_probes, item); \
77                 _mmstreamrec_dbg_log("Adding event probe on [%s:%s] - [ID : %lu], [Category : %x] ", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category); \
78         } \
79 } while (0);
80
81 #define MMSTREAMRECORDER_ADD_DATA_PROBE(x_pad, x_category, x_callback, x_hstreamrecorder) \
82 do { \
83         MMStreamRecorderHandlerItem *item = NULL; \
84         item = (MMStreamRecorderHandlerItem *) g_malloc(sizeof(MMStreamRecorderHandlerItem)); \
85         if (!item) { \
86                 _mmstreamrec_dbg_err("Cannot connect buffer probe [malloc fail] \n"); \
87         } else if (x_category == 0 || !(x_category & _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL)) { \
88                 _mmstreamrec_dbg_err("Invalid handler category : %x \n", x_category); \
89         } else { \
90                 item->object = G_OBJECT(x_pad); \
91                 item->category = x_category; \
92                 item->handler_id = gst_pad_add_data_probe(x_pad, G_CALLBACK(x_callback), x_hstreamrecorder); \
93                 x_hstreamrecorder->data_probes = g_list_append(x_hstreamrecorder->data_probes, item); \
94                 _mmstreamrec_dbg_log("Adding data probe on [%s:%s] - [ID : %lu], [Category : %x] ", GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category); \
95         } \
96 } while (0);
97
98 #define MMSTREAMRECORDER_SIGNAL_CONNECT(x_object, x_category, x_signal, x_callback, x_hstreamrecorder) \
99 do { \
100         MMStreamRecorderHandlerItem* item = NULL; \
101         item = (MMStreamRecorderHandlerItem *) g_malloc(sizeof(MMStreamRecorderHandlerItem)); \
102         if (!item) { \
103                 _mmstreamrec_dbg_err("Cannot connect signal [%s]\n", x_signal); \
104         } else if (x_category == 0 || !(x_category & _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL)) { \
105                 _mmstreamrec_dbg_err("Invalid handler category : %x \n", x_category); \
106         } else { \
107                 item->object = G_OBJECT(x_object); \
108                 item->category = x_category; \
109                 item->handler_id = g_signal_connect(G_OBJECT(x_object), x_signal,\
110                                                     G_CALLBACK(x_callback), x_hstreamrecorder); \
111                 x_hstreamrecorder->signals = g_list_append(x_hstreamrecorder->signals, item); \
112                 _mmstreamrec_dbg_log("Connecting signal on [%s] - [ID : %lu], [Category : %x] ", GST_OBJECT_NAME(item->object), item->handler_id, item->category); \
113         } \
114 } while (0);
115
116 #define MMSTREAMRECORDER_G_OBJECT_GET(obj, name, value) \
117 do { \
118         if (obj) { \
119                 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(obj)), name)) { \
120                         g_object_get(G_OBJECT(obj), name, value, NULL); \
121                 } else { \
122                         _mmstreamrec_dbg_warn("The object doesn't have a property named(%s)", name); \
123                 } \
124         } else { \
125                 _mmstreamrec_dbg_err("Null object"); \
126         } \
127 } while (0)
128
129 #define MMSTREAMRECORDER_G_OBJECT_SET(obj, name, value) \
130 do { \
131         if (obj) { \
132                 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(obj)), name)) { \
133                         g_object_set(G_OBJECT(obj), name, value, NULL); \
134                 } else { \
135                         _mmstreamrec_dbg_warn("The object doesn't have a property named(%s)", name); \
136                 } \
137         } else { \
138                 _mmstreamrec_dbg_err("Null object"); \
139         } \
140 } while (0)
141
142 #define MMSTREAMRECORDER_SEND_MESSAGE(handle, msg_id, msg_code) \
143 {\
144         _MMStreamRecorderMsgItem msg;\
145         msg.id = msg_id;\
146         msg.param.code = msg_code;\
147         _mmstreamrec_dbg_log("msg id : %x, code : %x", msg_id, msg_code);\
148         _mmstreamrecorder_send_message((MMHandleType)handle, &msg);\
149 }
150
151 /*=======================================================================================
152 | ENUM DEFINITIONS                                                                      |
153 ========================================================================================*/
154 /**
155  *Type define of util.
156  */
157 typedef enum {
158         _MMSTREAMRECORDER_HANDLER_VIDEOREC = (1 << 0),
159         _MMSTREAMRECORDER_HANDLER_AUDIOREC = (1 << 1),
160 } _MMStreamRecorderHandlerCategory;
161
162 /*=======================================================================================
163 | STRUCTURE DEFINITIONS                                                                 |
164 ========================================================================================*/
165
166 /**
167  * Structure of handler item
168  */
169 typedef struct {
170         GObject *object;
171         _MMStreamRecorderHandlerCategory category;
172         gulong handler_id;
173 } MMStreamRecorderHandlerItem;
174
175 /**
176  * Structure of message item
177  */
178 typedef struct {
179         MMHandleType handle;    /**< handle */
180         int id;                 /**< message id */
181         MMMessageParamType param;
182                                                         /**< message parameter */
183 } _MMStreamRecorderMsgItem;
184
185 /*=======================================================================================
186 | CONSTANT DEFINITIONS                                                                  |
187 ========================================================================================*/
188 #define _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL \
189         (_MMSTREAMRECORDER_HANDLER_VIDEOREC | _MMSTREAMRECORDER_HANDLER_AUDIOREC)
190
191 /*=======================================================================================
192 | GLOBAL FUNCTION PROTOTYPES                                                            |
193 ========================================================================================*/
194 /* GStreamer */
195 void _mmstreamrecorder_remove_buffer_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
196 void _mmstreamrecorder_remove_event_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
197 void _mmstreamrecorder_remove_data_probe(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
198 void _mmstreamrecorder_disconnect_signal(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
199 void _mmstreamrecorder_element_release_noti(gpointer data, GObject *where_the_object_was);
200
201 /* Message */
202 gboolean _mmstreamrecorder_msg_callback(void *data);
203 gboolean _mmstreamrecorder_send_message(MMHandleType handle, _MMStreamRecorderMsgItem *data);
204 gboolean _mmstreamrecorder_remove_message_all(MMHandleType handle);
205
206 gboolean _mmstreamrecorder_handle_gst_error(MMHandleType handle, GstMessage *message, GError *error);
207 gint _mmstreamrecorder_gst_handle_stream_error(MMHandleType handle, int code, GstMessage *message);
208 gint _mmstreamrecorder_gst_handle_resource_error(MMHandleType handle, int code, GstMessage *message);
209 gint _mmstreamrecorder_gst_handle_library_error(MMHandleType handle, int code, GstMessage *message);
210 gint _mmstreamrecorder_gst_handle_core_error(MMHandleType handle, int code, GstMessage *message);
211 gboolean _mmstreamrecorder_handle_gst_warning(MMHandleType handle, GstMessage *message, GError *error);
212 void _mmstreamrecorder_remove_all_handlers(MMHandleType handle, _MMStreamRecorderHandlerCategory category);
213
214 /**
215  * This function is callback function of main pipeline.
216  * Once this function is registered with certain pipeline using gst_bus_add_watch(),
217  * this callback will be called every time when there is upcomming message from pipeline.
218  * Basically, this function is used as error handling function, now.
219  *
220  * @param[in]   bus             pointer of buf that called this function.
221  * @param[in]   message         callback message from pipeline.
222  * @param[in]   data            user data.
223  * @return      This function returns true on success, or false value with error
224  * @remarks
225  * @see         __mmstreamrecorder_create_preview_pipeline()
226  *
227  */
228 gboolean _mmstreamrecorder_pipeline_cb_message(GstBus *bus, GstMessage *message, gpointer data);
229
230 GstPadProbeReturn __mmstreamrecorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
231
232 GstPadProbeReturn __mmstreamrecorder_video_dataprobe_audio_disable(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
233
234 GstPadProbeReturn __mmstreamrecorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
235
236 GstPadProbeReturn __mmstreamrecorder_audio_dataprobe_check(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
237
238 GstPadProbeReturn __mmstreamrecorder_audioque_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
239
240 GstPadProbeReturn __mmstreamrecorder_audio_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
241 void __mmstreamrecorder_audiorec_pad_added_cb(GstElement *element, GstPad *pad, MMHandleType handle);
242
243 #ifdef __cplusplus
244 }
245 #endif
246 #endif                                                  /* __MM_STREAMRECORDER_GSTDISPATCH_H__ */