Re: [PATCH v2] v4l2-compliance: Add test for V4L2_FMTDESC_FLAG_ENUM_ALL flag

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 31/07/2024 12:21, Benjamin Gaignard wrote:
> 
> Le 31/07/2024 à 12:02, Hans Verkuil a écrit :
>> On 31/07/2024 11:35, Benjamin Gaignard wrote:
>>> If V4L2_FMTDESC_FLAG_ENUM_ALL flag is supported, test if all
>>> pixel formats list with VIDIOC_ENUM_FMT without the flag been set
>>> is a subset of the list created with the flag.
>>> Also Test that the flag is cleared after calling VIDIOC_ENUM_FMT.
>>>
>>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxxxxx>
>>> ---
>>> changes in version 2:
>>> - Completely rework how the test it done.
>>>
>>>   include/linux/videodev2.h                   |  3 ++
>>>   utils/common/v4l2-info.cpp                  |  1 +
>>>   utils/v4l2-compliance/v4l2-test-formats.cpp | 36 +++++++++++++++++++++
>>>   3 files changed, 40 insertions(+)
>>>
>>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
>>> index f18a40d4..c166bb35 100644
>>> --- a/include/linux/videodev2.h
>>> +++ b/include/linux/videodev2.h
>>> @@ -864,6 +864,9 @@ struct v4l2_fmtdesc {
>>>   #define V4L2_FMT_FLAG_CSC_QUANTIZATION        0x0100
>>>   #define V4L2_FMT_FLAG_META_LINE_BASED        0x0200
>>>   +/*  Format description flag, to be ORed with the index */
>>> +#define V4L2_FMTDESC_FLAG_ENUM_ALL        0x80000000
>>> +
>>>       /* Frame Size and frame rate enumeration */
>>>   /*
>>>    *    F R A M E   S I Z E   E N U M E R A T I O N
>>> diff --git a/utils/common/v4l2-info.cpp b/utils/common/v4l2-info.cpp
>>> index aaf7b0b5..248ab9c3 100644
>>> --- a/utils/common/v4l2-info.cpp
>>> +++ b/utils/common/v4l2-info.cpp
>>> @@ -383,6 +383,7 @@ static constexpr flag_def fmtdesc_ ## enc_type ## _def[] = {             \
>>>       { V4L2_FMT_FLAG_CSC_QUANTIZATION, "csc-quantization" },         \
>>>       { V4L2_FMT_FLAG_CSC_XFER_FUNC, "csc-xfer-func" },             \
>>>       { V4L2_FMT_FLAG_META_LINE_BASED, "meta-line-based" },            \
>>> +    { V4L2_FMTDESC_FLAG_ENUM_ALL, "enum-all-format" },            \
>> Ah, no. This lists the possible flag of the flags field, V4L2_FMTDESC_FLAG_ENUM_ALL
>> doesn't belong there.
>>
>> In fact, there is no need to add it at all since it is never reported.
>>
>> But you do need to add support for it in v4l2-ctl: I think that the various
>> --list-formats(-ext) options needs to check for an optional suboption 'all',
>> which will set the new V4L2_FMTDESC_FLAG_ENUM_ALL flag. That's a separate patch
>> for v4l2-ctl.
>>
>>>       { 0, NULL }                                 \
>>>   };
>>>   diff --git a/utils/v4l2-compliance/v4l2-test-formats.cpp b/utils/v4l2-compliance/v4l2-test-formats.cpp
>>> index fc16ad39..2b743da5 100644
>>> --- a/utils/v4l2-compliance/v4l2-test-formats.cpp
>>> +++ b/utils/v4l2-compliance/v4l2-test-formats.cpp
>>> @@ -224,6 +224,7 @@ static int testEnumFrameSizes(struct node *node, __u32 pixfmt)
>>>   static int testEnumFormatsType(struct node *node, unsigned type)
>>>   {
>>>       pixfmt_map &map = node->buftype_pixfmts[type];
>>> +    pixfmt_map enum_all;
>>>       struct v4l2_fmtdesc fmtdesc;
>>>       unsigned f = 0;
>>>       int ret;
>>> @@ -317,6 +318,41 @@ static int testEnumFormatsType(struct node *node, unsigned type)
>>>                       fmtdesc.pixelformat, fcc2s(fmtdesc.pixelformat).c_str());
>>>           map[fmtdesc.pixelformat] = fmtdesc.flags;
>>>       }
>>> +
>>> +    /* Test V4L2_FMTDESC_FLAG_ENUM_ALL if supported */
>>> +    f = 0;
>>> +    for (;;) {
>>> +        memset(&fmtdesc, 0xff, sizeof(fmtdesc));
>>> +        fmtdesc.type = type;
>>> +        fmtdesc.index = f | V4L2_FMTDESC_FLAG_ENUM_ALL;
>>> +        fmtdesc.mbus_code = 0;
>>> +
>>> +        ret = doioctl(node, VIDIOC_ENUM_FMT, &fmtdesc);
>>> +        if (ret == ENOTTY)
>>> +            return ret;
>> This would be a failure: it can't return ENOTTY since that was already tested
>> in the first test without the ALL flag. You can drop this test, since it will
>> fail later.
>>
>>> +        if (f == 0 && ret == EINVAL)
>>> +            return 0;
>>> +        if (ret == EINVAL)
>>> +            break;
>>> +        if (ret)
>>> +            return fail("expected EINVAL, but got %d when enumerating buftype %d\n", ret, type);
>> This will catch the ENOTTY.
>>
>>> +        if (fmtdesc.index != f)
>>> +            return fail("V4L2_FMTDESC_FLAG_ENUM_ALL hasn't been cleared from fmtdesc.index 0x%x f 0x%x\n", fmtdesc.index, f);
>>> +        f++;
>>> +        if (type == V4L2_BUF_TYPE_PRIVATE)
>>> +            continue;
>>> +        assert(type <= V4L2_BUF_TYPE_LAST);
>>> +        if (enum_all.find(fmtdesc.pixelformat) != enum_all.end())
>>> +            return fail("duplicate format %08x (%s)\n",
>>> +                    fmtdesc.pixelformat, fcc2s(fmtdesc.pixelformat).c_str());
>>> +        enum_all[fmtdesc.pixelformat] = fmtdesc.flags;
>>> +    }
>>> +    /* if V4L2_FMTDESC_FLAG_ENUM_ALL is supported, verify that the list is a subset of VIDIOC_ENUM_FMT list */
>>> +    if (!enum_all.empty()) {
>> You can drop this if. If enum_all is empty, and map isn't, then it will just
>> fail in the next for loop.
> 
> enum_all could be empty if V4L2_FMTDESC_FLAG_ENUM_ALL isn't supported and
> it shouldn't fail in this case.

But that is caught by the "if (f == 0 && ret == EINVAL)" check above. In that case
it just returns 0.

Regards,

	Hans

> 
>>> +        for (auto it = map.begin(); it != map.end(); it++)
>>> +            if (enum_all.find(it->first) == enum_all.end())
>>> +                return fail("V4L2_FMTDESC_FLAG_ENUM_ALL failed to enumerate format %08x (%s)\n", it->first, fcc2s(it->first).c_str());
>>> +    }
>>>       info("found %d formats for buftype %d\n", f, type);
>> Note that f was reset above, so this info message should be moved up to just before the
>> V4L2_FMTDESC_FLAG_ENUM_ALL test starts.
>>
>> But perhaps keep this info message here as well, just change it to:
>>
>>        info("found %d formats for buftype %d (with V4L2_FMTDESC_FLAG_ENUM_ALL)\n", f, type);
>>
>> Regards,
>>
>>     Hans
>>
>>>       return 0;
>>>   }
>>





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux