Change directory structure for code integration
[platform/core/multimedia/libmm-wfd.git] / src / mm_wfd_sink_util.c
1 /*
2  * libmm-wfd
3  *
4  * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, ByungWook Jang <bw.jang@samsung.com>,
7  * Maksym Ukhanov <m.ukhanov@samsung.com>, Hyunjun Ko <zzoon.ko@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include "mm_wfd_sink_util.h"
24 #include <stdio.h>
25 #include <tzplatform_config.h>
26
27 #define DUMP_TS_DATA_PATH tzplatform_mkpath(TZ_SYS_VAR, "tmp/")
28
29 static GstPadProbeReturn
30 _mm_wfd_sink_util_dump(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
31 {
32         gint8 *data = NULL;
33         gint size = 0;
34         FILE *f = NULL;
35         char buf[256] = {0, };
36         char path[256] = {0, };
37         GstElement * parent = NULL;
38
39         parent = gst_pad_get_parent_element(pad);
40         if (parent == NULL) {
41                 wfd_sink_error("The parent of pad is NULL.");
42                 return GST_PAD_PROBE_OK;
43         }
44
45         snprintf(path, sizeof(path), "%s%s_%s.ts", DUMP_TS_DATA_PATH, gst_element_get_name(parent), gst_pad_get_name(pad));
46         gst_object_unref(parent);
47
48         if (info && info->type & GST_PAD_PROBE_TYPE_BUFFER) {
49                 GstMapInfo buf_info;
50                 GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
51
52                 gst_buffer_map(buffer, &buf_info, GST_MAP_READ);
53
54                 wfd_sink_debug("got buffer %p with size %d", buffer, buf_info.size);
55                 data = (gint8 *)(buf_info.data);
56                 size = buf_info.size;
57                 f = fopen(path, "a");
58                 if (f == NULL) {
59                         strerror_r(errno, buf, sizeof(buf));
60                         wfd_sink_error("failed to fopen! : %s", buf);
61                         return GST_PAD_PROBE_OK;
62                 }
63                 fwrite(data, size, 1, f);
64                 fclose(f);
65                 gst_buffer_unmap(buffer, &buf_info);
66         }
67
68         return GST_PAD_PROBE_OK;
69 }
70
71 static GstPadProbeReturn
72 _mm_wfd_sink_util_pad_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
73 {
74         GstElement *parent = NULL;
75
76         wfd_sink_return_val_if_fail(info &&
77                                                 info->type != GST_PAD_PROBE_TYPE_INVALID,
78                                                 GST_PAD_PROBE_DROP);
79         wfd_sink_return_val_if_fail(pad, GST_PAD_PROBE_DROP);
80
81         parent = (GstElement *)gst_object_get_parent(GST_OBJECT(pad));
82         if (!parent) {
83                 wfd_sink_error("failed to get parent of pad");
84                 return GST_PAD_PROBE_DROP;
85         }
86
87         if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
88                 GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
89                 /* show name and timestamp */
90                 wfd_sink_debug("BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u  (%"G_GSSIZE_FORMAT" bytes)\n",
91                                         GST_STR_NULL(GST_ELEMENT_NAME(parent)),
92                                         GST_STR_NULL(GST_PAD_NAME(pad)),
93                                         GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
94                                         gst_buffer_get_size(buffer));
95         } else if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM ||
96                         info->type & GST_PAD_PROBE_TYPE_EVENT_UPSTREAM ||
97                         info->type & GST_PAD_PROBE_TYPE_EVENT_FLUSH ||
98                         info->type & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
99                 GstEvent *event = gst_pad_probe_info_get_event(info);
100
101                 /* show name and event type */
102                 wfd_sink_debug("EVENT PROBE : %s:%s :  %s\n",
103                                         GST_STR_NULL(GST_ELEMENT_NAME(parent)),
104                                         GST_STR_NULL(GST_PAD_NAME(pad)),
105                                         GST_EVENT_TYPE_NAME(event));
106
107                 if (GST_EVENT_TYPE(event) == GST_EVENT_SEGMENT) {
108                         const GstSegment *segment = NULL;
109                         gst_event_parse_segment(event, &segment);
110                         if (segment)
111                                 wfd_sink_debug("NEWSEGMENT : %" GST_TIME_FORMAT
112                                                         " -- %"  GST_TIME_FORMAT ", time %" GST_TIME_FORMAT " \n",
113                                                         GST_TIME_ARGS(segment->start), GST_TIME_ARGS(segment->stop),
114                                                         GST_TIME_ARGS(segment->time));
115                 }
116         }
117
118         if (parent)
119                 gst_object_unref(parent);
120
121         return GST_PAD_PROBE_OK;
122 }
123
124 void
125 mm_wfd_sink_util_add_pad_probe(GstPad *pad, GstElement *element, const gchar *pad_name)
126 {
127         GstPad *probe_pad = NULL;
128
129         if (!pad) {
130                 if (element && pad_name)
131                         probe_pad = gst_element_get_static_pad(element, pad_name);
132         } else {
133                 probe_pad = pad;
134                 gst_object_ref(probe_pad);
135         }
136
137         if (probe_pad) {
138                 wfd_sink_debug("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
139                 gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_DATA_BOTH, _mm_wfd_sink_util_pad_probe_cb, (gpointer)NULL, NULL);
140                 gst_object_unref(probe_pad);
141         }
142 }
143
144 void
145 mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *pad_name)
146 {
147         GstPad *probe_pad = NULL;
148
149         if (element && pad_name)
150                 probe_pad = gst_element_get_static_pad(element, pad_name);
151
152         if (probe_pad) {
153                 wfd_sink_debug("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
154                 gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_BUFFER, _mm_wfd_sink_util_dump, (gpointer)NULL, NULL);
155                 gst_object_unref(probe_pad);
156         }
157 }
158
159 static GstPadProbeReturn
160 _mm_wfd_sink_util_check_first_buffer_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
161 {
162         GstElement *parent = NULL;
163         GstBuffer *buffer = NULL;
164         guint *probe_id = (guint *)user_data;
165
166         wfd_sink_return_val_if_fail(pad, GST_PAD_PROBE_DROP);
167         wfd_sink_return_val_if_fail(info, GST_PAD_PROBE_DROP);
168
169         parent = GST_ELEMENT_CAST(gst_object_get_parent(GST_OBJECT(pad)));
170         if (parent == NULL) {
171                 wfd_sink_error("The parent of pad is NULL.");
172                 return GST_PAD_PROBE_DROP;
173         }
174
175         buffer = gst_pad_probe_info_get_buffer(info);
176
177         wfd_sink_debug("FIRST BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u (%"G_GSSIZE_FORMAT" bytes)\n",
178                                 GST_STR_NULL(GST_ELEMENT_NAME(parent)), GST_STR_NULL(GST_PAD_NAME(pad)),
179                                 GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), gst_buffer_get_size(buffer));
180
181         if (probe_id && *probe_id > 0) {
182                 wfd_sink_debug("remove buffer probe[%d]\n", *probe_id);
183                 gst_pad_remove_probe(pad, *probe_id);
184
185                 MMWFDSINK_FREEIF(probe_id);
186         }
187
188         if (parent)
189                 gst_object_unref(parent);
190
191         return GST_PAD_PROBE_REMOVE;
192 }
193
194 void
195 mm_wfd_sink_util_add_pad_probe_for_checking_first_buffer(GstPad *pad, GstElement *element, const gchar *pad_name)
196 {
197         GstPad *probe_pad = NULL;
198         guint *probe_id = NULL;
199
200         if (!pad) {
201                 if (element && pad_name)
202                         probe_pad = gst_element_get_static_pad(element, pad_name);
203         } else {
204                 probe_pad = pad;
205                 gst_object_ref(probe_pad);
206         }
207
208         if (probe_pad) {
209                 probe_id  = g_malloc0(sizeof(guint));
210                 if (!probe_id) {
211                         wfd_sink_error("failed to allocate memory for probe id\n");
212                         gst_object_unref(probe_pad);
213                         return;
214                 }
215
216                 *probe_id = gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_BUFFER, _mm_wfd_sink_util_check_first_buffer_cb, (gpointer)probe_id, NULL);
217                 wfd_sink_debug("add pad(%s) probe, %d", GST_STR_NULL(GST_PAD_NAME(probe_pad)), *probe_id);
218
219                 gst_object_unref(probe_pad);
220         }
221
222         return;
223 }
224