Home | History | Annotate | Download | only in user_space
      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