1 /* 2 * v4l-test: Test environment for Video For Linux Two API 3 * 4 * 29 Mar 2009 0.2 Comments updated 5 * 18 Mar 2009 0.1 First release 6 * 7 * Written by Mrton Nmeth <nm127 (at) freemail.hu> 8 * Released under GPL 9 */ 10 11 #include <stdio.h> 12 #include <sys/types.h> 13 #include <sys/stat.h> 14 #include <fcntl.h> 15 #include <unistd.h> 16 #include <sys/ioctl.h> 17 #include <errno.h> 18 #include <string.h> 19 20 #include <linux/videodev2.h> 21 #include <linux/errno.h> 22 23 #include <CUnit/CUnit.h> 24 25 #include "v4l2_test.h" 26 #include "dev_video.h" 27 #include "video_limits.h" 28 29 #include "test_VIDIOC_PARM.h" 30 31 int valid_v4l2_captureparm_capability(__u32 capability) 32 { 33 int valid = 0; 34 35 if ((capability & ~(V4L2_CAP_TIMEPERFRAME)) == 0) { 36 valid = 1; 37 } else { 38 valid = 0; 39 } 40 return valid; 41 } 42 43 int valid_v4l2_outputparm_capability(__u32 capability) 44 { 45 int valid = 0; 46 47 if ((capability & ~(V4L2_CAP_TIMEPERFRAME)) == 0) { 48 valid = 1; 49 } else { 50 valid = 0; 51 } 52 return valid; 53 } 54 55 int valid_v4l2_captureparm_capturemode(__u32 capturemode) 56 { 57 int valid = 0; 58 59 if ((capturemode & ~(V4L2_MODE_HIGHQUALITY)) == 0) { 60 valid = 1; 61 } else { 62 valid = 0; 63 } 64 return valid; 65 } 66 67 int valid_v4l2_outputparm_outputpmode(__u32 outputmode) 68 { 69 int valid = 0; 70 71 if ((outputmode & ~(V4L2_MODE_HIGHQUALITY)) == 0) { 72 valid = 1; 73 } else { 74 valid = 0; 75 } 76 return valid; 77 } 78 79 static void do_get_param(enum v4l2_buf_type type) 80 { 81 int ret_get, errno_get; 82 struct v4l2_streamparm parm; 83 struct v4l2_streamparm parm2; 84 85 memset(&parm, 0xff, sizeof(parm)); 86 parm.type = type; 87 ret_get = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm); 88 errno_get = errno; 89 90 dprintf("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_get=%i, errno_get=%i\n", 91 __FILE__, __LINE__, type, ret_get, errno_get); 92 93 if (ret_get == 0) { 94 CU_ASSERT_EQUAL(ret_get, 0); 95 CU_ASSERT_EQUAL(parm.type, type); 96 97 switch (parm.type) { 98 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 99 dprintf("\t%s:%u: { .type=%i, parm.capture = { " 100 ".capability = 0x%X, " 101 ".capturemode = 0x%X, " 102 ".timeperframe = { .numerator = %u, .denominator = %u }, " 103 ".extendedmode = %u, " 104 ".readbuffers = %u, " 105 "reserved[] = { 0x%X, 0x%X, 0x%X, 0x%X }}}\n", 106 __FILE__, __LINE__, 107 parm.type, 108 parm.parm.capture.capability, 109 parm.parm.capture.capturemode, 110 parm.parm.capture.timeperframe.numerator, 111 parm.parm.capture.timeperframe.denominator, 112 parm.parm.capture.extendedmode, 113 parm.parm.capture.readbuffers, 114 parm.parm.capture.reserved[0], 115 parm.parm.capture.reserved[1], 116 parm.parm.capture.reserved[2], 117 parm.parm.capture.reserved[3] 118 ); 119 120 CU_ASSERT(valid_v4l2_captureparm_capability 121 (parm.parm.capture.capability)); 122 CU_ASSERT(valid_v4l2_captureparm_capturemode 123 (parm.parm.capture.capturemode)); 124 125 if (parm.parm.capture. 126 capability & V4L2_CAP_TIMEPERFRAME) { 127 //CU_ASSERT_EQUAL(parm.parm.capture.timeperframe.numerator, ???); 128 //CU_ASSERT_EQUAL(parm.parm.capture.timeperframe.denominator, ???); 129 CU_ASSERT(parm.parm.capture.timeperframe. 130 denominator != 0); 131 // TODO: timerperframe: check struct v4l2_standard frameperiod field 132 } else { 133 //CU_ASSERT_EQUAL(parm.parm.capture.timeperframe.numerator, 0); 134 //CU_ASSERT_EQUAL(parm.parm.capture.timeperframe.denominator, 0); 135 CU_ASSERT(parm.parm.output.timeperframe. 136 denominator != 0); 137 } 138 139 //CU_ASSERT_EQUAL(parm.parm.capture.extendedmode, ???); 140 //CU_ASSERT_EQUAL(parm.parm.capture.readbuffers, ???); 141 142 CU_ASSERT_EQUAL(parm.parm.capture.reserved[0], 0); 143 CU_ASSERT_EQUAL(parm.parm.capture.reserved[1], 0); 144 CU_ASSERT_EQUAL(parm.parm.capture.reserved[2], 0); 145 CU_ASSERT_EQUAL(parm.parm.capture.reserved[3], 0); 146 break; 147 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 148 dprintf("\t%s:%u: { .type=%i, parm.output = { " 149 ".capability = 0x%X, " 150 ".outputmode = 0x%X, " 151 ".timeperframe = { .numerator = %u, .denominator = %u }, " 152 ".extendedmode = %u, " 153 ".writebuffers = %u, " 154 "reserved[] = { 0x%X, 0x%X, 0x%X, 0x%X }}}\n", 155 __FILE__, __LINE__, 156 parm.type, 157 parm.parm.output.capability, 158 parm.parm.output.outputmode, 159 parm.parm.output.timeperframe.numerator, 160 parm.parm.output.timeperframe.denominator, 161 parm.parm.output.extendedmode, 162 parm.parm.output.writebuffers, 163 parm.parm.output.reserved[0], 164 parm.parm.output.reserved[1], 165 parm.parm.output.reserved[2], 166 parm.parm.output.reserved[3] 167 ); 168 169 CU_ASSERT(valid_v4l2_outputparm_capability 170 (parm.parm.output.capability)); 171 CU_ASSERT(valid_v4l2_outputparm_outputpmode 172 (parm.parm.output.outputmode)); 173 174 if (parm.parm.output.capability & V4L2_CAP_TIMEPERFRAME) { 175 //CU_ASSERT_EQUAL(parm.parm.output.timeperframe.numerator, ???); 176 //CU_ASSERT_EQUAL(parm.parm.output.timeperframe.denominator, ???); 177 CU_ASSERT(parm.parm.output.timeperframe. 178 denominator != 0); 179 // TODO: timerperframe: check struct v4l2_standard frameperiod field 180 } else { 181 //CU_ASSERT_EQUAL(parm.parm.output.timeperframe.numerator, 0); 182 //CU_ASSERT_EQUAL(parm.parm.output.timeperframe.denominator, 0); 183 CU_ASSERT(parm.parm.output.timeperframe. 184 denominator != 0); 185 } 186 187 //CU_ASSERT_EQUAL(parm.parm.output.extendedmode, ???); 188 //CU_ASSERT_EQUAL(parm.parm.output.writebuffers, ???); 189 190 CU_ASSERT_EQUAL(parm.parm.output.reserved[0], 0); 191 CU_ASSERT_EQUAL(parm.parm.output.reserved[1], 0); 192 CU_ASSERT_EQUAL(parm.parm.output.reserved[2], 0); 193 CU_ASSERT_EQUAL(parm.parm.output.reserved[3], 0); 194 break; 195 default: 196 ; 197 } 198 199 } else { 200 CU_ASSERT_EQUAL(ret_get, -1); 201 CU_ASSERT_EQUAL(errno_get, EINVAL); 202 203 /* check whether the parm structure is untouched */ 204 memset(&parm2, 0xff, sizeof(parm2)); 205 parm2.type = type; 206 207 CU_ASSERT_EQUAL(memcmp(&parm, &parm2, sizeof(parm)), 0); 208 209 } 210 211 } 212 213 void test_VIDIOC_G_PARM() 214 { 215 do_get_param(V4L2_BUF_TYPE_VIDEO_CAPTURE); 216 do_get_param(V4L2_BUF_TYPE_VIDEO_OUTPUT); 217 do_get_param(V4L2_BUF_TYPE_PRIVATE); 218 } 219 220 static void do_get_param_invalid(enum v4l2_buf_type type) 221 { 222 int ret_get, errno_get; 223 struct v4l2_streamparm parm; 224 struct v4l2_streamparm parm2; 225 226 memset(&parm, 0xff, sizeof(parm)); 227 parm.type = type; 228 ret_get = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm); 229 errno_get = errno; 230 231 dprintf("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_get=%i, errno_get=%i\n", 232 __FILE__, __LINE__, type, ret_get, errno_get); 233 234 CU_ASSERT_EQUAL(ret_get, -1); 235 CU_ASSERT_EQUAL(errno_get, EINVAL); 236 237 /* check whether the parm structure is untouched */ 238 memset(&parm2, 0xff, sizeof(parm2)); 239 parm2.type = type; 240 241 CU_ASSERT_EQUAL(memcmp(&parm, &parm2, sizeof(parm)), 0); 242 } 243 244 void test_VIDIOC_G_PARM_invalid() 245 { 246 do_get_param_invalid(S32_MIN); 247 248 /* check if 0x80000001 is not treated as 1 (V4L2_BUF_TYPE_VIDEO_CAPTURE) */ 249 do_get_param_invalid(S32_MIN + 1); 250 251 /* check if 0x80000002 is not treated as 2 (V4L2_BUF_TYPE_VIDEO_OUTPUT) */ 252 do_get_param_invalid(S32_MIN + 2); 253 254 do_get_param_invalid(S16_MIN); 255 do_get_param_invalid(0); 256 do_get_param_invalid(V4L2_BUF_TYPE_VIDEO_OVERLAY); 257 do_get_param_invalid(V4L2_BUF_TYPE_VBI_CAPTURE); 258 do_get_param_invalid(V4L2_BUF_TYPE_VBI_OUTPUT); 259 do_get_param_invalid(V4L2_BUF_TYPE_SLICED_VBI_CAPTURE); 260 do_get_param_invalid(V4L2_BUF_TYPE_SLICED_VBI_OUTPUT); 261 do_get_param_invalid(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY); 262 do_get_param_invalid(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY + 1); 263 do_get_param_invalid(V4L2_BUF_TYPE_PRIVATE - 1); 264 do_get_param_invalid(S16_MAX); 265 do_get_param_invalid(S32_MAX); 266 } 267 268 void test_VIDIOC_G_PARM_NULL() 269 { 270 int ret_capture, errno_capture; 271 int ret_output, errno_output; 272 int ret_private, errno_private; 273 int ret_null, errno_null; 274 enum v4l2_buf_type type; 275 struct v4l2_streamparm parm; 276 277 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 278 memset(&parm, 0, sizeof(parm)); 279 parm.type = type; 280 ret_capture = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm); 281 errno_capture = errno; 282 dprintf 283 ("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_capture=%i, errno_capture=%i\n", 284 __FILE__, __LINE__, type, ret_capture, errno_capture); 285 286 type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 287 memset(&parm, 0, sizeof(parm)); 288 parm.type = type; 289 ret_output = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm); 290 errno_output = errno; 291 dprintf 292 ("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_output=%i, errno_output=%i\n", 293 __FILE__, __LINE__, type, ret_output, errno_output); 294 295 type = V4L2_BUF_TYPE_PRIVATE; 296 memset(&parm, 0, sizeof(parm)); 297 parm.type = type; 298 ret_private = ioctl(get_video_fd(), VIDIOC_G_PARM, &parm); 299 errno_private = errno; 300 dprintf 301 ("\t%s:%u: VIDIOC_G_PARM, type=%i, ret_private=%i, errno_private=%i\n", 302 __FILE__, __LINE__, type, ret_private, errno_private); 303 304 ret_null = ioctl(get_video_fd(), VIDIOC_G_PARM, NULL); 305 errno_null = errno; 306 dprintf("\t%s:%u: VIDIOC_G_PARM, ret_null=%i, errno_null=%i\n", 307 __FILE__, __LINE__, ret_null, errno_null); 308 309 if (ret_capture == 0 || ret_output == 0 || ret_private == 0) { 310 /* if at least one type is supported, then the 311 * parameter shall be tested and the result shall be EFAULT 312 */ 313 CU_ASSERT_EQUAL(ret_null, -1); 314 CU_ASSERT_EQUAL(errno_null, EFAULT); 315 } else { 316 CU_ASSERT_EQUAL(ret_capture, -1); 317 CU_ASSERT_EQUAL(errno_capture, EINVAL); 318 CU_ASSERT_EQUAL(ret_output, -1); 319 CU_ASSERT_EQUAL(errno_output, EINVAL); 320 CU_ASSERT_EQUAL(ret_private, -1); 321 CU_ASSERT_EQUAL(errno_private, EINVAL); 322 CU_ASSERT_EQUAL(ret_null, -1); 323 CU_ASSERT_EQUAL(errno_null, EINVAL); 324 } 325 326 } 327 328 /* TODO: test cases for VIDIOC_S_PARM */ 329