Commit 8853c752 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

v4l2: fix step-wise and continuous frame sizes enumeration

Width and height are independent for step-wise frame sizes (yes,
enumerating is slow). Continuous frame sizes are step-size with one
pixel steps for both dimensions (yes, enumerationg is very slow).

A few device drivers use either of those two types, though the discrete
type is much more common.
parent b79c09ce
...@@ -235,7 +235,7 @@ static float GetMaxFPS( vlc_object_t *obj, int fd, uint32_t pixel_format, ...@@ -235,7 +235,7 @@ static float GetMaxFPS( vlc_object_t *obj, int fd, uint32_t pixel_format,
/ (float)fie.discrete.numerator; / (float)fie.discrete.numerator;
if( fps > max ) if( fps > max )
max = fps; max = fps;
msg_Dbg( obj, " discrete frame interval %"PRIu32"/%"PRIu32 msg_Dbg( obj, " discrete frame interval %"PRIu32"/%"PRIu32
" supported", " supported",
fie.discrete.numerator, fie.discrete.denominator ); fie.discrete.numerator, fie.discrete.denominator );
fie.index++; fie.index++;
...@@ -245,7 +245,7 @@ static float GetMaxFPS( vlc_object_t *obj, int fd, uint32_t pixel_format, ...@@ -245,7 +245,7 @@ static float GetMaxFPS( vlc_object_t *obj, int fd, uint32_t pixel_format,
case V4L2_FRMIVAL_TYPE_STEPWISE: case V4L2_FRMIVAL_TYPE_STEPWISE:
case V4L2_FRMIVAL_TYPE_CONTINUOUS: case V4L2_FRMIVAL_TYPE_CONTINUOUS:
msg_Dbg( obj, " frame intervals from %"PRIu32"/%"PRIu32 msg_Dbg( obj, " frame intervals from %"PRIu32"/%"PRIu32
"to %"PRIu32"/%"PRIu32" supported", "to %"PRIu32"/%"PRIu32" supported",
fie.stepwise.min.numerator, fie.stepwise.min.denominator, fie.stepwise.min.numerator, fie.stepwise.min.denominator,
fie.stepwise.max.numerator, fie.stepwise.max.denominator ); fie.stepwise.max.numerator, fie.stepwise.max.denominator );
...@@ -277,48 +277,39 @@ float GetAbsoluteMaxFrameRate( vlc_object_t *obj, int fd, ...@@ -277,48 +277,39 @@ float GetAbsoluteMaxFrameRate( vlc_object_t *obj, int fd,
float max = -1.; float max = -1.;
switch( fse.type ) switch( fse.type )
{ {
case V4L2_FRMSIZE_TYPE_DISCRETE: case V4L2_FRMSIZE_TYPE_DISCRETE:
do do
{ {
float fps = GetMaxFPS( obj, fd, pixel_format, float fps = GetMaxFPS( obj, fd, pixel_format,
fse.discrete.width, fse.discrete.height ); fse.discrete.width, fse.discrete.height );
if( fps > max ) if( fps > max )
max = fps; max = fps;
msg_Dbg( obj, " discrete size %"PRIu32"x%"PRIu32" supported", fse.index++;
fse.discrete.width, fse.discrete.height ); } while( v4l2_ioctl( fd, VIDIOC_ENUM_FRAMESIZES, &fse ) >= 0 );
fse.index++; break;
} while( v4l2_ioctl( fd, VIDIOC_ENUM_FRAMESIZES, &fse ) >= 0 );
break; case V4L2_FRMSIZE_TYPE_STEPWISE:
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
msg_Dbg( obj, " sizes from %"PRIu32"x%"PRIu32" "
"to %"PRIu32"x%"PRIu32" supported",
fse.stepwise.min_width, fse.stepwise.min_height,
fse.stepwise.max_width, fse.stepwise.max_height );
if( fse.type == V4L2_FRMSIZE_TYPE_STEPWISE )
msg_Dbg( obj, " with %"PRIu32"x%"PRIu32" steps",
fse.stepwise.step_width, fse.stepwise.step_height );
case V4L2_FRMSIZE_TYPE_STEPWISE: for( uint32_t width = fse.stepwise.min_width;
for( uint32_t width = fse.stepwise.min_width, width <= fse.stepwise.max_width;
height = fse.stepwise.min_height; width += fse.stepwise.step_width )
width <= fse.stepwise.max_width for( uint32_t height = fse.stepwise.min_height;
&& height <= fse.stepwise.max_width; height <= fse.stepwise.max_width;
width += fse.stepwise.step_width, height += fse.stepwise.step_height )
height += fse.stepwise.step_height )
{ {
float fps = GetMaxFPS( obj, fd, pixel_format, width, height ); float fps = GetMaxFPS( obj, fd, pixel_format, width, height );
if( fps > max ) if( fps > max )
max = fps; max = fps;
} }
msg_Dbg( obj, " sizes from %"PRIu32"x%"PRIu32" to %"PRIu32 break;
"x%"PRIu32" supported with %"PRIu32"x%"PRIu32" steps",
fse.stepwise.min_width, fse.stepwise.min_height,
fse.stepwise.max_width, fse.stepwise.max_height,
fse.stepwise.step_width, fse.stepwise.step_height );
break;
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
/* FIXME */
msg_Err( obj, "V4L2_FRMSIZE_TYPE_CONTINUOUS support incorrect" );
max = GetMaxFPS( obj, fd, pixel_format, fse.stepwise.max_width,
fse.stepwise.max_height );
msg_Dbg( obj, " sizes from %"PRIu32"x%"PRIu32" to %"PRIu32
"x%"PRIu32" all supported",
fse.stepwise.min_width, fse.stepwise.min_height,
fse.stepwise.max_width, fse.stepwise.max_height );
break;
} }
return max; return max;
#else #else
...@@ -343,27 +334,40 @@ void GetMaxDimensions( vlc_object_t *obj, int fd, uint32_t pixel_format, ...@@ -343,27 +334,40 @@ void GetMaxDimensions( vlc_object_t *obj, int fd, uint32_t pixel_format,
switch( fse.type ) switch( fse.type )
{ {
case V4L2_FRMSIZE_TYPE_DISCRETE: case V4L2_FRMSIZE_TYPE_DISCRETE:
do do
{
msg_Dbg( obj, " discrete size %"PRIu32"x%"PRIu32" supported",
fse.discrete.width, fse.discrete.height );
float fps = GetMaxFPS( obj, fd, pixel_format,
fse.discrete.width, fse.discrete.height );
if( fps >= fps_min && fse.discrete.width > *pwidth )
{ {
float fps = GetMaxFPS( obj, fd, pixel_format, *pwidth = fse.discrete.width;
fse.discrete.width, fse.discrete.height ); *pheight = fse.discrete.height;
if( fps >= fps_min && fse.discrete.width > *pwidth ) }
{ fse.index++;
*pwidth = fse.discrete.width; }
*pheight = fse.discrete.height; while( v4l2_ioctl( fd, VIDIOC_ENUM_FRAMESIZES, &fse ) >= 0 );
} break;
fse.index++;
} while( v4l2_ioctl( fd, VIDIOC_ENUM_FRAMESIZES, &fse ) >= 0 ); case V4L2_FRMSIZE_TYPE_STEPWISE:
break; case V4L2_FRMSIZE_TYPE_CONTINUOUS:
msg_Dbg( obj, " sizes from %"PRIu32"x%"PRIu32" "
"to %"PRIu32"x%"PRIu32" supported",
fse.stepwise.min_width, fse.stepwise.min_height,
fse.stepwise.max_width, fse.stepwise.max_height );
if( fse.type == V4L2_FRMSIZE_TYPE_STEPWISE )
msg_Dbg( obj, " with %"PRIu32"x%"PRIu32" steps",
fse.stepwise.step_width, fse.stepwise.step_height );
case V4L2_FRMSIZE_TYPE_STEPWISE: for( uint32_t width = fse.stepwise.min_width;
for( uint32_t width = fse.stepwise.min_width, width <= fse.stepwise.max_width;
height = fse.stepwise.min_height; width += fse.stepwise.step_width )
width <= fse.stepwise.max_width for( uint32_t height = fse.stepwise.min_height;
&& height <= fse.stepwise.max_width; height <= fse.stepwise.max_width;
width += fse.stepwise.step_width, height += fse.stepwise.step_height )
height += fse.stepwise.step_height )
{ {
float fps = GetMaxFPS( obj, fd, pixel_format, width, height ); float fps = GetMaxFPS( obj, fd, pixel_format, width, height );
if( fps >= fps_min && width > *pwidth ) if( fps >= fps_min && width > *pwidth )
...@@ -372,20 +376,7 @@ void GetMaxDimensions( vlc_object_t *obj, int fd, uint32_t pixel_format, ...@@ -372,20 +376,7 @@ void GetMaxDimensions( vlc_object_t *obj, int fd, uint32_t pixel_format,
*pheight = height; *pheight = height;
} }
} }
break; break;
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
{
float fps = GetMaxFPS( obj, fd, pixel_format,
fse.stepwise.max_width, fse.stepwise.max_height );
msg_Err( obj, "V4L2_FRMSIZE_TYPE_CONTINUOUS support incorrect" );
if( fps >= fps_min && fse.stepwise.max_width > *pwidth )
{
*pwidth = fse.stepwise.max_width;
*pheight = fse.stepwise.max_height;
}
break;
}
} }
#endif #endif
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment