1 /*
2 V4L2 API codec ioctl tests.
3
4 Copyright (C) 2012 Hans Verkuil <hverkuil-cisco@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program 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
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
19 */
20
21 #include <map>
22 #include <set>
23
24 #include <sys/types.h>
25
26 #include "v4l2-compliance.h"
27
testEncoder(struct node * node)28 int testEncoder(struct node *node)
29 {
30 struct v4l2_encoder_cmd cmd;
31 bool is_encoder = node->codec_mask & (STATEFUL_ENCODER | JPEG_ENCODER);
32 int ret;
33
34 fail_on_test((node->codec_mask & STATELESS_ENCODER) && !node->has_media);
35 if (IS_ENCODER(node) && node->has_media)
36 fail_on_test(node->function != MEDIA_ENT_F_PROC_VIDEO_ENCODER);
37 memset(&cmd, 0xff, sizeof(cmd));
38 memset(&cmd.raw, 0, sizeof(cmd.raw));
39 ret = doioctl(node, VIDIOC_ENCODER_CMD, &cmd);
40 if (ret == ENOTTY) {
41 fail_on_test(is_encoder);
42 fail_on_test(doioctl(node, VIDIOC_TRY_ENCODER_CMD, &cmd) != ENOTTY);
43 return ret;
44 }
45 fail_on_test(IS_DECODER(node));
46 fail_on_test(ret != EINVAL);
47 ret = doioctl(node, VIDIOC_TRY_ENCODER_CMD, &cmd);
48 fail_on_test(ret == ENOTTY);
49 fail_on_test(ret != EINVAL);
50
51 cmd.cmd = V4L2_ENC_CMD_STOP;
52 cmd.flags = ~0U;
53 ret = doioctl(node, VIDIOC_TRY_ENCODER_CMD, &cmd);
54 fail_on_test(ret != 0);
55 fail_on_test(cmd.flags & ~V4L2_ENC_CMD_STOP_AT_GOP_END);
56 fail_on_test(is_encoder && cmd.flags);
57 cmd.flags = 0;
58 ret = doioctl(node, VIDIOC_TRY_ENCODER_CMD, &cmd);
59 fail_on_test(ret != 0);
60 ret = doioctl(node, VIDIOC_ENCODER_CMD, &cmd);
61 fail_on_test(ret != 0);
62
63 cmd.cmd = V4L2_ENC_CMD_START;
64 cmd.flags = ~0U;
65 ret = doioctl(node, VIDIOC_TRY_ENCODER_CMD, &cmd);
66 fail_on_test(ret != 0);
67 fail_on_test(cmd.flags);
68
69 cmd.cmd = V4L2_ENC_CMD_PAUSE;
70 ret = doioctl(node, VIDIOC_ENCODER_CMD, &cmd);
71 fail_on_test(ret != EPERM && ret != EINVAL);
72 fail_on_test(is_encoder && ret != EINVAL);
73
74 cmd.cmd = V4L2_ENC_CMD_RESUME;
75 ret = doioctl(node, VIDIOC_ENCODER_CMD, &cmd);
76 fail_on_test(ret != EPERM && ret != EINVAL);
77 fail_on_test(is_encoder && ret != EINVAL);
78 return 0;
79 }
80
testEncIndex(struct node * node)81 int testEncIndex(struct node *node)
82 {
83 struct v4l2_enc_idx idx;
84 int ret;
85
86 memset(&idx, 0xff, sizeof(idx));
87 ret = doioctl(node, VIDIOC_G_ENC_INDEX, &idx);
88 if (ret == ENOTTY)
89 return ret;
90 if (check_0(idx.reserved, sizeof(idx.reserved)))
91 return fail("idx.reserved not zeroed\n");
92 fail_on_test(ret);
93 fail_on_test(idx.entries != 0);
94 fail_on_test(idx.entries_cap == 0);
95 return 0;
96 }
97
testDecoder(struct node * node)98 int testDecoder(struct node *node)
99 {
100 struct v4l2_decoder_cmd cmd;
101 bool is_decoder = node->codec_mask & (STATEFUL_DECODER | JPEG_DECODER);
102 bool is_stateless = node->codec_mask & STATELESS_DECODER;
103 int ret;
104
105 fail_on_test((node->codec_mask & STATELESS_DECODER) && !node->has_media);
106 if (IS_DECODER(node) && node->has_media)
107 fail_on_test(node->function != MEDIA_ENT_F_PROC_VIDEO_DECODER);
108 memset(&cmd, 0xff, sizeof(cmd));
109 memset(&cmd.raw, 0, sizeof(cmd.raw));
110 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
111 if (ret == ENOTTY) {
112 fail_on_test(is_decoder);
113 fail_on_test(doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd) != ENOTTY);
114 return ret;
115 }
116 fail_on_test(IS_ENCODER(node));
117 fail_on_test(ret != EINVAL);
118 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
119 fail_on_test(ret == ENOTTY);
120 fail_on_test(ret != EINVAL);
121
122 if (is_stateless) {
123 cmd.cmd = V4L2_DEC_CMD_FLUSH;
124 cmd.flags = 0;
125 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
126 fail_on_test(ret);
127 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
128 fail_on_test(ret);
129
130 cmd.cmd = V4L2_DEC_CMD_STOP;
131 cmd.flags = 0;
132 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
133 fail_on_test(!ret);
134 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
135 fail_on_test(!ret);
136
137 cmd.cmd = V4L2_DEC_CMD_START;
138 cmd.flags = 0;
139 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
140 fail_on_test(!ret);
141 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
142 fail_on_test(!ret);
143
144 cmd.cmd = V4L2_DEC_CMD_PAUSE;
145 cmd.flags = 0;
146 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
147 fail_on_test(!ret);
148 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
149 fail_on_test(!ret);
150
151 cmd.cmd = V4L2_DEC_CMD_RESUME;
152 cmd.flags = 0;
153 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
154 fail_on_test(!ret);
155 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
156 fail_on_test(!ret);
157 } else {
158 cmd.cmd = V4L2_DEC_CMD_STOP;
159 cmd.flags = ~0;
160 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
161 fail_on_test(ret);
162 fail_on_test(cmd.flags & ~(V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY));
163 fail_on_test(is_decoder && cmd.flags);
164 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
165 fail_on_test(ret);
166
167 cmd.cmd = V4L2_DEC_CMD_START;
168 cmd.flags = ~0;
169 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
170 fail_on_test(ret);
171 fail_on_test(cmd.flags & ~V4L2_DEC_CMD_START_MUTE_AUDIO);
172 fail_on_test(is_decoder && cmd.flags);
173
174 cmd.cmd = V4L2_DEC_CMD_START;
175 cmd.flags = 0;
176 cmd.start.speed = ~0;
177 cmd.start.format = ~0U;
178 ret = doioctl(node, VIDIOC_TRY_DECODER_CMD, &cmd);
179 fail_on_test(ret);
180 fail_on_test(cmd.start.format == ~0U);
181 fail_on_test(cmd.start.speed == ~0);
182 fail_on_test(is_decoder && cmd.start.format);
183 fail_on_test(is_decoder && cmd.start.speed);
184
185 cmd.cmd = V4L2_DEC_CMD_PAUSE;
186 cmd.flags = 0;
187 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
188 fail_on_test(ret != EPERM && ret != EINVAL);
189 fail_on_test(is_decoder && ret != EINVAL);
190
191 cmd.cmd = V4L2_DEC_CMD_RESUME;
192 ret = doioctl(node, VIDIOC_DECODER_CMD, &cmd);
193 fail_on_test(ret != EPERM && ret != EINVAL);
194 fail_on_test(is_decoder && ret != EINVAL);
195 }
196
197 return 0;
198 }
199