Add sub functions for recording
[platform/core/multimedia/libmm-camcorder.git] / src / include / mm_camcorder_util.h
1 /*
2  * libmm-camcorder
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jeongmo Yang <jm80.yang@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_CAMCORDER_UTIL_H__
23 #define __MM_CAMCORDER_UTIL_H__
24
25 /*=======================================================================================
26 | INCLUDE FILES                                                                         |
27 ========================================================================================*/
28 #include <gio/gio.h>
29 #include <linux/magic.h>
30 #include <storage.h>
31
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 /*=======================================================================================
38 | GLOBAL DEFINITIONS AND DECLARATIONS FOR CAMCORDER                                     |
39 ========================================================================================*/
40
41 /*=======================================================================================
42 | MACRO DEFINITIONS                                                                     |
43 ========================================================================================*/
44 #ifndef CLEAR
45 #define CLEAR(x)            memset(&(x), 0, sizeof(x))
46 #endif
47
48 #define MMCAMCORDER_ADD_BUFFER_PROBE(x_pad, x_category, x_callback, x_hcamcorder) \
49 do { \
50         MMCamcorderHandlerItem *item = NULL; \
51         item = (MMCamcorderHandlerItem *)g_malloc(sizeof(MMCamcorderHandlerItem)); \
52         if (!item) {\
53                 _mmcam_dbg_err("Cannot connect buffer probe [malloc fail] \n"); \
54         } else if (x_category == 0 || !(x_category & _MMCAMCORDER_HANDLER_CATEGORY_ALL)) { \
55                 _mmcam_dbg_err("Invalid handler category : %x \n", x_category); \
56         } else { \
57                 item->object = G_OBJECT(x_pad); \
58                 item->category = x_category; \
59                 item->handler_id = gst_pad_add_probe(x_pad, GST_PAD_PROBE_TYPE_BUFFER, x_callback, x_hcamcorder, NULL); \
60                 x_hcamcorder->buffer_probes = g_list_append(x_hcamcorder->buffer_probes, item); \
61                 _mmcam_dbg_log("Adding buffer probe on [%s:%s] - [ID : %lu], [Category : %x] ", \
62                         GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category); \
63         } \
64 } while (0)
65
66 #define MMCAMCORDER_ADD_EVENT_PROBE(x_pad, x_category, x_callback, x_hcamcorder) \
67 do { \
68         MMCamcorderHandlerItem *item = NULL; \
69         item = (MMCamcorderHandlerItem *) g_malloc(sizeof(MMCamcorderHandlerItem)); \
70         if (!item) { \
71                 _mmcam_dbg_err("Cannot connect buffer probe [malloc fail] \n"); \
72         } \
73         else if (x_category == 0 || !(x_category & _MMCAMCORDER_HANDLER_CATEGORY_ALL)) { \
74                 _mmcam_dbg_err("Invalid handler category : %x \n", x_category); \
75         } else { \
76                 item->object = G_OBJECT(x_pad); \
77                 item->category = x_category; \
78                 item->handler_id = gst_pad_add_probe(x_pad, GST_PAD_PROBE_TYPE_EVENT_BOTH, x_callback, x_hcamcorder, NULL); \
79                 x_hcamcorder->event_probes = g_list_append(x_hcamcorder->event_probes, item); \
80                 _mmcam_dbg_log("Adding event probe on [%s:%s] - [ID : %lu], [Category : %x] ", \
81                         GST_DEBUG_PAD_NAME(item->object), item->handler_id, item->category); \
82         } \
83 } while (0)
84
85 #define MMCAMCORDER_SIGNAL_CONNECT(x_object, x_category, x_signal, x_callback, x_hcamcorder) \
86 do { \
87         MMCamcorderHandlerItem* item = NULL; \
88         item = (MMCamcorderHandlerItem *) g_malloc(sizeof(MMCamcorderHandlerItem)); \
89         if (!item) { \
90                 _mmcam_dbg_err("Cannot connect signal [%s]\n", x_signal); \
91         } else if (x_category == 0 || !(x_category & _MMCAMCORDER_HANDLER_CATEGORY_ALL)) { \
92                 _mmcam_dbg_err("Invalid handler category : %x \n", x_category); \
93         } else { \
94                 item->object = G_OBJECT(x_object); \
95                 item->category = x_category; \
96                 item->handler_id = g_signal_connect(G_OBJECT(x_object), x_signal, \
97                         G_CALLBACK(x_callback), x_hcamcorder); \
98                 x_hcamcorder->signals = g_list_append(x_hcamcorder->signals, item); \
99                 _mmcam_dbg_log("Connecting signal on [%s][%p] - [ID : %lu], [Category : %x] ", \
100                         GST_OBJECT_NAME(item->object), item->object, item->handler_id, item->category); \
101         } \
102 } while (0)
103
104 #define MMCAMCORDER_G_OBJECT_GET(obj, name, value) \
105 do { \
106         if (obj) { \
107                 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(obj)), name)) { \
108                         g_object_get(G_OBJECT(obj), name, value, NULL); \
109                 } else { \
110                         _mmcam_dbg_warn("The object doesn't have a property named(%s)", name); \
111                 } \
112         } else { \
113                 _mmcam_dbg_err("Null object"); \
114         } \
115 } while (0)
116
117 #define MMCAMCORDER_G_OBJECT_SET(obj, name, value) \
118 do { \
119         if (obj) { \
120                 GParamSpec *spec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(obj)), name);\
121                 if (spec) { \
122                         if (spec->value_type == G_TYPE_INT64) {\
123                                 g_object_set(G_OBJECT(obj), name, (gint64)value, NULL); \
124                         } else if (spec->value_type == G_TYPE_UINT64) { \
125                                 g_object_set(G_OBJECT(obj), name, (guint64)value, NULL); \
126                         } else if (spec->value_type == G_TYPE_FLOAT) { \
127                                 g_object_set(G_OBJECT(obj), name, (float)value, NULL); \
128                         } else if (spec->value_type == G_TYPE_DOUBLE) { \
129                                 g_object_set(G_OBJECT(obj), name, (double)value, NULL); \
130                         } else { \
131                                 g_object_set(G_OBJECT(obj), name, value, NULL); \
132                         } \
133                 } else { \
134                         _mmcam_dbg_warn("The object doesn't have a property named(%s)", name); \
135                 } \
136         } else { \
137                 _mmcam_dbg_err("Null object"); \
138         } \
139 } while (0)
140
141 #define MMCAMCORDER_G_OBJECT_SET_POINTER(obj, name, value) \
142 do { \
143         if (obj) { \
144                 GParamSpec *spec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(obj)), name);\
145                 if (spec) { \
146                         g_object_set(G_OBJECT(obj), name, value, NULL); \
147                 } else { \
148                         _mmcam_dbg_warn("The object doesn't have a property named(%s)", name); \
149                 } \
150         } else { \
151                 _mmcam_dbg_err("Null object"); \
152         } \
153 } while (0)
154
155 #define MMCAM_FOURCC(a, b, c, d)  (guint32)((a)|(b)<<8|(c)<<16|(d)<<24)
156 #define MMCAM_FOURCC_ARGS(fourcc) \
157                 ((gchar)((fourcc)&0xff)), \
158                 ((gchar)(((fourcc)>>8)&0xff)), \
159                 ((gchar)(((fourcc)>>16)&0xff)), \
160                 ((gchar)(((fourcc)>>24)&0xff))
161
162 #define MMCAM_SEND_MESSAGE(handle, msg_id, msg_code) \
163 do {\
164         _MMCamcorderMsgItem msg;\
165         msg.id = msg_id;\
166         msg.param.code = msg_code;\
167         _mmcam_dbg_log("msg id : %x, code : %x", msg_id, msg_code);\
168         _mmcamcorder_send_message((MMHandleType)handle, &msg);\
169 } while (0)
170
171
172 /*=======================================================================================
173 | ENUM DEFINITIONS                                                                      |
174 ========================================================================================*/
175 /**
176  * Structure of GDBus Callback.
177  */
178 typedef struct {
179         GCond sync_cond;
180         GMutex sync_mutex;
181         int param;
182         int is_playing;
183         guint subscribe_id;
184         void *mm_handle;
185 } _MMCamcorderGDbusCbInfo;
186
187 /**
188  *Type define of util.
189  */
190 typedef enum {
191         _MMCAMCORDER_HANDLER_PREVIEW = (1 << 0),
192         _MMCAMCORDER_HANDLER_VIDEOREC = (1 << 1),
193         _MMCAMCORDER_HANDLER_STILLSHOT = (1 << 2),
194         _MMCAMCORDER_HANDLER_AUDIOREC = (1 << 3),
195 } _MMCamcorderHandlerCategory;
196
197 /*=======================================================================================
198 | STRUCTURE DEFINITIONS                                                                 |
199 ========================================================================================*/
200
201 /**
202  * Structure of location info
203  */
204 typedef struct {
205         gint32 longitude;
206         gint32 latitude;
207         gint32 altitude;
208 } _MMCamcorderLocationInfo;
209
210 /**
211  * Structure of handler item
212  */
213 typedef struct {
214         GObject *object;
215         _MMCamcorderHandlerCategory category;
216         gulong handler_id;
217 } MMCamcorderHandlerItem;
218
219 /**
220  * Structure of message item
221  */
222 typedef struct {
223         MMHandleType handle;        /**< handle */
224         int id;                     /**< message id */
225         MMMessageParamType param;   /**< message parameter */
226         GMutex lock;                /**< mutex for item */
227 } _MMCamcorderMsgItem;
228
229 /**
230  * Structure of storage information
231  */
232 typedef struct {
233         storage_type_e type;
234         int id;
235 } _MMCamcorderStorageInfo;
236
237
238 /*=======================================================================================
239 | CONSTANT DEFINITIONS                                                                  |
240 ========================================================================================*/
241 #define G_DBUS_TIMEOUT                          3000
242 #define FAT32_FILE_SYSTEM_MAX_SIZE              (4294967295UL)     /* 4 GigaByte - 1 byte */
243 #define NANO_SEC_PER_MILI_SEC                   1000000
244 #define _MMCAMCORDER_HANDLER_CATEGORY_ALL \
245         (_MMCAMCORDER_HANDLER_PREVIEW | _MMCAMCORDER_HANDLER_VIDEOREC |_MMCAMCORDER_HANDLER_STILLSHOT | _MMCAMCORDER_HANDLER_AUDIOREC)
246
247
248 /*=======================================================================================
249 | GLOBAL FUNCTION PROTOTYPES                                                            |
250 ========================================================================================*/
251 /* GStreamer */
252 void _mmcamcorder_remove_buffer_probe(MMHandleType handle, _MMCamcorderHandlerCategory category);
253 void _mmcamcorder_remove_one_buffer_probe(MMHandleType handle, void *object);
254 void _mmcamcorder_remove_event_probe(MMHandleType handle, _MMCamcorderHandlerCategory category);
255 void _mmcamcorder_disconnect_signal(MMHandleType handle, _MMCamcorderHandlerCategory category);
256 void _mmcamcorder_remove_all_handlers(MMHandleType handle, _MMCamcorderHandlerCategory category);
257 void _mmcamcorder_element_release_noti(gpointer data, GObject *where_the_object_was);
258 gboolean _mmcamcorder_add_elements_to_bin(GstBin *bin, GList *element_list);
259 gboolean _mmcamcorder_link_elements(GList *element_list);
260
261 /* Message */
262 #ifdef _MMCAMCORDER_ENABLE_IDLE_MESSAGE_CALLBACK
263 gboolean _mmcamcorder_msg_callback(void *data);
264 #endif /* _MMCAMCORDER_ENABLE_IDLE_MESSAGE_CALLBACK */
265 gboolean _mmcamcorder_send_message(MMHandleType handle, _MMCamcorderMsgItem *data);
266 void _mmcamcorder_remove_message_all(MMHandleType handle);
267
268 /* Pixel format */
269 int _mmcamcorder_get_pixel_format(GstCaps *pad);
270 int _mmcamcorder_get_pixtype(unsigned int fourcc);
271 unsigned int _mmcamcorder_get_fourcc(int pixtype, int codectype, int use_zero_copy_format);
272
273 /* JPEG encode */
274 gboolean _mmcamcorder_encode_jpeg(void *src_data, unsigned int src_width, unsigned int src_height,
275         int src_format, unsigned int src_length, unsigned int jpeg_quality,
276         void **result_data, unsigned int *result_length);
277 /* resize */
278 gboolean _mmcamcorder_resize_frame(unsigned char *src_data, unsigned int src_width, unsigned int src_height, unsigned int src_length, int src_format,
279         unsigned char **dst_data, unsigned int *dst_width, unsigned int *dst_height, size_t *dst_length);
280 gboolean _mmcamcorder_downscale_UYVYorYUYV(unsigned char *src, unsigned int src_width, unsigned int src_height,
281         unsigned char **dst, unsigned int dst_width, unsigned int dst_height);
282
283 /* Recording */
284 /* find top level tag only, do not use this function for finding sub level tags.
285    tag_fourcc is Four-character-code (FOURCC) */
286 gint _mmcamcorder_find_tag(FILE *f, guint32 tag_fourcc, gboolean do_rewind);
287 gboolean _mmcamcorder_find_fourcc(FILE *f, guint32 tag_fourcc, gboolean do_rewind);
288 gint32 _mmcamcorder_double_to_fix(gdouble d_number);
289 gboolean _mmcamcorder_update_size(FILE *f, gint64 prev_pos, gint64 curr_pos);
290 gboolean _mmcamcorder_write_loci(FILE *f, _MMCamcorderLocationInfo info);
291 gboolean _mmcamcorder_write_geodata(FILE *f, _MMCamcorderLocationInfo info);
292 gboolean _mmcamcorder_write_udta(FILE *f, int gps_enable, _MMCamcorderLocationInfo info, _MMCamcorderLocationInfo geotag);
293 guint64 _mmcamcorder_get_container_size(const guchar *size);
294 guint64 _mmcamcorder_get_container_size64(const guchar *size);
295 gboolean _mmcamcorder_update_composition_matrix(FILE *f, int orientation);
296 void _mmcamcorder_adjust_recording_max_size(const char *filename, guint64 *max_size);
297
298 /* File system */
299 int _mmcamcorder_get_storage_validity(MMHandleType handle, const char *filename, guint64 min_space, gboolean *storage_validity);
300 int _mmcamcorder_get_storage_info(const gchar *path, const gchar *root_directory, _MMCamcorderStorageInfo *storage_info);
301 int _mmcamcorder_get_freespace(storage_type_e type, guint64 *free_space);
302 int _mmcamcorder_get_file_size(const char *filename, guint64 *size);
303 int _mmcamcorder_get_file_system_type(const gchar *path, int *file_system_type);
304
305 /* Task */
306 void *_mmcamcorder_util_task_thread_func(void *data);
307
308 /* device */
309 int _mmcamcorder_get_device_flash_brightness(GDBusConnection *conn, int *brightness);
310
311 /* sound play via dbus*/
312 int _mmcamcorder_send_sound_play_message(GDBusConnection *conn, _MMCamcorderGDbusCbInfo *gdbus_info,
313         const char *sample_name, const char *stream_role, const char *volume_gain, int sync_play);
314
315 /* request to show pop-up related DPM policy */
316 void _mmcamcorder_request_dpm_popup(GDBusConnection *conn, const char *restricted_policy);
317
318 /* dbus signal emit */
319 void _mmcamcorder_emit_dbus_signal(GDBusConnection *conn, const char *object_name,
320         const char *interface_name, const char *signal_name, int value);
321
322 /* audio buffer */
323 int _mmcamcorder_get_audiosrc_blocksize(int samplerate, int format, int channel, int interval, int *blocksize);
324
325 #ifdef __cplusplus
326 }
327 #endif
328
329 #endif /* __MM_CAMCORDER_UTIL_H__ */