1 /* Gstreamer
2 * Copyright (C) <2011> Intel Corporation
3 * Copyright (C) <2011> Collabora Ltd.
4 * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21 #include <gst/check/gstcheck.h>
22 #include <gst/codecparsers/gsth264parser.h>
23
24 static guint8 slice_dpa[] = {
25 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x03, 0x00,
26 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x09, 0x00, 0x0a, 0x00,
27 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00,
28 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00,
29 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00,
30 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00,
31 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00,
32 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00,
33 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
34 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00,
35 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00,
36 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00,
37 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00,
38 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00,
39 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00,
40 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00,
41 0x5f, 0x00, 0x60, 0x00, 0x61, 0x01, 0x04, 0x00, 0xc4, 0x00, 0xa6, 0x00,
42 0xc5, 0x00, 0xab, 0x00, 0x82, 0x00, 0xc2, 0x00, 0xd8, 0x00, 0xc6, 0x00,
43 0xe4, 0x00, 0xbe, 0x00, 0xb0, 0x00, 0xe6, 0x00, 0xb6, 0x00, 0xb7, 0x00,
44 0xb4, 0x00, 0xb5, 0x00, 0x87, 0x00, 0xb2, 0x00, 0xb3, 0x00, 0xd9, 0x00,
45 0x8c, 0x00, 0xe5, 0x00, 0xbf, 0x00, 0xb1, 0x00, 0xe7, 0x00, 0xbb, 0x00,
46 0xa3, 0x00, 0x84, 0x00, 0x85, 0x00, 0xbd, 0x00, 0x96, 0x00, 0xe8, 0x00,
47 0x86, 0x00, 0x8e, 0x00, 0x8b, 0x00, 0x9d, 0x00, 0xa9, 0x00, 0x8a, 0x01,
48 0x05, 0x00, 0x83, 0x00, 0xf2, 0x00, 0xf3, 0x00, 0x8d, 0x00, 0x97, 0x00,
49 0x88, 0x00, 0xde, 0x00, 0xf1, 0x00, 0x9e, 0x00, 0xaa, 0x00, 0xf5, 0x00,
50 0xf4, 0x00, 0xf6, 0x00, 0xa2, 0x00, 0xad, 0x00, 0xc9, 0x00, 0xc7, 0x00,
51 0xae, 0x00, 0x62, 0x00, 0x63, 0x00, 0x90, 0x00, 0x64, 0x00, 0xcb, 0x00,
52 0x65, 0x00, 0xc8, 0x00, 0xca, 0x00, 0xcf, 0x00, 0xcc, 0x00, 0xcd, 0x00,
53 0xce, 0x00, 0xe9, 0x00, 0x66, 0x00, 0xd3, 0x00, 0xd0, 0x00, 0xd1, 0x00,
54 0xaf, 0x00, 0x67, 0x00, 0x91, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd5, 0x00,
55 0x68, 0x00, 0xeb, 0x00, 0xed, 0x00, 0x89, 0x00, 0x6a, 0x00, 0x69, 0x00,
56 0x6b, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x6e, 0x00, 0xa0, 0x00, 0x6f, 0x00,
57 0x71, 0x00, 0x70, 0x00, 0x72, 0x00, 0x73, 0x00, 0x75, 0x00, 0x74, 0x00,
58 0x76, 0x00, 0x77, 0x00, 0xea, 0x00, 0x78, 0x00, 0x7a, 0x00, 0x79, 0x00,
59 0x7b, 0x00, 0x7d, 0x00, 0x7c, 0x00, 0xa1, 0x00, 0x7f, 0x00, 0x7e, 0x00,
60 0x80, 0x00, 0x81, 0x00, 0xec, 0x00, 0xee, 0x00, 0xba, 0x01, 0x06, 0x00,
61 0xef, 0x00, 0xe1, 0x00, 0xe0, 0x00, 0xdc, 0x01, 0x07, 0x01, 0x08, 0x01,
62 0x09, 0x01, 0x0a, 0x01, 0x0b, 0x01, 0x0c, 0x00, 0xdb, 0x00, 0xe2, 0x01,
63 0x0d, 0x01, 0x0e, 0x01, 0x0f, 0x01, 0x10, 0x01, 0x11, 0x01, 0x12, 0x00,
64 0xdf, 0x01, 0x13, 0x01, 0x14, 0x01, 0x15, 0x01, 0x16, 0x01, 0x17, 0x00,
65 0xfd, 0x00, 0xff, 0x01, 0x18, 0x01, 0x19, 0x01, 0x1a, 0x01, 0x1b, 0x01,
66 0x1c, 0x01, 0x1d, 0x01, 0x1e, 0x01, 0x1f, 0x01, 0x20, 0x01, 0x21, 0x01,
67 0x22, 0x01, 0x23, 0x01, 0x24, 0x01, 0x25, 0x01, 0x26, 0x00, 0xfe, 0x01,
68 0x00, 0x01, 0x27, 0x01, 0x28, 0x01, 0x29, 0x01, 0x2a, 0x01, 0x2b, 0x01,
69 0x2c, 0x01, 0x2d, 0x01, 0x2e, 0x01, 0x2f, 0x01, 0x30, 0x01, 0x31, 0x00,
70 0xe3, 0x00, 0xd7, 0x01, 0x32, 0x00, 0xf8, 0x00, 0xf9, 0x01, 0x33, 0x01,
71 0x34, 0x01, 0x35, 0x01, 0x36, 0x01, 0x37, 0x01, 0x38, 0x01, 0x39, 0x01,
72 0x3a, 0x01, 0x3b, 0x01, 0x3c, 0x01, 0x3d, 0x01, 0x3e, 0x01, 0x3f, 0x01,
73 0x40, 0x01, 0x41, 0x01, 0x42, 0x01, 0x43, 0x01, 0x44, 0x01, 0x45, 0x01,
74 0x46, 0x01, 0x47, 0x01, 0x48, 0x01, 0x49, 0x01, 0x4a, 0x01, 0x4b, 0x01,
75 0x4c, 0x00, 0x08, 0x05, 0x2e, 0x6e, 0x75, 0x6c, 0x6c, 0x0c, 0x76, 0x69,
76 0x73, 0x69, 0x62, 0x6c, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x04, 0x45,
77 0x75, 0x72, 0x6f, 0x06, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x0a, 0x62,
78 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x74, 0x68, 0x06, 0x53, 0x61,
79 0x63, 0x75, 0x74, 0x65, 0x06, 0x54, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06,
80 0x5a, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x73, 0x61, 0x63, 0x75, 0x74,
81 0x65, 0x06, 0x74, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x7a, 0x61, 0x63,
82 0x75, 0x74, 0x65, 0x07, 0x41, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07,
83 0x61, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x0c, 0x73, 0x63, 0x6f, 0x6d,
84 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x53, 0x63, 0x6f,
85 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x5a, 0x64,
86 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x4c, 0x63, 0x61,
87 0x72, 0x6f, 0x6e, 0x06, 0x6c, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x0a, 0x7a,
88 0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x52, 0x61,
89 0x63, 0x75, 0x74, 0x65, 0x06, 0x41, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06,
90 0x4c, 0x61, 0x63, 0x75, 0x74, 0x65, 0x07, 0x45, 0x6f, 0x67, 0x6f, 0x6e,
91 0x65, 0x6b, 0x06, 0x45, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x44, 0x63,
92 0x61, 0x72, 0x6f, 0x6e, 0x07, 0x44, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e,
93 0x06, 0x4e, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x4e, 0x63, 0x61, 0x72,
94 0x6f, 0x6e, 0x0d, 0x4f, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d,
95 0x6c, 0x61, 0x75, 0x74, 0x06, 0x52, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x05,
96 0x55, 0x72, 0x69, 0x6e, 0x67, 0x09, 0x6e, 0x75, 0x6e, 0x67, 0x61, 0x64,
97 0x65, 0x73, 0x68, 0x0d, 0x55, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75,
98 0x6d, 0x6c, 0x61, 0x75, 0x74, 0x0c, 0x54, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
99 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x72, 0x61, 0x63, 0x75, 0x74,
100 0x65, 0x06, 0x61, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x6c, 0x61, 0x63,
101 0x75, 0x74, 0x65, 0x07, 0x65, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x06,
102 0x65, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x64, 0x63, 0x61, 0x72, 0x6f,
103 0x6e, 0x07, 0x64, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x06, 0x6e, 0x61,
104 0x63, 0x75, 0x74, 0x65, 0x06, 0x6e, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x0d,
105 0x6f, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d, 0x6c, 0x61, 0x75,
106 0x74, 0x06, 0x72, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x05, 0x75, 0x72, 0x69,
107 0x6e, 0x67, 0x0d, 0x75, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d,
108 0x6c, 0x61, 0x75, 0x74, 0x0c, 0x74, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61,
109 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x49, 0x64, 0x6f, 0x74, 0x61, 0x63,
110 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x52, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61,
111 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
112 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x49, 0x6f, 0x67, 0x6f, 0x6e,
113 0x65, 0x6b, 0x07, 0x41, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x45,
114 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x0a, 0x45, 0x64, 0x6f, 0x74, 0x61,
115 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x47, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
116 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x4b, 0x63, 0x6f, 0x6d, 0x6d,
117 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x49, 0x6d, 0x61, 0x63,
118 0x72, 0x6f, 0x6e, 0x0c, 0x4c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63,
119 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x4e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61,
120 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x4f, 0x6d, 0x61, 0x63, 0x72, 0x6f,
121 0x6e, 0x07, 0x55, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x55, 0x6d,
122 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x69, 0x6f, 0x67, 0x6f, 0x6e, 0x65,
123 0x6b, 0x07, 0x61, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x65, 0x6d,
124 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x0a, 0x65, 0x64, 0x6f, 0x74, 0x61, 0x63,
125 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x67, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61,
126 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x6b, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
127 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x69, 0x6d, 0x61, 0x63, 0x72,
128 0x6f, 0x6e, 0x0c, 0x6c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63,
129 0x65, 0x6e, 0x74, 0x0c, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63,
130 0x63, 0x65, 0x6e, 0x74, 0x07, 0x6f, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e,
131 0x07, 0x75, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x75, 0x6d, 0x61,
132 0x63, 0x72, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02
133 };
134
135 /* IDR slice, SEQ_END, IDR slice, STREAM_END */
136 static guint8 slice_eoseq_slice[] = {
137 0x00, 0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00,
138 0x10, 0xff, 0xfe, 0xf6, 0xf0, 0xfe, 0x05, 0x36,
139 0x56, 0x04, 0x50, 0x96, 0x7b, 0x3f, 0x53, 0xe1,
140 0x00, 0x00, 0x00, 0x01, 0x0a,
141 0x00, 0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00,
142 0x10, 0xff, 0xfe, 0xf6, 0xf0, 0xfe, 0x05, 0x36,
143 0x56, 0x04, 0x50, 0x96, 0x7b, 0x3f, 0x53, 0xe1,
144 0x00, 0x00, 0x00, 0x01, 0x0b
145 };
146
GST_START_TEST(test_h264_parse_slice_dpa)147 GST_START_TEST (test_h264_parse_slice_dpa)
148 {
149 GstH264ParserResult res;
150 GstH264NalUnit nalu;
151
152 GstH264NalParser *parser = gst_h264_nal_parser_new ();
153
154 res = gst_h264_parser_identify_nalu (parser, slice_dpa, 0,
155 sizeof (slice_dpa), &nalu);
156
157 assert_equals_int (res, GST_H264_PARSER_OK);
158 assert_equals_int (nalu.type, GST_H264_NAL_SLICE_DPA);
159
160 gst_h264_nal_parser_free (parser);
161 }
162
163 GST_END_TEST;
164
GST_START_TEST(test_h264_parse_slice_eoseq_slice)165 GST_START_TEST (test_h264_parse_slice_eoseq_slice)
166 {
167 GstH264ParserResult res;
168 GstH264NalUnit nalu;
169 GstH264NalParser *const parser = gst_h264_nal_parser_new ();
170 const guint8 *buf = slice_eoseq_slice;
171 guint n, buf_size = sizeof (slice_eoseq_slice);
172
173 res = gst_h264_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
174
175 assert_equals_int (res, GST_H264_PARSER_OK);
176 assert_equals_int (nalu.type, GST_H264_NAL_SLICE_IDR);
177 assert_equals_int (nalu.size, 20);
178
179 n = nalu.offset + nalu.size;
180 buf += n;
181 buf_size -= n;
182
183 res = gst_h264_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
184
185 assert_equals_int (res, GST_H264_PARSER_OK);
186 assert_equals_int (nalu.type, GST_H264_NAL_SEQ_END);
187 assert_equals_int (nalu.size, 1);
188
189 n = nalu.offset + nalu.size;
190 buf += n;
191 buf_size -= n;
192
193 res = gst_h264_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
194
195 assert_equals_int (res, GST_H264_PARSER_OK);
196 assert_equals_int (nalu.type, GST_H264_NAL_SLICE_IDR);
197 assert_equals_int (nalu.size, 20);
198
199 n = nalu.offset + nalu.size;
200 buf += n;
201 buf_size -= n;
202
203 res = gst_h264_parser_identify_nalu (parser, buf, 0, buf_size, &nalu);
204
205 assert_equals_int (res, GST_H264_PARSER_OK);
206 assert_equals_int (nalu.type, GST_H264_NAL_STREAM_END);
207 assert_equals_int (nalu.size, 1);
208
209 gst_h264_nal_parser_free (parser);
210 }
211
212 GST_END_TEST;
213
GST_START_TEST(test_h264_parse_slice_5bytes)214 GST_START_TEST (test_h264_parse_slice_5bytes)
215 {
216 GstH264ParserResult res;
217 GstH264NalUnit nalu;
218 GstH264NalParser *const parser = gst_h264_nal_parser_new ();
219 const guint8 *buf = slice_eoseq_slice;
220
221 res = gst_h264_parser_identify_nalu (parser, buf, 0, 5, &nalu);
222
223 assert_equals_int (res, GST_H264_PARSER_NO_NAL_END);
224 assert_equals_int (nalu.type, GST_H264_NAL_SLICE_IDR);
225 assert_equals_int (nalu.size, 1);
226
227 gst_h264_nal_parser_free (parser);
228 }
229
230 GST_END_TEST;
231
GST_START_TEST(test_h264_parse_identify_nalu_avc)232 GST_START_TEST (test_h264_parse_identify_nalu_avc)
233 {
234 GstH264ParserResult res;
235 GstH264NalUnit nalu;
236 GstH264NalParser *const parser = gst_h264_nal_parser_new ();
237 /* Skip 3 bytes for the start code */
238 const gsize nal_size = sizeof (slice_dpa) - 3;
239 const gsize buf_size = 4 + nal_size;
240 guint8 *buf = g_new (guint8, buf_size);
241
242 memcpy (buf + 4, slice_dpa + 3, nal_size);
243
244 GST_WRITE_UINT16_BE (buf + 2, nal_size);
245 res = gst_h264_parser_identify_nalu_avc (parser, buf, 2, buf_size, 2, &nalu);
246
247 assert_equals_int (res, GST_H264_PARSER_OK);
248 assert_equals_int (nalu.type, GST_H264_NAL_SLICE_DPA);
249 assert_equals_int (nalu.offset, 4);
250 assert_equals_int (nalu.size, nal_size);
251
252 GST_WRITE_UINT32_BE (buf, nal_size);
253 res = gst_h264_parser_identify_nalu_avc (parser, buf, 0, buf_size, 4, &nalu);
254
255 assert_equals_int (res, GST_H264_PARSER_OK);
256 assert_equals_int (nalu.type, GST_H264_NAL_SLICE_DPA);
257 assert_equals_int (nalu.offset, 4);
258 assert_equals_int (nalu.size, nal_size);
259
260 GST_WRITE_UINT32_BE (buf, G_MAXUINT32);
261 res = gst_h264_parser_identify_nalu_avc (parser, buf, 0, buf_size, 4, &nalu);
262
263 assert_equals_int (res, GST_H264_PARSER_BROKEN_DATA);
264
265 GST_WRITE_UINT32_BE (buf, G_MAXUINT32 - 2);
266 res = gst_h264_parser_identify_nalu_avc (parser, buf, 0, buf_size, 4, &nalu);
267
268 assert_equals_int (res, GST_H264_PARSER_BROKEN_DATA);
269
270 GST_WRITE_UINT32_BE (buf, G_MAXUINT32 - 3);
271 res = gst_h264_parser_identify_nalu_avc (parser, buf, 0, buf_size, 4, &nalu);
272
273 assert_equals_int (res, GST_H264_PARSER_BROKEN_DATA);
274
275 GST_WRITE_UINT32_BE (buf, G_MAXUINT32 - 4);
276 res = gst_h264_parser_identify_nalu_avc (parser, buf, 0, buf_size, 4, &nalu);
277
278 assert_equals_int (res, GST_H264_PARSER_NO_NAL_END);
279
280 GST_WRITE_UINT32_BE (buf, G_MAXUINT32 - 6);
281 res = gst_h264_parser_identify_nalu_avc (parser, buf, 0, buf_size, 4, &nalu);
282
283 assert_equals_int (res, GST_H264_PARSER_NO_NAL_END);
284
285 g_free (buf);
286 gst_h264_nal_parser_free (parser);
287 }
288
289 GST_END_TEST;
290
291 static guint8 nalu_sps_with_vui[] = {
292 0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x28,
293 0xac, 0xd9, 0x40, 0x78, 0x04, 0x4f, 0xde, 0x03,
294 0xd2, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01, 0xf4,
295 0x80, 0x00, 0x75, 0x30, 0x4f, 0x8b, 0x16, 0xcb
296 };
297
298 static guint8 nalu_sei_pic_timing[] = {
299 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x01, 0x32, 0x80
300 };
301
302 static guint8 nalu_chained_sei[] = {
303 0x00, 0x00, 0x01, 0x06, 0x01, 0x02, 0x32, 0x80,
304 0x06, 0x01, 0xc4, 0x80
305 };
306
307 /* Content light level information SEI message */
308 static guint8 h264_sei_cll[] = {
309 0x00, 0x00, 0x00, 0x01, 0x06, 0x90, 0x04, 0x03, 0xe8, 0x01, 0x90, 0x80
310 };
311
312 /* Mastering display colour volume information SEI message */
313 static guint8 h264_sei_mdcv[] = {
314 0x00, 0x00, 0x00, 0x01, 0x06, 0x89, 0x18, 0x84,
315 0xd0, 0x3e, 0x80, 0x33, 0x90, 0x86, 0xc4, 0x1d,
316 0x4c, 0x0b, 0xb8, 0x3d, 0x13, 0x40, 0x42, 0x00,
317 0x98, 0x96, 0x80, 0x00, 0x00, 0x03, 0x00, 0x01,
318 0x80
319 };
320
321 /* closed caption data */
322 static guint8 h264_sei_user_data_registered[] = {
323 0x00, 0x00, 0x00, 0x01, 0x06, 0x04, 0x47, 0xb5, 0x00, 0x31, 0x47, 0x41,
324 0x39, 0x34, 0x03, 0xd4,
325 0xff, 0xfc, 0x80, 0x80, 0xfd, 0x80, 0x80, 0xfa, 0x00, 0x00, 0xfa, 0x00,
326 0x00, 0xfa, 0x00, 0x00,
327 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
328 0xfa, 0x00, 0x00, 0xfa,
329 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
330 0x00, 0x00, 0xfa, 0x00,
331 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00,
332 0x00, 0xff, 0x80
333 };
334
335 /* frame packing, side-by-side */
336 static guint8 h264_sei_frame_packing[] = {
337 0x00, 0x00, 0x00, 0x01, 0x06, 0x2d, 0x07, 0x81, 0x81, 0x00, 0x00, 0x03,
338 0x00, 0x01, 0x20, 0x80
339 };
340
GST_START_TEST(test_h264_parse_invalid_sei)341 GST_START_TEST (test_h264_parse_invalid_sei)
342 {
343 GstH264ParserResult res;
344 GstH264NalUnit nalu;
345 GstH264NalParser *const parser = gst_h264_nal_parser_new ();
346 const guint8 *buf = nalu_sps_with_vui;
347 GArray *seis = NULL;
348 GstH264SEIMessage *sei;
349
350 /* First try parsing the SEI, which will fail because there's no SPS yet */
351 res =
352 gst_h264_parser_identify_nalu (parser, nalu_sei_pic_timing, 0,
353 sizeof (nalu_sei_pic_timing), &nalu);
354 assert_equals_int (res, GST_H264_PARSER_NO_NAL_END);
355 assert_equals_int (nalu.type, GST_H264_NAL_SEI);
356
357 res = gst_h264_parser_parse_sei (parser, &nalu, &seis);
358 assert_equals_int (res, GST_H264_PARSER_BROKEN_LINK);
359 g_array_free (seis, TRUE);
360
361 /* Inject SPS */
362 res =
363 gst_h264_parser_identify_nalu (parser, buf, 0, sizeof (nalu_sps_with_vui),
364 &nalu);
365 assert_equals_int (res, GST_H264_PARSER_NO_NAL_END);
366 assert_equals_int (nalu.type, GST_H264_NAL_SPS);
367 assert_equals_int (nalu.size, 28);
368
369 res = gst_h264_parser_parse_nal (parser, &nalu);
370 assert_equals_int (res, GST_H264_PARSER_OK);
371
372 /* Parse the SEI again */
373 res =
374 gst_h264_parser_identify_nalu (parser, nalu_sei_pic_timing, 0,
375 sizeof (nalu_sei_pic_timing), &nalu);
376 assert_equals_int (res, GST_H264_PARSER_NO_NAL_END);
377 assert_equals_int (nalu.type, GST_H264_NAL_SEI);
378
379 res = gst_h264_parser_parse_sei (parser, &nalu, &seis);
380 assert_equals_int (res, GST_H264_PARSER_OK);
381 fail_if (seis == NULL);
382 assert_equals_int (seis->len, 1);
383 g_array_free (seis, TRUE);
384
385 /* Parse NALU with 2 chained SEI */
386 res =
387 gst_h264_parser_identify_nalu (parser, nalu_chained_sei, 0,
388 sizeof (nalu_chained_sei), &nalu);
389 assert_equals_int (res, GST_H264_PARSER_NO_NAL_END);
390 assert_equals_int (nalu.type, GST_H264_NAL_SEI);
391
392 res = gst_h264_parser_parse_sei (parser, &nalu, &seis);
393 assert_equals_int (res, GST_H264_PARSER_OK);
394 fail_if (seis == NULL);
395 assert_equals_int (seis->len, 2);
396 sei = &g_array_index (seis, GstH264SEIMessage, 0);
397 assert_equals_int (sei->payloadType, GST_H264_SEI_PIC_TIMING);
398
399 sei = &g_array_index (seis, GstH264SEIMessage, 1);
400 assert_equals_int (sei->payloadType, GST_H264_SEI_RECOVERY_POINT);
401
402 g_array_free (seis, TRUE);
403
404 gst_h264_nal_parser_free (parser);
405 }
406
407 GST_END_TEST;
408
409 typedef gboolean (*SEICheckFunc) (gconstpointer a, gconstpointer b);
410
411 static gboolean
check_sei_user_data_registered(const GstH264RegisteredUserData * a,const GstH264RegisteredUserData * b)412 check_sei_user_data_registered (const GstH264RegisteredUserData * a,
413 const GstH264RegisteredUserData * b)
414 {
415 if (a->country_code != b->country_code)
416 return FALSE;
417
418 if ((a->country_code == 0xff) &&
419 (a->country_code_extension != b->country_code_extension))
420 return FALSE;
421
422 if (a->size != b->size)
423 return FALSE;
424
425 return !memcmp (a->data, b->data, a->size);
426 }
427
428 static gboolean
check_sei_frame_packing(const GstH264FramePacking * a,const GstH264FramePacking * b)429 check_sei_frame_packing (const GstH264FramePacking * a,
430 const GstH264FramePacking * b)
431 {
432 if ((a->frame_packing_id != b->frame_packing_id) ||
433 (a->frame_packing_cancel_flag != b->frame_packing_cancel_flag))
434 return FALSE;
435
436 if (!a->frame_packing_cancel_flag) {
437 if ((a->frame_packing_type != b->frame_packing_type) ||
438 (a->quincunx_sampling_flag != b->quincunx_sampling_flag) ||
439 (a->content_interpretation_type != b->content_interpretation_type) ||
440 (a->spatial_flipping_flag != b->spatial_flipping_flag) ||
441 (a->frame0_flipped_flag != b->frame0_flipped_flag) ||
442 (a->field_views_flag != b->field_views_flag) ||
443 (a->current_frame_is_frame0_flag != b->current_frame_is_frame0_flag) ||
444 (a->frame0_self_contained_flag != b->frame0_self_contained_flag) ||
445 (a->frame1_self_contained_flag != b->frame1_self_contained_flag))
446 return FALSE;
447
448 if (!a->quincunx_sampling_flag &&
449 a->frame_packing_type != GST_H264_FRAME_PACKING_TEMPORAL_INTERLEAVING) {
450 if ((a->frame0_grid_position_x != b->frame0_grid_position_x) ||
451 (a->frame0_grid_position_y != b->frame0_grid_position_y) ||
452 (a->frame1_grid_position_x != b->frame1_grid_position_x) ||
453 (a->frame1_grid_position_y != b->frame1_grid_position_y))
454 return FALSE;
455 }
456
457 if (a->frame_packing_repetition_period !=
458 b->frame_packing_repetition_period)
459 return FALSE;
460 }
461
462 return TRUE;
463 }
464
465 static gboolean
check_sei_mdcv(const GstH264MasteringDisplayColourVolume * a,const GstH264MasteringDisplayColourVolume * b)466 check_sei_mdcv (const GstH264MasteringDisplayColourVolume * a,
467 const GstH264MasteringDisplayColourVolume * b)
468 {
469 gint i;
470 for (i = 0; i < 3; i++) {
471 if (a->display_primaries_x[i] != b->display_primaries_x[i] ||
472 a->display_primaries_y[i] != b->display_primaries_y[i])
473 return FALSE;
474 }
475
476 return (a->white_point_x == b->white_point_x) &&
477 (a->white_point_y == b->white_point_y) &&
478 (a->max_display_mastering_luminance == b->max_display_mastering_luminance)
479 && (a->min_display_mastering_luminance ==
480 b->min_display_mastering_luminance);
481 }
482
483 static gboolean
check_sei_cll(const GstH264ContentLightLevel * a,const GstH264ContentLightLevel * b)484 check_sei_cll (const GstH264ContentLightLevel * a,
485 const GstH264ContentLightLevel * b)
486 {
487 return (a->max_content_light_level == b->max_content_light_level) &&
488 (a->max_pic_average_light_level == b->max_pic_average_light_level);
489 }
490
491 static gboolean
check_sei_pic_timing(const GstH264PicTiming * a,const GstH264PicTiming * b)492 check_sei_pic_timing (const GstH264PicTiming * a, const GstH264PicTiming * b)
493 {
494 if (a->CpbDpbDelaysPresentFlag != b->CpbDpbDelaysPresentFlag)
495 return FALSE;
496
497 if (a->CpbDpbDelaysPresentFlag) {
498 if (a->cpb_removal_delay != b->cpb_removal_delay ||
499 a->cpb_removal_delay_length_minus1 != b->cpb_removal_delay_length_minus1
500 || a->dpb_output_delay != b->dpb_output_delay
501 || a->dpb_output_delay_length_minus1 !=
502 b->dpb_output_delay_length_minus1)
503 return FALSE;
504 }
505
506 if (a->pic_struct_present_flag != b->pic_struct_present_flag)
507 return FALSE;
508
509 if (a->pic_struct_present_flag) {
510 const guint8 num_clock_ts_table[9] = {
511 1, 1, 1, 2, 2, 3, 3, 2, 3
512 };
513 guint8 num_clock_num_ts;
514 guint i;
515
516 if (a->pic_struct != b->pic_struct)
517 return FALSE;
518
519 if (a->time_offset_length != b->time_offset_length)
520 return FALSE;
521
522 num_clock_num_ts = num_clock_ts_table[a->pic_struct];
523
524 for (i = 0; i < num_clock_num_ts; i++) {
525 if (a->clock_timestamp_flag[i] != b->clock_timestamp_flag[i])
526 return FALSE;
527
528 if (a->clock_timestamp_flag[i]) {
529 const GstH264ClockTimestamp *ta = &a->clock_timestamp[i];
530 const GstH264ClockTimestamp *tb = &b->clock_timestamp[i];
531
532 if (ta->ct_type != tb->ct_type ||
533 ta->nuit_field_based_flag != tb->nuit_field_based_flag ||
534 ta->counting_type != tb->counting_type ||
535 ta->discontinuity_flag != tb->discontinuity_flag ||
536 ta->cnt_dropped_flag != tb->cnt_dropped_flag ||
537 ta->n_frames != tb->n_frames)
538 return FALSE;
539
540 if (ta->full_timestamp_flag) {
541 if (ta->seconds_value != tb->seconds_value ||
542 ta->minutes_value != tb->minutes_value ||
543 ta->hours_value != tb->hours_value)
544 return FALSE;
545 } else {
546 if (ta->seconds_flag != tb->seconds_flag)
547 return FALSE;
548
549 if (ta->seconds_flag) {
550 if (ta->seconds_value != tb->seconds_value ||
551 ta->minutes_flag != tb->minutes_flag)
552 return FALSE;
553
554 if (ta->minutes_flag) {
555 if (ta->minutes_value != tb->minutes_value ||
556 ta->hours_flag != tb->hours_flag)
557 return FALSE;
558
559 if (ta->hours_flag) {
560 if (ta->hours_value != tb->hours_value)
561 return FALSE;
562 }
563 }
564 }
565 }
566
567 if (ta->time_offset != tb->time_offset)
568 return FALSE;
569 }
570 }
571 }
572
573 return TRUE;
574 }
575
GST_START_TEST(test_h264_create_sei)576 GST_START_TEST (test_h264_create_sei)
577 {
578 GstH264NalParser *parser;
579 GstH264ParserResult parse_ret;
580 GstH264NalUnit nalu;
581 GArray *msg_array = NULL;
582 GstMemory *mem;
583 gint i;
584 GstMapInfo info;
585 struct
586 {
587 guint8 *raw_data;
588 guint len;
589 GstH264SEIPayloadType type;
590 GstH264SEIMessage parsed_message;
591 SEICheckFunc check_func;
592 } test_list[] = {
593 /* *INDENT-OFF* */
594 {h264_sei_user_data_registered, G_N_ELEMENTS (h264_sei_user_data_registered),
595 GST_H264_SEI_REGISTERED_USER_DATA, {0,},
596 (SEICheckFunc) check_sei_user_data_registered},
597 {h264_sei_frame_packing, G_N_ELEMENTS (h264_sei_frame_packing),
598 GST_H264_SEI_FRAME_PACKING, {0,},
599 (SEICheckFunc) check_sei_frame_packing},
600 {h264_sei_mdcv, G_N_ELEMENTS (h264_sei_mdcv),
601 GST_H264_SEI_MASTERING_DISPLAY_COLOUR_VOLUME, {0,},
602 (SEICheckFunc) check_sei_mdcv},
603 {h264_sei_cll, G_N_ELEMENTS (h264_sei_cll),
604 GST_H264_SEI_CONTENT_LIGHT_LEVEL, {0,},
605 (SEICheckFunc) check_sei_cll},
606 {nalu_sei_pic_timing, G_N_ELEMENTS (nalu_sei_pic_timing),
607 GST_H264_SEI_PIC_TIMING, {0,},
608 (SEICheckFunc) check_sei_pic_timing},
609 /* *INDENT-ON* */
610 };
611
612 parser = gst_h264_nal_parser_new ();
613
614 /* inject SPS for picture timing sei */
615 parse_ret =
616 gst_h264_parser_identify_nalu_unchecked (parser, nalu_sps_with_vui, 0,
617 sizeof (nalu_sps_with_vui), &nalu);
618 assert_equals_int (parse_ret, GST_H264_PARSER_OK);
619 assert_equals_int (nalu.type, GST_H264_NAL_SPS);
620 assert_equals_int (nalu.size, 28);
621
622 parse_ret = gst_h264_parser_parse_nal (parser, &nalu);
623 assert_equals_int (parse_ret, GST_H264_PARSER_OK);
624
625 /* test single sei message per sei nal unit */
626 for (i = 0; i < G_N_ELEMENTS (test_list); i++) {
627 gsize nal_size;
628
629 parse_ret = gst_h264_parser_identify_nalu_unchecked (parser,
630 test_list[i].raw_data, 0, test_list[i].len, &nalu);
631 assert_equals_int (parse_ret, GST_H264_PARSER_OK);
632 assert_equals_int (nalu.type, GST_H264_NAL_SEI);
633
634 parse_ret = gst_h264_parser_parse_sei (parser, &nalu, &msg_array);
635 assert_equals_int (parse_ret, GST_H264_PARSER_OK);
636 assert_equals_int (msg_array->len, 1);
637
638 /* test bytestream */
639 mem = gst_h264_create_sei_memory (4, msg_array);
640 fail_unless (mem != NULL);
641 fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
642 GST_MEMDUMP ("created sei nal", info.data, info.size);
643 GST_MEMDUMP ("original sei nal", test_list[i].raw_data, test_list[i].len);
644 assert_equals_int (info.size, test_list[i].len);
645 fail_if (memcmp (info.data, test_list[i].raw_data, test_list[i].len));
646 gst_memory_unmap (mem, &info);
647 gst_memory_unref (mem);
648
649 /* test packetized */
650 mem = gst_h264_create_sei_memory_avc (4, msg_array);
651 fail_unless (mem != NULL);
652 fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
653 assert_equals_int (info.size, test_list[i].len);
654 fail_if (memcmp (info.data + 4, test_list[i].raw_data + 4,
655 test_list[i].len - 4));
656 nal_size = GST_READ_UINT32_BE (info.data);
657 assert_equals_int (nal_size, info.size - 4);
658 gst_memory_unmap (mem, &info);
659 gst_memory_unref (mem);
660
661 /* store parsed SEI for following tests */
662 test_list[i].parsed_message =
663 g_array_index (msg_array, GstH264SEIMessage, 0);
664 if (test_list[i].type == GST_H264_SEI_REGISTERED_USER_DATA) {
665 GstH264RegisteredUserData *dst_rud =
666 &test_list[i].parsed_message.payload.registered_user_data;
667 const GstH264SEIMessage *src_msg =
668 &g_array_index (msg_array, GstH264SEIMessage, 0);
669 const GstH264RegisteredUserData *src_rud =
670 &src_msg->payload.registered_user_data;
671
672 dst_rud->data = g_malloc (src_rud->size);
673 memcpy ((guint8 *) dst_rud->data, src_rud->data, src_rud->size);
674 }
675 g_array_unref (msg_array);
676 }
677
678 /* test multiple SEI messages in a nal unit */
679 msg_array = g_array_new (FALSE, FALSE, sizeof (GstH264SEIMessage));
680 for (i = 0; i < G_N_ELEMENTS (test_list); i++)
681 g_array_append_val (msg_array, test_list[i].parsed_message);
682
683 mem = gst_h264_create_sei_memory (4, msg_array);
684 fail_unless (mem != NULL);
685 g_array_unref (msg_array);
686
687 /* parse sei message from buffer */
688 fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
689 parse_ret = gst_h264_parser_identify_nalu_unchecked (parser,
690 info.data, 0, info.size, &nalu);
691 assert_equals_int (parse_ret, GST_H264_PARSER_OK);
692 assert_equals_int (nalu.type, GST_H264_NAL_SEI);
693 parse_ret = gst_h264_parser_parse_sei (parser, &nalu, &msg_array);
694 gst_memory_unmap (mem, &info);
695 gst_memory_unref (mem);
696
697 assert_equals_int (parse_ret, GST_H264_PARSER_OK);
698 assert_equals_int (msg_array->len, G_N_ELEMENTS (test_list));
699 for (i = 0; i < msg_array->len; i++) {
700 GstH264SEIMessage *msg = &g_array_index (msg_array, GstH264SEIMessage, i);
701
702 assert_equals_int (msg->payloadType, test_list[i].type);
703 fail_unless (test_list[i].check_func (&msg->payload,
704 &test_list[i].parsed_message.payload));
705 }
706
707 /* clean up */
708 for (i = 0; i < G_N_ELEMENTS (test_list); i++)
709 gst_h264_sei_clear (&test_list[i].parsed_message);
710
711 g_array_unref (msg_array);
712 gst_h264_nal_parser_free (parser);
713 }
714
715 GST_END_TEST;
716
717 static Suite *
h264parser_suite(void)718 h264parser_suite (void)
719 {
720 Suite *s = suite_create ("H264 Parser library");
721
722 TCase *tc_chain = tcase_create ("general");
723
724 suite_add_tcase (s, tc_chain);
725 tcase_add_test (tc_chain, test_h264_parse_slice_dpa);
726 tcase_add_test (tc_chain, test_h264_parse_slice_eoseq_slice);
727 tcase_add_test (tc_chain, test_h264_parse_slice_5bytes);
728 tcase_add_test (tc_chain, test_h264_parse_identify_nalu_avc);
729 tcase_add_test (tc_chain, test_h264_parse_invalid_sei);
730 tcase_add_test (tc_chain, test_h264_create_sei);
731
732 return s;
733 }
734
735 GST_CHECK_MAIN (h264parser);
736