• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  *
3  * Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include <gst/gst.h>
25 #include <gst/check/gstcheck.h>
26 #include <gst/check/gstharness.h>
27 #include <gst/video/video.h>
28 
29 #include <string.h>
30 
31 static GstStaticCaps foo_bar_caps = GST_STATIC_CAPS ("foo/bar");
32 static GstStaticCaps cea708_cc_data_caps =
33 GST_STATIC_CAPS ("closedcaption/x-cea-708,format=(string) cc_data");
34 static GstStaticCaps cea708_cdp_caps =
35 GST_STATIC_CAPS ("closedcaption/x-cea-708,format=(string) cdp");
36 
GST_START_TEST(no_captions)37 GST_START_TEST (no_captions)
38 {
39   GstHarness *h;
40   GstBuffer *buf, *outbuf;
41   GstCaps *caps;
42 
43   h = gst_harness_new_with_padnames ("cccombiner", "sink", "src");
44 
45   gst_harness_set_src_caps_str (h, foo_bar_caps.string);
46 
47   buf = gst_buffer_new_and_alloc (128);
48   GST_BUFFER_PTS (buf) = 0;
49   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
50   outbuf = gst_harness_push_and_pull (h, gst_buffer_ref (buf));
51 
52   fail_unless (outbuf != NULL);
53   fail_unless (outbuf == buf);
54 
55   caps = gst_pad_get_current_caps (h->sinkpad);
56   fail_unless (caps != NULL);
57   fail_unless (gst_caps_can_intersect (caps,
58           gst_static_caps_get (&foo_bar_caps)));
59   gst_caps_unref (caps);
60 
61   gst_buffer_unref (buf);
62   gst_buffer_unref (outbuf);
63 
64   gst_harness_teardown (h);
65 }
66 
67 GST_END_TEST;
68 
GST_START_TEST(captions_and_eos)69 GST_START_TEST (captions_and_eos)
70 {
71   GstHarness *h, *h2;
72   GstBuffer *buf, *outbuf;
73   GstPad *caption_pad;
74   GstCaps *caps;
75   GstVideoCaptionMeta *meta;
76 
77   h = gst_harness_new_with_padnames ("cccombiner", "sink", "src");
78   h2 = gst_harness_new_with_element (h->element, NULL, NULL);
79   caption_pad = gst_element_get_request_pad (h->element, "caption");
80   gst_harness_add_element_sink_pad (h2, caption_pad);
81   gst_object_unref (caption_pad);
82 
83   gst_harness_set_src_caps_str (h, foo_bar_caps.string);
84   gst_harness_set_src_caps_str (h2, cea708_cc_data_caps.string);
85 
86   /* Push a buffer and caption buffer */
87   buf = gst_buffer_new_and_alloc (128);
88   GST_BUFFER_PTS (buf) = 0;
89   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
90   gst_harness_push (h, buf);
91 
92   buf = gst_buffer_new_and_alloc (128);
93   GST_BUFFER_PTS (buf) = 0;
94   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
95   gst_harness_push (h2, buf);
96 
97   /* And another one: the first video buffer should be retrievable
98    * after the second caption buffer is pushed */
99   buf = gst_buffer_new_and_alloc (128);
100   GST_BUFFER_PTS (buf) = 40 * GST_MSECOND;
101   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
102   gst_harness_push (h, buf);
103 
104   buf = gst_buffer_new_and_alloc (128);
105   GST_BUFFER_PTS (buf) = 40 * GST_MSECOND;
106   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
107   gst_harness_push (h2, buf);
108 
109   /* Pull the first output buffer */
110   outbuf = gst_harness_pull (h);
111   fail_unless (outbuf != NULL);
112 
113   meta = gst_buffer_get_video_caption_meta (outbuf);
114   fail_unless (meta != NULL);
115   fail_unless_equals_int (meta->caption_type,
116       GST_VIDEO_CAPTION_TYPE_CEA708_RAW);
117   fail_unless_equals_int (meta->size, 128);
118 
119   gst_buffer_unref (outbuf);
120 
121   /* Push EOS on both pads get the second output buffer, we otherwise wait
122    * in case there are further captions for the current video buffer */
123   gst_harness_push_event (h, gst_event_new_eos ());
124   gst_harness_push_event (h2, gst_event_new_eos ());
125 
126   outbuf = gst_harness_pull (h);
127   fail_unless (outbuf != NULL);
128 
129   meta = gst_buffer_get_video_caption_meta (outbuf);
130   fail_unless (meta != NULL);
131   fail_unless_equals_int (meta->caption_type,
132       GST_VIDEO_CAPTION_TYPE_CEA708_RAW);
133   fail_unless_equals_int (meta->size, 128);
134 
135   gst_buffer_unref (outbuf);
136 
137   /* Caps should be equal to input caps */
138   caps = gst_pad_get_current_caps (h->sinkpad);
139   fail_unless (caps != NULL);
140   fail_unless (gst_caps_can_intersect (caps,
141           gst_static_caps_get (&foo_bar_caps)));
142   gst_caps_unref (caps);
143 
144   gst_harness_teardown (h);
145   gst_harness_teardown (h2);
146 }
147 
148 GST_END_TEST;
149 
GST_START_TEST(captions_type_change_and_eos)150 GST_START_TEST (captions_type_change_and_eos)
151 {
152   GstHarness *h, *h2;
153   GstBuffer *buf, *outbuf;
154   GstPad *caption_pad;
155   GstCaps *caps;
156   GstVideoCaptionMeta *meta;
157 
158   h = gst_harness_new_with_padnames ("cccombiner", "sink", "src");
159   h2 = gst_harness_new_with_element (h->element, NULL, NULL);
160   caption_pad = gst_element_get_request_pad (h->element, "caption");
161   gst_harness_add_element_sink_pad (h2, caption_pad);
162   gst_object_unref (caption_pad);
163 
164   gst_harness_set_src_caps_str (h, foo_bar_caps.string);
165   gst_harness_set_src_caps_str (h2, cea708_cc_data_caps.string);
166 
167   /* Push a buffer and caption buffer */
168   buf = gst_buffer_new_and_alloc (128);
169   GST_BUFFER_PTS (buf) = 0;
170   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
171   gst_harness_push (h, buf);
172 
173   buf = gst_buffer_new_and_alloc (128);
174   GST_BUFFER_PTS (buf) = 0;
175   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
176   gst_harness_push (h2, buf);
177 
178   /* Change caption type */
179   gst_harness_set_src_caps_str (h2, cea708_cdp_caps.string);
180 
181   /* And another one: the first video buffer should be retrievable
182    * after the second caption buffer is pushed */
183   buf = gst_buffer_new_and_alloc (128);
184   GST_BUFFER_PTS (buf) = 40 * GST_MSECOND;
185   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
186   gst_harness_push (h, buf);
187 
188   buf = gst_buffer_new_and_alloc (128);
189   GST_BUFFER_PTS (buf) = 40 * GST_MSECOND;
190   GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
191   gst_harness_push (h2, buf);
192 
193   /* Pull the first output buffer */
194   outbuf = gst_harness_pull (h);
195   fail_unless (outbuf != NULL);
196 
197   meta = gst_buffer_get_video_caption_meta (outbuf);
198   fail_unless (meta != NULL);
199   fail_unless_equals_int (meta->caption_type,
200       GST_VIDEO_CAPTION_TYPE_CEA708_RAW);
201   fail_unless_equals_int (meta->size, 128);
202 
203   gst_buffer_unref (outbuf);
204 
205   /* Push EOS on both pads get the second output buffer, we otherwise wait
206    * in case there are further captions for the current video buffer */
207   gst_harness_push_event (h, gst_event_new_eos ());
208   gst_harness_push_event (h2, gst_event_new_eos ());
209 
210   outbuf = gst_harness_pull (h);
211   fail_unless (outbuf != NULL);
212 
213   meta = gst_buffer_get_video_caption_meta (outbuf);
214   fail_unless (meta != NULL);
215   fail_unless_equals_int (meta->caption_type,
216       GST_VIDEO_CAPTION_TYPE_CEA708_CDP);
217   fail_unless_equals_int (meta->size, 128);
218 
219   gst_buffer_unref (outbuf);
220 
221   /* Caps should be equal to input caps */
222   caps = gst_pad_get_current_caps (h->sinkpad);
223   fail_unless (caps != NULL);
224   fail_unless (gst_caps_can_intersect (caps,
225           gst_static_caps_get (&foo_bar_caps)));
226   gst_caps_unref (caps);
227 
228   gst_harness_teardown (h);
229   gst_harness_teardown (h2);
230 }
231 
232 GST_END_TEST;
233 
234 static Suite *
cccombiner_suite(void)235 cccombiner_suite (void)
236 {
237   Suite *s = suite_create ("cccombiner");
238   TCase *tc = tcase_create ("general");
239 
240   suite_add_tcase (s, tc);
241 
242   tcase_add_test (tc, no_captions);
243   tcase_add_test (tc, captions_and_eos);
244   tcase_add_test (tc, captions_type_change_and_eos);
245 
246   return s;
247 }
248 
249 GST_CHECK_MAIN (cccombiner);
250