d03dda5d3593c2b7e5a446e17f855f85c07ccac8
[platform/core/multimedia/libmm-wfd.git] / sink / 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
26 #define DUMP_TS_DATA_PATH "/var/tmp/"
27
28 static GstPadProbeReturn
29 _mm_wfd_sink_util_dump (GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
30 {
31         gint8 *data = NULL;
32         gint size = 0;
33         FILE *f = NULL;
34         char buf[256] = {0,};
35         char path[256] = {0,};
36
37         snprintf(path , sizeof(path), "%s%s_%s.ts", DUMP_TS_DATA_PATH,
38                 gst_element_get_name(gst_pad_get_parent_element(pad)), gst_pad_get_name(pad));
39
40         if (info && info->type & GST_PAD_PROBE_TYPE_BUFFER) {
41                 GstMapInfo buf_info;
42                 GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
43
44                 gst_buffer_map(buffer, &buf_info, GST_MAP_READ);
45
46                 wfd_sink_debug ("got buffer %p with size %d", buffer, buf_info.size);
47                 data = (gint8 *)(buf_info.data);
48                 size = buf_info.size;
49                 f = fopen(path, "a");
50                 if(f == NULL)
51                 {
52                         strerror_r(errno, buf, sizeof(buf));
53                         wfd_sink_error("failed to fopen! : %s", buf);
54                         return GST_PAD_PROBE_OK;
55                 }
56                 fwrite(data, size, 1, f);
57                 fclose(f);
58                 gst_buffer_unmap(buffer, &buf_info);
59         }
60
61         return GST_PAD_PROBE_OK;
62 }
63
64 static GstPadProbeReturn
65 _mm_wfd_sink_util_pad_probe_cb(GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
66 {
67         GstElement* parent = NULL;
68
69         wfd_sink_return_val_if_fail(info &&
70                 info->type != GST_PAD_PROBE_TYPE_INVALID,
71                 GST_PAD_PROBE_DROP);
72         wfd_sink_return_val_if_fail(pad, GST_PAD_PROBE_DROP);
73
74         parent = (GstElement*)gst_object_get_parent(GST_OBJECT(pad));
75         if(!parent)
76         {
77                 wfd_sink_error("failed to get parent of pad");
78                 return GST_PAD_PROBE_DROP;
79         }
80
81         if (info->type & GST_PAD_PROBE_TYPE_BUFFER)
82         {
83                 GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
84                 /* show name and timestamp */
85                 wfd_sink_debug("BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u  (%"G_GSSIZE_FORMAT" bytes)\n",
86                         GST_STR_NULL(GST_ELEMENT_NAME(parent)),
87                         GST_STR_NULL(GST_PAD_NAME(pad)),
88                         GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
89                         gst_buffer_get_size(buffer));
90         }
91         else if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM ||
92                 info->type & GST_PAD_PROBE_TYPE_EVENT_UPSTREAM ||
93                 info->type & GST_PAD_PROBE_TYPE_EVENT_FLUSH ||
94                 info->type & GST_PAD_PROBE_TYPE_EVENT_BOTH)
95         {
96                 GstEvent *event = gst_pad_probe_info_get_event (info);
97
98                 /* show name and event type */
99                 wfd_sink_debug("EVENT PROBE : %s:%s :  %s\n",
100                         GST_STR_NULL(GST_ELEMENT_NAME(parent)),
101                         GST_STR_NULL(GST_PAD_NAME(pad)),
102                         GST_EVENT_TYPE_NAME(event));
103
104                 if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)
105                 {
106                         const GstSegment* segment = NULL;
107                         gst_event_parse_segment (event, &segment);
108                         if (segment)
109                                 wfd_sink_debug ("NEWSEGMENT : %" G_GINT64_FORMAT
110                                         " -- %"  G_GINT64_FORMAT ", time %" G_GINT64_FORMAT " \n",
111                                         segment->start, segment->stop, segment->time);
112                 }
113         }
114
115         if ( parent )
116                 gst_object_unref(parent);
117
118         return GST_PAD_PROBE_OK;
119 }
120
121 void
122 mm_wfd_sink_util_add_pad_probe(GstPad *pad, GstElement *element, const gchar *pad_name)
123 {
124         GstPad * probe_pad = NULL;
125
126         if (!pad)
127         {
128                 if(element && pad_name)
129                         probe_pad = gst_element_get_static_pad(element, pad_name);
130         }
131         else
132         {
133                 probe_pad = pad;
134                 gst_object_ref(probe_pad);
135         }
136
137         if (probe_pad)
138         {
139                 wfd_sink_debug ("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
140                 gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_DATA_BOTH,
141                         _mm_wfd_sink_util_pad_probe_cb, (gpointer)NULL, NULL);
142                 gst_object_unref(probe_pad);
143         }
144 }
145
146 void
147 mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *pad_name)
148 {
149         GstPad * probe_pad = NULL;
150
151         if(element && pad_name)
152                 probe_pad = gst_element_get_static_pad(element, pad_name);
153
154         if (probe_pad)
155         {
156                 wfd_sink_debug ("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
157                 gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_BUFFER, _mm_wfd_sink_util_dump, (gpointer)NULL, NULL);
158                 gst_object_unref(probe_pad);
159         }
160 }
161
162 static GstPadProbeReturn
163 _mm_wfd_sink_util_check_first_buffer_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
164 {
165         GstElement* parent = NULL;
166         GstBuffer *buffer = NULL;
167         guint *probe_id = (guint*)user_data;
168
169         wfd_sink_return_val_if_fail(pad, GST_PAD_PROBE_DROP);
170         wfd_sink_return_val_if_fail(info, GST_PAD_PROBE_DROP);
171
172         parent = GST_ELEMENT_CAST(gst_object_get_parent(GST_OBJECT(pad)));
173         if( parent == NULL)
174         {
175                 wfd_sink_error("The parent of pad is NULL.");
176                 return GST_PAD_PROBE_DROP;
177         }
178
179         buffer = gst_pad_probe_info_get_buffer (info);
180
181         wfd_sink_debug("FIRST BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u (%"G_GSSIZE_FORMAT" bytes)\n",
182                 GST_STR_NULL(GST_ELEMENT_NAME(parent)), GST_STR_NULL(GST_PAD_NAME(pad)),
183                 GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), gst_buffer_get_size(buffer));
184
185         if (probe_id && *probe_id >0)
186         {
187                 wfd_sink_debug("remove buffer probe[%d]\n", *probe_id);
188                 gst_pad_remove_probe(pad, *probe_id);
189
190                 MMWFDSINK_FREEIF(probe_id);
191         }
192
193         if ( parent )
194                 gst_object_unref(parent);
195
196         return GST_PAD_PROBE_REMOVE;
197 }
198
199 void
200 mm_wfd_sink_util_add_pad_probe_for_checking_first_buffer(GstPad *pad, GstElement *element, const gchar *pad_name)
201 {
202         GstPad * probe_pad = NULL;
203         guint *probe_id = NULL;
204
205         if (!pad)
206         {
207                 if(element && pad_name)
208                         probe_pad = gst_element_get_static_pad(element, pad_name);
209         }
210         else
211         {
212                 probe_pad = pad;
213                 gst_object_ref(probe_pad);
214         }
215
216         if (probe_pad)
217         {
218                 probe_id  = g_malloc0(sizeof(guint));
219                 if (!probe_id)
220                 {
221                         wfd_sink_error("failed to allocate memory for probe id\n");
222                         gst_object_unref(probe_pad);
223                         return;
224                 }
225
226                 *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);
227                 wfd_sink_debug ("add pad(%s) probe, %d",
228                         GST_STR_NULL(GST_PAD_NAME(probe_pad)), *probe_id);
229
230                 gst_object_unref(probe_pad);
231         }
232
233         return;
234 }
235