1. Use wfdtsdemux instead of tsdemux.
[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                         strerror_r(errno, buf, sizeof(buf));
52                         wfd_sink_error("failed to fopen! : %s", buf);
53                         return GST_PAD_PROBE_OK;
54                 }
55                 fwrite(data, size, 1, f);
56                 fclose(f);
57                 gst_buffer_unmap(buffer, &buf_info);
58         }
59
60         return GST_PAD_PROBE_OK;
61 }
62
63 static GstPadProbeReturn
64 _mm_wfd_sink_util_pad_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
65 {
66         GstElement *parent = NULL;
67
68         wfd_sink_return_val_if_fail(info &&
69                                     info->type != GST_PAD_PROBE_TYPE_INVALID,
70                                     GST_PAD_PROBE_DROP);
71         wfd_sink_return_val_if_fail(pad, GST_PAD_PROBE_DROP);
72
73         parent = (GstElement *)gst_object_get_parent(GST_OBJECT(pad));
74         if (!parent) {
75                 wfd_sink_error("failed to get parent of pad");
76                 return GST_PAD_PROBE_DROP;
77         }
78
79         if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
80                 GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
81                 /* show name and timestamp */
82                 wfd_sink_debug("BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u  (%"G_GSSIZE_FORMAT" bytes)\n",
83                                GST_STR_NULL(GST_ELEMENT_NAME(parent)),
84                                GST_STR_NULL(GST_PAD_NAME(pad)),
85                                GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
86                                gst_buffer_get_size(buffer));
87         } else if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM ||
88                    info->type & GST_PAD_PROBE_TYPE_EVENT_UPSTREAM ||
89                    info->type & GST_PAD_PROBE_TYPE_EVENT_FLUSH ||
90                    info->type & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
91                 GstEvent *event = gst_pad_probe_info_get_event(info);
92
93                 /* show name and event type */
94                 wfd_sink_debug("EVENT PROBE : %s:%s :  %s\n",
95                                GST_STR_NULL(GST_ELEMENT_NAME(parent)),
96                                GST_STR_NULL(GST_PAD_NAME(pad)),
97                                GST_EVENT_TYPE_NAME(event));
98
99                 if (GST_EVENT_TYPE(event) == GST_EVENT_SEGMENT) {
100                         const GstSegment *segment = NULL;
101                         gst_event_parse_segment(event, &segment);
102                         if (segment)
103                                 wfd_sink_debug("NEWSEGMENT : %" G_GINT64_FORMAT
104                                                " -- %"  G_GINT64_FORMAT ", time %" G_GINT64_FORMAT " \n",
105                                                segment->start, segment->stop, segment->time);
106                 }
107         }
108
109         if (parent)
110                 gst_object_unref(parent);
111
112         return GST_PAD_PROBE_OK;
113 }
114
115 void
116 mm_wfd_sink_util_add_pad_probe(GstPad *pad, GstElement *element, const gchar *pad_name)
117 {
118         GstPad *probe_pad = NULL;
119
120         if (!pad) {
121                 if (element && pad_name)
122                         probe_pad = gst_element_get_static_pad(element, pad_name);
123         } else {
124                 probe_pad = pad;
125                 gst_object_ref(probe_pad);
126         }
127
128         if (probe_pad) {
129                 wfd_sink_debug("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
130                 gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_DATA_BOTH,
131                                   _mm_wfd_sink_util_pad_probe_cb, (gpointer)NULL, NULL);
132                 gst_object_unref(probe_pad);
133         }
134 }
135
136 void
137 mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *pad_name)
138 {
139         GstPad *probe_pad = NULL;
140
141         if (element && pad_name)
142                 probe_pad = gst_element_get_static_pad(element, pad_name);
143
144         if (probe_pad) {
145                 wfd_sink_debug("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
146                 gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_BUFFER, _mm_wfd_sink_util_dump, (gpointer)NULL, NULL);
147                 gst_object_unref(probe_pad);
148         }
149 }
150
151 static GstPadProbeReturn
152 _mm_wfd_sink_util_check_first_buffer_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
153 {
154         GstElement *parent = NULL;
155         GstBuffer *buffer = NULL;
156         guint *probe_id = (guint *)user_data;
157
158         wfd_sink_return_val_if_fail(pad, GST_PAD_PROBE_DROP);
159         wfd_sink_return_val_if_fail(info, GST_PAD_PROBE_DROP);
160
161         parent = GST_ELEMENT_CAST(gst_object_get_parent(GST_OBJECT(pad)));
162         if (parent == NULL) {
163                 wfd_sink_error("The parent of pad is NULL.");
164                 return GST_PAD_PROBE_DROP;
165         }
166
167         buffer = gst_pad_probe_info_get_buffer(info);
168
169         wfd_sink_debug("FIRST BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u (%"G_GSSIZE_FORMAT" bytes)\n",
170                        GST_STR_NULL(GST_ELEMENT_NAME(parent)), GST_STR_NULL(GST_PAD_NAME(pad)),
171                        GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), gst_buffer_get_size(buffer));
172
173         if (probe_id && *probe_id > 0) {
174                 wfd_sink_debug("remove buffer probe[%d]\n", *probe_id);
175                 gst_pad_remove_probe(pad, *probe_id);
176
177                 MMWFDSINK_FREEIF(probe_id);
178         }
179
180         if (parent)
181                 gst_object_unref(parent);
182
183         return GST_PAD_PROBE_REMOVE;
184 }
185
186 void
187 mm_wfd_sink_util_add_pad_probe_for_checking_first_buffer(GstPad *pad, GstElement *element, const gchar *pad_name)
188 {
189         GstPad *probe_pad = NULL;
190         guint *probe_id = NULL;
191
192         if (!pad) {
193                 if (element && pad_name)
194                         probe_pad = gst_element_get_static_pad(element, pad_name);
195         } else {
196                 probe_pad = pad;
197                 gst_object_ref(probe_pad);
198         }
199
200         if (probe_pad) {
201                 probe_id  = g_malloc0(sizeof(guint));
202                 if (!probe_id) {
203                         wfd_sink_error("failed to allocate memory for probe id\n");
204                         gst_object_unref(probe_pad);
205                         return;
206                 }
207
208                 *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);
209                 wfd_sink_debug("add pad(%s) probe, %d",
210                                GST_STR_NULL(GST_PAD_NAME(probe_pad)), *probe_id);
211
212                 gst_object_unref(probe_pad);
213         }
214
215         return;
216 }
217