Home | History | Annotate | Download | only in user_space
      1 /*
      2  * v4l-test: Test environment for Video For Linux Two API
      3  *
      4  *  3 Apr 2009  0.4  Minor style cleanup
      5  *  7 Mar 2009  0.3  Test cases added for VIDIOC_S_CROP
      6  * 13 Feb 2009  0.2  Test cases added for VIDIOC_G_CROP
      7  *  7 Feb 2009  0.1  First release
      8  *
      9  * Written by Mrton Nmeth <nm127 (at) freemail.hu>
     10  * Released under GPL
     11  */
     12 
     13 #include <sys/ioctl.h>
     14 #include <errno.h>
     15 #include <string.h>
     16 
     17 #include <linux/videodev2.h>
     18 #include <linux/errno.h>
     19 
     20 #include <CUnit/CUnit.h>
     21 
     22 #include "v4l2_test.h"
     23 #include "dev_video.h"
     24 #include "video_limits.h"
     25 
     26 #include "test_VIDIOC_CROP.h"
     27 
     28 void do_get_crop(enum v4l2_buf_type type)
     29 {
     30 	int ret1, errno1;
     31 	struct v4l2_crop crop;
     32 
     33 	memset(&crop, 0xff, sizeof(crop));
     34 	crop.type = type;
     35 	ret1 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
     36 	errno1 = errno;
     37 
     38 	dprintf("\tVIDIOC_G_CROP: type=%i, ret1=%i, errno1=%i\n",
     39 		type, ret1, errno1);
     40 
     41 	if (ret1 == 0) {
     42 		CU_ASSERT_EQUAL(ret1, 0);
     43 
     44 	} else {
     45 		CU_ASSERT_EQUAL(ret1, -1);
     46 		CU_ASSERT_EQUAL(errno1, EINVAL);
     47 	}
     48 
     49 }
     50 
     51 void test_VIDIOC_G_CROP()
     52 {
     53 	do_get_crop(V4L2_BUF_TYPE_VIDEO_CAPTURE);
     54 	do_get_crop(V4L2_BUF_TYPE_VIDEO_OUTPUT);
     55 	do_get_crop(V4L2_BUF_TYPE_VIDEO_OVERLAY);
     56 }
     57 
     58 void do_get_crop_invalid(enum v4l2_buf_type type)
     59 {
     60 	int ret1, errno1;
     61 	struct v4l2_crop crop;
     62 
     63 	memset(&crop, 0xff, sizeof(crop));
     64 	crop.type = type;
     65 	ret1 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
     66 	errno1 = errno;
     67 
     68 	dprintf("\tVIDIOC_G_CROP: type=%i, ret1=%i, errno1=%i\n",
     69 		type, ret1, errno1);
     70 
     71 	CU_ASSERT_EQUAL(ret1, -1);
     72 	CU_ASSERT_EQUAL(errno1, EINVAL);
     73 }
     74 
     75 void test_VIDIOC_G_CROP_invalid()
     76 {
     77 	do_get_crop_invalid(0);
     78 	do_get_crop_invalid(V4L2_BUF_TYPE_VBI_CAPTURE);
     79 	do_get_crop_invalid(V4L2_BUF_TYPE_VBI_OUTPUT);
     80 	do_get_crop_invalid(V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
     81 	do_get_crop_invalid(V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
     82 	do_get_crop_invalid(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
     83 	do_get_crop_invalid(V4L2_BUF_TYPE_PRIVATE);
     84 	do_get_crop_invalid(S32_MAX);
     85 	do_get_crop_invalid(((__u32) S32_MAX) + 1);
     86 	do_get_crop_invalid(U32_MAX);
     87 }
     88 
     89 void test_VIDIOC_G_CROP_NULL()
     90 {
     91 	int ret_get1, errno_get1;
     92 	int ret_get2, errno_get2;
     93 	int ret_get3, errno_get3;
     94 	int ret_null, errno_null;
     95 	struct v4l2_crop crop;
     96 
     97 	memset(&crop, 0, sizeof(crop));
     98 	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     99 
    100 	ret_get1 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
    101 	errno_get1 = errno;
    102 
    103 	dprintf("\t%s:%u: VIDIOC_G_CROP ret_get1=%i, errno_get1=%i\n",
    104 		__FILE__, __LINE__, ret_get1, errno_get1);
    105 
    106 	memset(&crop, 0, sizeof(crop));
    107 	crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    108 
    109 	ret_get2 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
    110 	errno_get2 = errno;
    111 
    112 	dprintf("\t%s:%u: VIDIOC_G_CROP ret_get2=%i, errno_get2=%i\n",
    113 		__FILE__, __LINE__, ret_get2, errno_get2);
    114 
    115 	memset(&crop, 0, sizeof(crop));
    116 	crop.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    117 
    118 	ret_get3 = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop);
    119 	errno_get3 = errno;
    120 
    121 	dprintf("\t%s:%u: VIDIOC_G_CROP ret_get3=%i, errno_get3=%i\n",
    122 		__FILE__, __LINE__, ret_get3, errno_get3);
    123 
    124 	ret_null = ioctl(get_video_fd(), VIDIOC_G_CROP, NULL);
    125 	errno_null = errno;
    126 
    127 	dprintf("\t%s:%u: VIDIOC_G_CROP ret_null=%i, errno_null=%i\n",
    128 		__FILE__, __LINE__, ret_null, errno_null);
    129 
    130 	if (ret_get1 == 0 || ret_get2 == 0 || ret_get3 == 0) {
    131 		CU_ASSERT_EQUAL(ret_null, -1);
    132 		CU_ASSERT_EQUAL(errno_null, EFAULT);
    133 
    134 	} else {
    135 		CU_ASSERT_EQUAL(ret_get1, -1);
    136 		CU_ASSERT_EQUAL(errno_get1, EINVAL);
    137 		CU_ASSERT_EQUAL(ret_get2, -1);
    138 		CU_ASSERT_EQUAL(errno_get2, EINVAL);
    139 		CU_ASSERT_EQUAL(ret_get3, -1);
    140 		CU_ASSERT_EQUAL(errno_get3, EINVAL);
    141 		CU_ASSERT_EQUAL(ret_null, -1);
    142 		CU_ASSERT_EQUAL(errno_null, EINVAL);
    143 
    144 	}
    145 
    146 }
    147 
    148 void do_set_crop(enum v4l2_buf_type type)
    149 {
    150 	int ret_orig, errno_orig;
    151 	int ret_set, errno_set;
    152 	int ret_new, errno_new;
    153 	int ret_cap, errno_cap;
    154 	struct v4l2_crop crop_orig;
    155 	struct v4l2_crop crop;
    156 	struct v4l2_crop crop_new;
    157 	struct v4l2_cropcap cropcap;
    158 	__s32 i;
    159 
    160 	memset(&crop_orig, 0, sizeof(crop_orig));
    161 	crop_orig.type = type;
    162 	ret_orig = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_orig);
    163 	errno_orig = errno;
    164 	dprintf("\t%s:%u: VIDIOC_G_CROP, ret_orig=%i, errno_orig=%i, "
    165 		"crop_orig = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    166 		__FILE__, __LINE__,
    167 		ret_orig, errno_orig,
    168 		crop_orig.type,
    169 		crop_orig.c.left,
    170 		crop_orig.c.top, crop_orig.c.width, crop_orig.c.height);
    171 
    172 	memset(&cropcap, 0, sizeof(cropcap));
    173 	cropcap.type = type;
    174 	ret_cap = ioctl(get_video_fd(), VIDIOC_CROPCAP, &cropcap);
    175 	errno_cap = errno;
    176 
    177 	dprintf
    178 	    ("\t%s:%u: VIDIOC_CROPCAP, ret_cap=%i, errno_cap=%i, cropcap = { .type = %i, "
    179 	     ".bounds = { .left = %i, .top = %i, .width = %i, .height = %i }, "
    180 	     ".defrect = { .left = %i, .top = %i, .width = %i, .height = %i }, "
    181 	     ".pixelaspect = { .numerator = %u, .denominator = %u } " "}\n",
    182 	     __FILE__, __LINE__, ret_cap, errno_cap, cropcap.type,
    183 	     cropcap.bounds.left, cropcap.bounds.top, cropcap.bounds.width,
    184 	     cropcap.bounds.height, cropcap.defrect.left, cropcap.defrect.top,
    185 	     cropcap.defrect.width, cropcap.defrect.height,
    186 	     cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator);
    187 
    188 	memset(&crop, 0xff, sizeof(crop));
    189 	crop.type = type;
    190 	crop.c = cropcap.bounds;
    191 	ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop);
    192 	errno_set = errno;
    193 	dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i, "
    194 		"crop = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    195 		__FILE__, __LINE__,
    196 		ret_set, errno_set,
    197 		crop.type,
    198 		crop.c.left, crop.c.top, crop.c.width, crop.c.height);
    199 
    200 	memset(&crop_new, 0, sizeof(crop_new));
    201 	crop_new.type = type;
    202 	ret_new = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_new);
    203 	errno_new = errno;
    204 	dprintf("\t%s:%u: VIDIOC_G_CROP, ret_new=%i, errno_new=%i, "
    205 		"crop_new = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    206 		__FILE__, __LINE__,
    207 		ret_new, errno_new,
    208 		crop_new.type,
    209 		crop_new.c.left,
    210 		crop_new.c.top, crop_new.c.width, crop_new.c.height);
    211 
    212 	if (ret_cap == 0) {
    213 		CU_ASSERT_EQUAL(ret_cap, 0);
    214 		CU_ASSERT_EQUAL(ret_set, 0);
    215 		CU_ASSERT_EQUAL(ret_new, 0);
    216 
    217 		if (ret_cap == 0 && ret_new == 0) {
    218 
    219 			/*     |   left                                   x   */
    220 			/* ----+----+-------------------------------------->  */
    221 			/*     |    :                                         */
    222 			/* top +    +------ cropcap.bounds -------+  ^        */
    223 			/*     |    |                             |  |        */
    224 			/*     |    | +------- crop_new --------+ |  |        */
    225 			/*     |    | |                         | |  |        */
    226 			/*     |    | |                         | |  |        */
    227 			/*     |    | |                         | |  | height */
    228 			/*     |    | +-------------------------+ |  |        */
    229 			/*     |    |                             |  |        */
    230 			/*     |    |                             |  |        */
    231 			/*     |    +-----------------------------+  v        */
    232 			/*     |    :                             :           */
    233 			/*     |    <---------- width ------------>           */
    234 			/*     |                                              */
    235 			/*     v y                                            */
    236 
    237 			CU_ASSERT(cropcap.bounds.left <= crop_new.c.left);
    238 			CU_ASSERT(cropcap.bounds.top <= crop_new.c.top);
    239 
    240 			CU_ASSERT(crop_new.c.left + crop_new.c.width <=
    241 				  cropcap.bounds.left + cropcap.bounds.width);
    242 			CU_ASSERT(crop_new.c.top + crop_new.c.height <=
    243 				  cropcap.bounds.top + cropcap.bounds.height);
    244 		}
    245 
    246 	} else {
    247 		CU_ASSERT_EQUAL(ret_cap, -1);
    248 		CU_ASSERT_EQUAL(errno_cap, EINVAL);
    249 		CU_ASSERT_EQUAL(ret_set, -1);
    250 		CU_ASSERT_EQUAL(errno_set, EINVAL);
    251 		CU_ASSERT_EQUAL(ret_new, -1);
    252 		CU_ASSERT_EQUAL(errno_new, EINVAL);
    253 
    254 	}
    255 
    256 	memset(&crop, 0xff, sizeof(crop));
    257 	crop.type = type;
    258 	crop.c = cropcap.defrect;
    259 	ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop);
    260 	errno_set = errno;
    261 	dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i, "
    262 		"crop = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    263 		__FILE__, __LINE__,
    264 		ret_set, errno_set,
    265 		crop.type,
    266 		crop.c.left, crop.c.top, crop.c.width, crop.c.height);
    267 
    268 	memset(&crop_new, 0, sizeof(crop_new));
    269 	crop_new.type = type;
    270 	ret_new = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_new);
    271 	errno_new = errno;
    272 	dprintf("\t%s:%u: VIDIOC_G_CROP, ret_new=%i, errno_new=%i, "
    273 		"crop_new = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    274 		__FILE__, __LINE__,
    275 		ret_new, errno_new,
    276 		crop_new.type,
    277 		crop_new.c.left,
    278 		crop_new.c.top, crop_new.c.width, crop_new.c.height);
    279 
    280 	if (ret_cap == 0) {
    281 		CU_ASSERT_EQUAL(ret_cap, 0);
    282 		CU_ASSERT_EQUAL(ret_set, 0);
    283 		CU_ASSERT_EQUAL(ret_new, 0);
    284 
    285 		if (ret_cap == 0 && ret_new == 0) {
    286 
    287 			/*     |   left                                   x   */
    288 			/* ----+----+-------------------------------------->  */
    289 			/*     |    :                                         */
    290 			/* top +    +------ cropcap.defrect ------+  ^        */
    291 			/*     |    |                             |  |        */
    292 			/*     |    | +------- crop_new --------+ |  |        */
    293 			/*     |    | |                         | |  |        */
    294 			/*     |    | |                         | |  |        */
    295 			/*     |    | |                         | |  | height */
    296 			/*     |    | +-------------------------+ |  |        */
    297 			/*     |    |                             |  |        */
    298 			/*     |    |                             |  |        */
    299 			/*     |    +-----------------------------+  v        */
    300 			/*     |    :                             :           */
    301 			/*     |    <---------- width ------------>           */
    302 			/*     |                                              */
    303 			/*     v y                                            */
    304 
    305 			CU_ASSERT(cropcap.defrect.left <= crop_new.c.left);
    306 			CU_ASSERT(cropcap.defrect.top <= crop_new.c.top);
    307 
    308 			CU_ASSERT(crop_new.c.left + crop_new.c.width <=
    309 				  cropcap.defrect.left + cropcap.defrect.width);
    310 			CU_ASSERT(crop_new.c.top + crop_new.c.height <=
    311 				  cropcap.defrect.top + cropcap.defrect.height);
    312 		}
    313 
    314 	} else {
    315 		CU_ASSERT_EQUAL(ret_cap, -1);
    316 		CU_ASSERT_EQUAL(errno_cap, EINVAL);
    317 		CU_ASSERT_EQUAL(ret_set, -1);
    318 		CU_ASSERT_EQUAL(errno_set, EINVAL);
    319 		CU_ASSERT_EQUAL(ret_new, -1);
    320 		CU_ASSERT_EQUAL(errno_new, EINVAL);
    321 
    322 	}
    323 
    324 	/*     |   left                                   x   */
    325 	/* ----+----+-------------------------------------->  */
    326 	/*     |    :                                         */
    327 	/* top +    +-------- crop.c -------------+  ^        */
    328 	/*     |    |                       :     |  |        */
    329 	/*     |    |                       :     |  |        */
    330 	/*     |    |                       :     |  |        */
    331 	/*     |    |                       :<----|  |        */
    332 	/*     |    |                       :     |  | height */
    333 	/*     |    |                       :     |  |        */
    334 	/*     |    |                       :     |  |        */
    335 	/*     |    |                       :     |  |        */
    336 	/*     |    +-----------------------------+  v        */
    337 	/*     |    :                             :           */
    338 	/*     |    <---------- width ------------>           */
    339 	/*     |                                              */
    340 	/*     v y                                            */
    341 	for (i = 0; i < cropcap.bounds.width; i++) {
    342 		memset(&crop, 0xff, sizeof(crop));
    343 		crop.type = type;
    344 		crop.c.left = cropcap.bounds.left;
    345 		crop.c.top = cropcap.bounds.top;
    346 		crop.c.width = cropcap.bounds.width - i;
    347 		crop.c.height = cropcap.bounds.height;
    348 		ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop);
    349 		errno_set = errno;
    350 		dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i, "
    351 			"crop = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    352 			__FILE__, __LINE__,
    353 			ret_set, errno_set,
    354 			crop.type,
    355 			crop.c.left, crop.c.top, crop.c.width, crop.c.height);
    356 
    357 		memset(&crop_new, 0, sizeof(crop_new));
    358 		crop_new.type = type;
    359 		ret_new = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_new);
    360 		errno_new = errno;
    361 		dprintf("\t%s:%u: VIDIOC_G_CROP, ret_new=%i, errno_new=%i, "
    362 			"crop_new = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    363 			__FILE__, __LINE__,
    364 			ret_new, errno_new,
    365 			crop_new.type,
    366 			crop_new.c.left,
    367 			crop_new.c.top, crop_new.c.width, crop_new.c.height);
    368 
    369 		if (ret_cap == 0) {
    370 			CU_ASSERT_EQUAL(ret_cap, 0);
    371 			CU_ASSERT_EQUAL(ret_set, 0);
    372 			CU_ASSERT_EQUAL(ret_new, 0);
    373 
    374 			if (ret_cap == 0 && ret_new == 0) {
    375 
    376 				CU_ASSERT(cropcap.defrect.left <=
    377 					  crop_new.c.left);
    378 				CU_ASSERT(cropcap.defrect.top <=
    379 					  crop_new.c.top);
    380 
    381 				CU_ASSERT(crop_new.c.left + crop_new.c.width <=
    382 					  cropcap.defrect.left +
    383 					  cropcap.defrect.width);
    384 				CU_ASSERT(crop_new.c.top + crop_new.c.height <=
    385 					  cropcap.defrect.top +
    386 					  cropcap.defrect.height);
    387 			}
    388 
    389 		} else {
    390 			CU_ASSERT_EQUAL(ret_cap, -1);
    391 			CU_ASSERT_EQUAL(errno_cap, EINVAL);
    392 			CU_ASSERT_EQUAL(ret_set, -1);
    393 			CU_ASSERT_EQUAL(errno_set, EINVAL);
    394 			CU_ASSERT_EQUAL(ret_new, -1);
    395 			CU_ASSERT_EQUAL(errno_new, EINVAL);
    396 		}
    397 	}
    398 
    399 	/*     |   left                                   x   */
    400 	/* ----+----+-------------------------------------->  */
    401 	/*     |    :                                         */
    402 	/* top +    +---------- crop.c -----------+  ^        */
    403 	/*     |    |                             |  |        */
    404 	/*     |    |                             |  |        */
    405 	/*     |    |                             |  |        */
    406 	/*     |    |                             |  |        */
    407 	/*     |    |.............................|  | height */
    408 	/*     |    |             ^               |  |        */
    409 	/*     |    |             |               |  |        */
    410 	/*     |    |             |               |  |        */
    411 	/*     |    +-----------------------------+  v        */
    412 	/*     |    :                             :           */
    413 	/*     |    <---------- width ------------>           */
    414 	/*     |                                              */
    415 	/*     v y                                            */
    416 	for (i = 0; i < cropcap.bounds.height; i++) {
    417 		memset(&crop, 0xff, sizeof(crop));
    418 		crop.type = type;
    419 		crop.c.left = cropcap.bounds.left;
    420 		crop.c.top = cropcap.bounds.top;
    421 		crop.c.width = cropcap.bounds.width;
    422 		crop.c.height = cropcap.bounds.height - i;
    423 		ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop);
    424 		errno_set = errno;
    425 		dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i, "
    426 			"crop = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    427 			__FILE__, __LINE__,
    428 			ret_set, errno_set,
    429 			crop.type,
    430 			crop.c.left, crop.c.top, crop.c.width, crop.c.height);
    431 
    432 		memset(&crop_new, 0, sizeof(crop_new));
    433 		crop_new.type = type;
    434 		ret_new = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_new);
    435 		errno_new = errno;
    436 		dprintf("\t%s:%u: VIDIOC_G_CROP, ret_new=%i, errno_new=%i, "
    437 			"crop_new = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    438 			__FILE__, __LINE__,
    439 			ret_new, errno_new,
    440 			crop_new.type,
    441 			crop_new.c.left,
    442 			crop_new.c.top, crop_new.c.width, crop_new.c.height);
    443 
    444 		if (ret_cap == 0) {
    445 			CU_ASSERT_EQUAL(ret_cap, 0);
    446 			CU_ASSERT_EQUAL(ret_set, 0);
    447 			CU_ASSERT_EQUAL(ret_new, 0);
    448 
    449 			if (ret_cap == 0 && ret_new == 0) {
    450 
    451 				CU_ASSERT(cropcap.defrect.left <=
    452 					  crop_new.c.left);
    453 				CU_ASSERT(cropcap.defrect.top <=
    454 					  crop_new.c.top);
    455 
    456 				CU_ASSERT(crop_new.c.left + crop_new.c.width <=
    457 					  cropcap.defrect.left +
    458 					  cropcap.defrect.width);
    459 				CU_ASSERT(crop_new.c.top + crop_new.c.height <=
    460 					  cropcap.defrect.top +
    461 					  cropcap.defrect.height);
    462 			}
    463 
    464 		} else {
    465 			CU_ASSERT_EQUAL(ret_cap, -1);
    466 			CU_ASSERT_EQUAL(errno_cap, EINVAL);
    467 			CU_ASSERT_EQUAL(ret_set, -1);
    468 			CU_ASSERT_EQUAL(errno_set, EINVAL);
    469 			CU_ASSERT_EQUAL(ret_new, -1);
    470 			CU_ASSERT_EQUAL(errno_new, EINVAL);
    471 		}
    472 	}
    473 
    474 	/*     |   left                                   x   */
    475 	/* ----+----+-------------------------------------->  */
    476 	/*     |    :                                         */
    477 	/* top +    +---------- crop.c -----------+  ^        */
    478 	/*     |    |    :                        |  |        */
    479 	/*     |    |    :                        |  |        */
    480 	/*     |    |    :                        |  |        */
    481 	/*     |    |--->:                        |  |        */
    482 	/*     |    |    :                        |  | height */
    483 	/*     |    |    :                        |  |        */
    484 	/*     |    |    :                        |  |        */
    485 	/*     |    |    :                        |  |        */
    486 	/*     |    +-----------------------------+  v        */
    487 	/*     |    :                             :           */
    488 	/*     |    <---------- width ------------>           */
    489 	/*     |                                              */
    490 	/*     v y                                            */
    491 	for (i = 0; i < cropcap.bounds.width; i++) {
    492 		memset(&crop, 0xff, sizeof(crop));
    493 		crop.type = type;
    494 		crop.c.left = cropcap.bounds.left + i;
    495 		crop.c.top = cropcap.bounds.top;
    496 		crop.c.width = cropcap.bounds.width - i;
    497 		crop.c.height = cropcap.bounds.height;
    498 		ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop);
    499 		errno_set = errno;
    500 		dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i, "
    501 			"crop = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    502 			__FILE__, __LINE__,
    503 			ret_set, errno_set,
    504 			crop.type,
    505 			crop.c.left, crop.c.top, crop.c.width, crop.c.height);
    506 
    507 		memset(&crop_new, 0, sizeof(crop_new));
    508 		crop_new.type = type;
    509 		ret_new = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_new);
    510 		errno_new = errno;
    511 		dprintf("\t%s:%u: VIDIOC_G_CROP, ret_new=%i, errno_new=%i, "
    512 			"crop_new = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    513 			__FILE__, __LINE__,
    514 			ret_new, errno_new,
    515 			crop_new.type,
    516 			crop_new.c.left,
    517 			crop_new.c.top, crop_new.c.width, crop_new.c.height);
    518 
    519 		if (ret_cap == 0) {
    520 			CU_ASSERT_EQUAL(ret_cap, 0);
    521 			CU_ASSERT_EQUAL(ret_set, 0);
    522 			CU_ASSERT_EQUAL(ret_new, 0);
    523 
    524 			if (ret_cap == 0 && ret_new == 0) {
    525 
    526 				CU_ASSERT(cropcap.defrect.left <=
    527 					  crop_new.c.left);
    528 				CU_ASSERT(cropcap.defrect.top <=
    529 					  crop_new.c.top);
    530 
    531 				CU_ASSERT(crop_new.c.left + crop_new.c.width <=
    532 					  cropcap.defrect.left +
    533 					  cropcap.defrect.width);
    534 				CU_ASSERT(crop_new.c.top + crop_new.c.height <=
    535 					  cropcap.defrect.top +
    536 					  cropcap.defrect.height);
    537 			}
    538 
    539 		} else {
    540 			CU_ASSERT_EQUAL(ret_cap, -1);
    541 			CU_ASSERT_EQUAL(errno_cap, EINVAL);
    542 			CU_ASSERT_EQUAL(ret_set, -1);
    543 			CU_ASSERT_EQUAL(errno_set, EINVAL);
    544 			CU_ASSERT_EQUAL(ret_new, -1);
    545 			CU_ASSERT_EQUAL(errno_new, EINVAL);
    546 		}
    547 	}
    548 
    549 	/*     |   left                                   x   */
    550 	/* ----+----+-------------------------------------->  */
    551 	/*     |    :                                         */
    552 	/* top +    +---------- crop.c -----------+  ^        */
    553 	/*     |    |         |                   |  |        */
    554 	/*     |    |         |                   |  |        */
    555 	/*     |    |         v                   |  |        */
    556 	/*     |    |.............................|  |        */
    557 	/*     |    |                             |  | height */
    558 	/*     |    |                             |  |        */
    559 	/*     |    |                             |  |        */
    560 	/*     |    |                             |  |        */
    561 	/*     |    +-----------------------------+  v        */
    562 	/*     |    :                             :           */
    563 	/*     |    <---------- width ------------>           */
    564 	/*     |                                              */
    565 	/*     v y                                            */
    566 	for (i = 0; i < cropcap.bounds.height; i++) {
    567 		memset(&crop, 0xff, sizeof(crop));
    568 		crop.type = type;
    569 		crop.c.left = cropcap.bounds.left;
    570 		crop.c.top = cropcap.bounds.top + i;
    571 		crop.c.width = cropcap.bounds.width;
    572 		crop.c.height = cropcap.bounds.height - i;
    573 		ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop);
    574 		errno_set = errno;
    575 		dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i, "
    576 			"crop = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    577 			__FILE__, __LINE__,
    578 			ret_set, errno_set,
    579 			crop.type,
    580 			crop.c.left, crop.c.top, crop.c.width, crop.c.height);
    581 
    582 		memset(&crop_new, 0, sizeof(crop_new));
    583 		crop_new.type = type;
    584 		ret_new = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_new);
    585 		errno_new = errno;
    586 		dprintf("\t%s:%u: VIDIOC_G_CROP, ret_new=%i, errno_new=%i, "
    587 			"crop_new = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    588 			__FILE__, __LINE__,
    589 			ret_new, errno_new,
    590 			crop_new.type,
    591 			crop_new.c.left,
    592 			crop_new.c.top, crop_new.c.width, crop_new.c.height);
    593 
    594 		if (ret_cap == 0) {
    595 			CU_ASSERT_EQUAL(ret_cap, 0);
    596 			CU_ASSERT_EQUAL(ret_set, 0);
    597 			CU_ASSERT_EQUAL(ret_new, 0);
    598 
    599 			if (ret_cap == 0 && ret_new == 0) {
    600 
    601 				CU_ASSERT(cropcap.defrect.left <=
    602 					  crop_new.c.left);
    603 				CU_ASSERT(cropcap.defrect.top <=
    604 					  crop_new.c.top);
    605 
    606 				CU_ASSERT(crop_new.c.left + crop_new.c.width <=
    607 					  cropcap.defrect.left +
    608 					  cropcap.defrect.width);
    609 				CU_ASSERT(crop_new.c.top + crop_new.c.height <=
    610 					  cropcap.defrect.top +
    611 					  cropcap.defrect.height);
    612 			}
    613 
    614 		} else {
    615 			CU_ASSERT_EQUAL(ret_cap, -1);
    616 			CU_ASSERT_EQUAL(errno_cap, EINVAL);
    617 			CU_ASSERT_EQUAL(ret_set, -1);
    618 			CU_ASSERT_EQUAL(errno_set, EINVAL);
    619 			CU_ASSERT_EQUAL(ret_new, -1);
    620 			CU_ASSERT_EQUAL(errno_new, EINVAL);
    621 		}
    622 	}
    623 
    624 	if (ret_orig == 0) {
    625 		/* it shall be possible to restore the original settings */
    626 		ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop_orig);
    627 		errno_set = errno;
    628 		dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i\n",
    629 			__FILE__, __LINE__, ret_set, errno_set);
    630 		CU_ASSERT_EQUAL(ret_set, 0);
    631 	}
    632 }
    633 
    634 void test_VIDIOC_S_CROP()
    635 {
    636 
    637 	do_set_crop(V4L2_BUF_TYPE_VIDEO_CAPTURE);
    638 	do_set_crop(V4L2_BUF_TYPE_VIDEO_OUTPUT);
    639 	do_set_crop(V4L2_BUF_TYPE_VIDEO_OVERLAY);
    640 	do_set_crop(V4L2_BUF_TYPE_PRIVATE);
    641 
    642 }
    643 
    644 void do_set_crop_invalid(enum v4l2_buf_type type)
    645 {
    646 	int ret_set, errno_set;
    647 	int ret_new, errno_new;
    648 	int ret_cap, errno_cap;
    649 	struct v4l2_crop crop;
    650 	struct v4l2_crop crop_new;
    651 	struct v4l2_cropcap cropcap;
    652 
    653 	memset(&cropcap, 0, sizeof(cropcap));
    654 	cropcap.type = type;
    655 	ret_cap = ioctl(get_video_fd(), VIDIOC_CROPCAP, &cropcap);
    656 	errno_cap = errno;
    657 
    658 	dprintf
    659 	    ("\t%s:%u: VIDIOC_CROPCAP, ret_cap=%i, errno_cap=%i, cropcap = { .type = %i, "
    660 	     ".bounds = { .left = %i, .top = %i, .width = %i, .height = %i }, "
    661 	     ".defrect = { .left = %i, .top = %i, .width = %i, .height = %i }, "
    662 	     ".pixelaspect = { .numerator = %u, .denominator = %u } " "}\n",
    663 	     __FILE__, __LINE__, ret_cap, errno_cap, cropcap.type,
    664 	     cropcap.bounds.left, cropcap.bounds.top, cropcap.bounds.width,
    665 	     cropcap.bounds.height, cropcap.defrect.left, cropcap.defrect.top,
    666 	     cropcap.defrect.width, cropcap.defrect.height,
    667 	     cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator);
    668 
    669 	memset(&crop, 0xff, sizeof(crop));
    670 	crop.type = type;
    671 	crop.c = cropcap.bounds;
    672 	ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop);
    673 	errno_set = errno;
    674 	dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i, "
    675 		"crop = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    676 		__FILE__, __LINE__,
    677 		ret_set, errno_set,
    678 		crop.type,
    679 		crop.c.left, crop.c.top, crop.c.width, crop.c.height);
    680 
    681 	memset(&crop_new, 0, sizeof(crop_new));
    682 	crop_new.type = type;
    683 	ret_new = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_new);
    684 	errno_new = errno;
    685 	dprintf("\t%s:%u: VIDIOC_G_CROP, ret_new=%i, errno_new=%i, "
    686 		"crop_new = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    687 		__FILE__, __LINE__,
    688 		ret_new, errno_new,
    689 		crop_new.type,
    690 		crop_new.c.left,
    691 		crop_new.c.top, crop_new.c.width, crop_new.c.height);
    692 
    693 	CU_ASSERT_EQUAL(ret_cap, -1);
    694 	CU_ASSERT_EQUAL(errno_cap, EINVAL);
    695 	CU_ASSERT_EQUAL(ret_set, -1);
    696 	CU_ASSERT_EQUAL(errno_set, EINVAL);
    697 	CU_ASSERT_EQUAL(ret_new, -1);
    698 	CU_ASSERT_EQUAL(errno_new, EINVAL);
    699 
    700 }
    701 
    702 void test_VIDIOC_S_CROP_invalid()
    703 {
    704 	do_set_crop_invalid(0);
    705 	do_set_crop_invalid(V4L2_BUF_TYPE_VBI_CAPTURE);
    706 	do_set_crop_invalid(V4L2_BUF_TYPE_VBI_OUTPUT);
    707 	do_set_crop_invalid(V4L2_BUF_TYPE_SLICED_VBI_CAPTURE);
    708 	do_set_crop_invalid(V4L2_BUF_TYPE_SLICED_VBI_OUTPUT);
    709 	do_set_crop_invalid(V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
    710 	do_set_crop_invalid(V4L2_BUF_TYPE_PRIVATE);
    711 	do_set_crop_invalid(S32_MAX);
    712 	do_set_crop_invalid(((__u32) S32_MAX) + 1);
    713 	do_set_crop_invalid(U32_MAX);
    714 }
    715 
    716 void do_set_crop_null(enum v4l2_buf_type type)
    717 {
    718 	int ret_orig, errno_orig;
    719 	int ret_set, errno_set;
    720 	int ret_cap, errno_cap;
    721 	int ret_null, errno_null;
    722 	struct v4l2_crop crop;
    723 	struct v4l2_crop crop_orig;
    724 	struct v4l2_cropcap cropcap;
    725 
    726 	memset(&crop_orig, 0, sizeof(crop_orig));
    727 	crop_orig.type = type;
    728 	ret_orig = ioctl(get_video_fd(), VIDIOC_G_CROP, &crop_orig);
    729 	errno_orig = errno;
    730 	dprintf("\t%s:%u: VIDIOC_G_CROP, ret_orig=%i, errno_orig=%i, "
    731 		"crop_orig = { .type=%i, .c={ .left=%i, .top=%i, .width=%i, .height=%i }}\n",
    732 		__FILE__, __LINE__,
    733 		ret_orig, errno_orig,
    734 		crop_orig.type,
    735 		crop_orig.c.left,
    736 		crop_orig.c.top, crop_orig.c.width, crop_orig.c.height);
    737 
    738 	memset(&cropcap, 0, sizeof(cropcap));
    739 	cropcap.type = type;
    740 	ret_cap = ioctl(get_video_fd(), VIDIOC_CROPCAP, &cropcap);
    741 	errno_cap = errno;
    742 
    743 	dprintf
    744 	    ("\t%s:%u: VIDIOC_CROPCAP, ret_cap=%i, errno_cap=%i, cropcap = { .type = %i, "
    745 	     ".bounds = { .left = %i, .top = %i, .width = %i, .height = %i }, "
    746 	     ".defrect = { .left = %i, .top = %i, .width = %i, .height = %i }, "
    747 	     ".pixelaspect = { .numerator = %u, .denominator = %u } " "}\n",
    748 	     __FILE__, __LINE__, ret_cap, errno_cap, cropcap.type,
    749 	     cropcap.bounds.left, cropcap.bounds.top, cropcap.bounds.width,
    750 	     cropcap.bounds.height, cropcap.defrect.left, cropcap.defrect.top,
    751 	     cropcap.defrect.width, cropcap.defrect.height,
    752 	     cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator);
    753 
    754 	memset(&crop, 0, sizeof(crop));
    755 	crop.type = type;
    756 	crop.c = cropcap.bounds;
    757 	ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop);
    758 	errno_set = errno;
    759 	dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i\n",
    760 		__FILE__, __LINE__, ret_set, errno_set);
    761 
    762 	ret_null = ioctl(get_video_fd(), VIDIOC_S_CROP, NULL);
    763 	errno_null = errno;
    764 	dprintf("\t%s:%u: VIDIOC_S_CROP, ret_null=%i, errno_null=%i\n",
    765 		__FILE__, __LINE__, ret_null, errno_null);
    766 
    767 	if (ret_set == 0) {
    768 		CU_ASSERT_EQUAL(ret_set, 0);
    769 		CU_ASSERT_EQUAL(ret_null, -1);
    770 		CU_ASSERT_EQUAL(errno_null, EFAULT);
    771 
    772 	} else {
    773 		CU_ASSERT_EQUAL(ret_set, -1);
    774 		CU_ASSERT_EQUAL(errno_set, EINVAL);
    775 		CU_ASSERT_EQUAL(ret_null, -1);
    776 		CU_ASSERT_EQUAL(errno_null, EINVAL);
    777 
    778 	}
    779 
    780 	if (ret_orig == 0) {
    781 		/* it shall be possible to restore the original settings */
    782 		ret_set = ioctl(get_video_fd(), VIDIOC_S_CROP, &crop_orig);
    783 		errno_set = errno;
    784 		dprintf("\t%s:%u: VIDIOC_S_CROP, ret_set=%i, errno_set=%i\n",
    785 			__FILE__, __LINE__, ret_set, errno_set);
    786 		CU_ASSERT_EQUAL(ret_set, 0);
    787 	}
    788 
    789 }
    790 
    791 void test_VIDIOC_S_CROP_NULL()
    792 {
    793 
    794 	do_set_crop_null(V4L2_BUF_TYPE_VIDEO_CAPTURE);
    795 	do_set_crop_null(V4L2_BUF_TYPE_VIDEO_OUTPUT);
    796 	do_set_crop_null(V4L2_BUF_TYPE_VIDEO_OVERLAY);
    797 	do_set_crop_null(V4L2_BUF_TYPE_PRIVATE);
    798 
    799 }
    800