This is a bug in the v4l "version" (build) of OpenCV 2.4 (including 2.4.12), but the bug is not in the libv4l version. For OpenCV 3.1.0, neither the v4l nor the libv4l version has the bug.
(Your error error message HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP
indicates that you have the v4l version; the message is in cap_v4l.cpp, see code, but not in cap_libv4l.cpp.)
A workaround to get the v4l version of OpenCV 2.4 to work at a fixed resolution other than 640x480 is
changing the values for DEFAULT_V4L_WIDTH
and DEFAULT_V4L_HEIGHT
in
modules/highgui/src/cap_v4l.cpp and re-building OpenCV, kudos to this
answer.
If you want to build the libv4l version instead, all you likely need to do is
install libv4l-dev
and rebuild OpenCV; WITH_LIBV4L
was enabled by default for me. If it is not, your cmake command should contain
-D WITH_LIBV4L=ON
The cmake output (or version_string.tmp) for a libv4l build contains something like
Video I/O:
...
V4L/V4L2: Using libv4l1 (ver 0.8.6) / libv4l2 (ver 0.8.6)
(For a v4l build, it is just V4L/V4L2: NO/YES
.)