diff mbox

[3/4] kms++util: Add verification module

Message ID 2804f59b2ecafc22abb57428f38a9b2d267ff0b7.1513206331.git-series.kieran.bingham@ideasonboard.com (mailing list archive)
State Not Applicable
Delegated to: Geert Uytterhoeven
Headers show

Commit Message

Kieran Bingham Dec. 13, 2017, 11:10 p.m. UTC
From: Kieran Bingham <kieran.bingham@ideasonboard.com>

Provide a util module to provide helpers involved in validation and verification
of data frames.

The first addition is a raw frame binary output with bindings to python modelled
on Tomi's implementation in wbcap.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 kms++util/inc/kms++util/kms++util.h |  2 ++
 kms++util/src/verification.cpp      | 21 +++++++++++++++++++++
 py/pykms/pykmsutil.cpp              |  5 +++++
 3 files changed, 28 insertions(+)
 create mode 100644 kms++util/src/verification.cpp

Comments

Tomi Valkeinen Dec. 15, 2017, 1:43 p.m. UTC | #1
Hi,

On 14/12/17 01:10, Kieran Bingham wrote:
> From: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> Provide a util module to provide helpers involved in validation and verification
> of data frames.
> 
> The first addition is a raw frame binary output with bindings to python modelled
> on Tomi's implementation in wbcap.

I don't think verification.cpp is a good name for this. A function to 
save the fb sounds like a generic fb utility.

In fact, I'd like to have a helper utility function to save as png, as 
converting a raw image to png is a bit of a hassle. Then again, we'd 
need a png library for that, and possibly bigger pieces of code to 
handle all the different pixel formats...

So, a function to save the raw bits is fine, but how about "fbutils.cpp" 
or such?

> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> ---
>   kms++util/inc/kms++util/kms++util.h |  2 ++
>   kms++util/src/verification.cpp      | 21 +++++++++++++++++++++
>   py/pykms/pykmsutil.cpp              |  5 +++++
>   3 files changed, 28 insertions(+)
>   create mode 100644 kms++util/src/verification.cpp
> 
> diff --git a/kms++util/inc/kms++util/kms++util.h b/kms++util/inc/kms++util/kms++util.h
> index 8e45b0df3cde..431de0bb159a 100644
> --- a/kms++util/inc/kms++util/kms++util.h
> +++ b/kms++util/inc/kms++util/kms++util.h
> @@ -27,6 +27,8 @@ void draw_text(IFramebuffer& buf, uint32_t x, uint32_t y, const std::string& str
>   void draw_color_bar(IFramebuffer& buf, int old_xpos, int xpos, int width);
>   
>   void draw_test_pattern(IFramebuffer &fb, YUVType yuvt = YUVType::BT601_Lim);
> +
> +void save_raw_frame(IFramebuffer& fb, const char *filename);
>   }
>   
>   #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
> diff --git a/kms++util/src/verification.cpp b/kms++util/src/verification.cpp
> new file mode 100644
> index 000000000000..3210bb144d2b
> --- /dev/null
> +++ b/kms++util/src/verification.cpp
> @@ -0,0 +1,21 @@
> +
> +#include <kms++/kms++.h>
> +#include <kms++util/kms++util.h>
> +
> +#include <fstream>
> +
> +using namespace std;
> +
> +namespace kms
> +{
> +
> +void save_raw_frame(IFramebuffer& fb, const char *filename)
> +{
> +	unique_ptr<ofstream> os;
> +	os = unique_ptr<ofstream>(new ofstream(filename, ofstream::binary));
> +
> +	for (unsigned i = 0; i < fb.num_planes(); ++i)
> +		os->write((char*)fb.map(i), fb.size(i));
> +}

You don't need any of that unique_ptr stuff here. I needed it as the 
code needed to handle the case where we don't save, i.e. os = null.

And I'm not fond of the function name, "frame" doesn't sound good. Maybe 
rather save_raw_fb(). Or save_fb_raw(), so in the future we might have 
also save_fb_png().

> +
> +}
> diff --git a/py/pykms/pykmsutil.cpp b/py/pykms/pykmsutil.cpp
> index 518d5eaa88f0..2d741751ba75 100644
> --- a/py/pykms/pykmsutil.cpp
> +++ b/py/pykms/pykmsutil.cpp
> @@ -59,4 +59,9 @@ void init_pykmstest(py::module &m)
>   	} );
>   	m.def("draw_text", [](Framebuffer& fb, uint32_t x, uint32_t y, const string& str, RGB color) {
>   		draw_text(fb, x, y, str, color); } );
> +
> +	// Verification and Validation
> +	m.def("save_raw_frame", [](Framebuffer& fb, const char * filename) {
> +		save_raw_frame(fb, filename);
> +	});
>   }
>
Kieran Bingham Dec. 16, 2017, 4:13 p.m. UTC | #2
Hi Tomi,

Thank you for taking the time to look at this topic.

On 15/12/17 13:43, Tomi Valkeinen wrote:
> Hi,
> 
> On 14/12/17 01:10, Kieran Bingham wrote:
>> From: Kieran Bingham <kieran.bingham@ideasonboard.com>
>>
>> Provide a util module to provide helpers involved in validation and verification
>> of data frames.
>>
>> The first addition is a raw frame binary output with bindings to python modelled
>> on Tomi's implementation in wbcap.
> 
> I don't think verification.cpp is a good name for this. A function to save the
> fb sounds like a generic fb utility.

Yes, I was originally going to put it in one of the existing framebuffer classes
- but then realised they were abstracted classes, and it had to use the base type :)

I was looking at verifying frames, so this was the first name that came to my
head :D

> In fact, I'd like to have a helper utility function to save as png, as
> converting a raw image to png is a bit of a hassle. Then again, we'd need a png
> library for that, and possibly bigger pieces of code to handle all the different
> pixel formats...

So would I ! I'm glad you bring the topic up :)

Are you happy to bring in external libraries to support such functionality?

I guess we can make it so the configure scripts select the feature if libraries
are available or such.

Being able to save directly to easily viewable file formats would certainly ease
things, (while still being able to save raw files for some manual verifications)

> So, a function to save the raw bits is fine, but how about "fbutils.cpp" or such?

Yes, that sounds reasonable.


>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
>> ---
>>   kms++util/inc/kms++util/kms++util.h |  2 ++
>>   kms++util/src/verification.cpp      | 21 +++++++++++++++++++++
>>   py/pykms/pykmsutil.cpp              |  5 +++++
>>   3 files changed, 28 insertions(+)
>>   create mode 100644 kms++util/src/verification.cpp
>>
>> diff --git a/kms++util/inc/kms++util/kms++util.h
>> b/kms++util/inc/kms++util/kms++util.h
>> index 8e45b0df3cde..431de0bb159a 100644
>> --- a/kms++util/inc/kms++util/kms++util.h
>> +++ b/kms++util/inc/kms++util/kms++util.h
>> @@ -27,6 +27,8 @@ void draw_text(IFramebuffer& buf, uint32_t x, uint32_t y,
>> const std::string& str
>>   void draw_color_bar(IFramebuffer& buf, int old_xpos, int xpos, int width);
>>     void draw_test_pattern(IFramebuffer &fb, YUVType yuvt = YUVType::BT601_Lim);
>> +
>> +void save_raw_frame(IFramebuffer& fb, const char *filename);
>>   }
>>     #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
>> diff --git a/kms++util/src/verification.cpp b/kms++util/src/verification.cpp
>> new file mode 100644
>> index 000000000000..3210bb144d2b
>> --- /dev/null
>> +++ b/kms++util/src/verification.cpp
>> @@ -0,0 +1,21 @@
>> +
>> +#include <kms++/kms++.h>
>> +#include <kms++util/kms++util.h>
>> +
>> +#include <fstream>
>> +
>> +using namespace std;
>> +
>> +namespace kms
>> +{
>> +
>> +void save_raw_frame(IFramebuffer& fb, const char *filename)
>> +{
>> +    unique_ptr<ofstream> os;
>> +    os = unique_ptr<ofstream>(new ofstream(filename, ofstream::binary));
>> +
>> +    for (unsigned i = 0; i < fb.num_planes(); ++i)
>> +        os->write((char*)fb.map(i), fb.size(i));
>> +}
> 
> You don't need any of that unique_ptr stuff here. I needed it as the code needed
> to handle the case where we don't save, i.e. os = null.

Ah OK - I thought it was providing the hook up to automatically close the stream
at the end of the function.

I guess an explicit close would be just as clean :)

As the commit message suggests, this was a direct copy paste from your
implementation after I saw it as a better implementation than my previous 'C'
version. (I don't spend a lot of time in C++ land)


> And I'm not fond of the function name, "frame" doesn't sound good. Maybe rather
> save_raw_fb(). Or save_fb_raw(), so in the future we might have also save_fb_png().

Agreed, sounds fine. I'm definitely looking forward to a save_fb_png().


>> +
>> +}
>> diff --git a/py/pykms/pykmsutil.cpp b/py/pykms/pykmsutil.cpp
>> index 518d5eaa88f0..2d741751ba75 100644
>> --- a/py/pykms/pykmsutil.cpp
>> +++ b/py/pykms/pykmsutil.cpp
>> @@ -59,4 +59,9 @@ void init_pykmstest(py::module &m)
>>       } );
>>       m.def("draw_text", [](Framebuffer& fb, uint32_t x, uint32_t y, const
>> string& str, RGB color) {
>>           draw_text(fb, x, y, str, color); } );
>> +
>> +    // Verification and Validation
>> +    m.def("save_raw_frame", [](Framebuffer& fb, const char * filename) {
>> +        save_raw_frame(fb, filename);
>> +    });
>>   }
>>
> 

Regards
--
Kieran
Laurent Pinchart Dec. 18, 2017, 11:36 a.m. UTC | #3
Hi Kieran,

On Saturday, 16 December 2017 18:13:51 EET Kieran Bingham wrote:
> On 15/12/17 13:43, Tomi Valkeinen wrote:
> > On 14/12/17 01:10, Kieran Bingham wrote:
> >> From: Kieran Bingham <kieran.bingham@ideasonboard.com>
> >> 
> >> Provide a util module to provide helpers involved in validation and
> >> verification of data frames.
> >> 
> >> The first addition is a raw frame binary output with bindings to python
> >> modelled on Tomi's implementation in wbcap.
> > 
> > I don't think verification.cpp is a good name for this. A function to save
> > the fb sounds like a generic fb utility.
> 
> Yes, I was originally going to put it in one of the existing framebuffer
> classes - but then realised they were abstracted classes, and it had to use
> the base type :)
> 
> I was looking at verifying frames, so this was the first name that came to
> my head :D
> 
> > In fact, I'd like to have a helper utility function to save as png, as
> > converting a raw image to png is a bit of a hassle. Then again, we'd need
> > a png library for that, and possibly bigger pieces of code to handle all
> > the different pixel formats...
> 
> So would I ! I'm glad you bring the topic up :)
> 
> Are you happy to bring in external libraries to support such functionality?
> 
> I guess we can make it so the configure scripts select the feature if
> libraries are available or such.
> 
> Being able to save directly to easily viewable file formats would certainly
> ease things, (while still being able to save raw files for some manual
> verifications)

The problem with PNG (or any other format really) is that you not only need to 
encode the image into the target format (PNG or JPG would require external 
libraries, simpler formats such as BMP or PNM could be handled internally), 
but you also need to convert the image to a particular RGB or YUV format 
depending on what the output format requires.

If you want to do so, I would like to reuse code from the v4l2convert library. 
The code should be moved to a library that doesn't depend on V4L2, as the 
current API encapsulate conversion in other operations. Other tools such as 
raw2rgbpnm could then be ported to use that library;

> > So, a function to save the raw bits is fine, but how about "fbutils.cpp"
> > or such?
> 
> Yes, that sounds reasonable.
> 
> >> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> >> ---
> >>   kms++util/inc/kms++util/kms++util.h |  2 ++
> >>   kms++util/src/verification.cpp      | 21 +++++++++++++++++++++
> >>   py/pykms/pykmsutil.cpp              |  5 +++++
> >>   3 files changed, 28 insertions(+)
> >>   create mode 100644 kms++util/src/verification.cpp
> >> 
> >> diff --git a/kms++util/inc/kms++util/kms++util.h
> >> b/kms++util/inc/kms++util/kms++util.h
> >> index 8e45b0df3cde..431de0bb159a 100644
> >> --- a/kms++util/inc/kms++util/kms++util.h
> >> +++ b/kms++util/inc/kms++util/kms++util.h
> >> @@ -27,6 +27,8 @@ void draw_text(IFramebuffer& buf, uint32_t x, uint32_t
> >> y,
> >> const std::string& str
> >>   void draw_color_bar(IFramebuffer& buf, int old_xpos, int xpos, int
> >> width); void draw_test_pattern(IFramebuffer &fb, YUVType yuvt =
> >> YUVType::BT601_Lim); +
> >> +void save_raw_frame(IFramebuffer& fb, const char *filename);
> >>   }
> >>     #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
> >> diff --git a/kms++util/src/verification.cpp
> >> b/kms++util/src/verification.cpp new file mode 100644
> >> index 000000000000..3210bb144d2b
> >> --- /dev/null
> >> +++ b/kms++util/src/verification.cpp
> >> @@ -0,0 +1,21 @@
> >> +
> >> +#include <kms++/kms++.h>
> >> +#include <kms++util/kms++util.h>
> >> +
> >> +#include <fstream>
> >> +
> >> +using namespace std;
> >> +
> >> +namespace kms
> >> +{
> >> +
> >> +void save_raw_frame(IFramebuffer& fb, const char *filename)
> >> +{
> >> +    unique_ptr<ofstream> os;
> >> +    os = unique_ptr<ofstream>(new ofstream(filename, ofstream::binary));
> >> +
> >> +    for (unsigned i = 0; i < fb.num_planes(); ++i)
> >> +        os->write((char*)fb.map(i), fb.size(i));
> >> +}
> > 
> > You don't need any of that unique_ptr stuff here. I needed it as the code
> > needed to handle the case where we don't save, i.e. os = null.
> 
> Ah OK - I thought it was providing the hook up to automatically close the
> stream at the end of the function.
> 
> I guess an explicit close would be just as clean :)
> 
> As the commit message suggests, this was a direct copy paste from your
> implementation after I saw it as a better implementation than my previous
> 'C' version. (I don't spend a lot of time in C++ land)
> 
> > And I'm not fond of the function name, "frame" doesn't sound good. Maybe
> > rather save_raw_fb(). Or save_fb_raw(), so in the future we might have
> > also save_fb_png().
> 
> Agreed, sounds fine. I'm definitely looking forward to a save_fb_png().
> 
> >> +
> >> +}
> >> diff --git a/py/pykms/pykmsutil.cpp b/py/pykms/pykmsutil.cpp
> >> index 518d5eaa88f0..2d741751ba75 100644
> >> --- a/py/pykms/pykmsutil.cpp
> >> +++ b/py/pykms/pykmsutil.cpp
> >> @@ -59,4 +59,9 @@ void init_pykmstest(py::module &m)
> >>       } );
> >>       m.def("draw_text", [](Framebuffer& fb, uint32_t x, uint32_t y,
> >> const
> >> string& str, RGB color) {
> >>           draw_text(fb, x, y, str, color); } );
> >> +
> >> +    // Verification and Validation
> >> +    m.def("save_raw_frame", [](Framebuffer& fb, const char * filename) {
> >> +        save_raw_frame(fb, filename);
> >> +    });
> >>   }
Tomi Valkeinen Dec. 18, 2017, 11:46 a.m. UTC | #4
On 18/12/17 13:36, Laurent Pinchart wrote:

> The problem with PNG (or any other format really) is that you not only need to
> encode the image into the target format (PNG or JPG would require external
> libraries, simpler formats such as BMP or PNM could be handled internally),
> but you also need to convert the image to a particular RGB or YUV format
> depending on what the output format requires.

Yes, that's the "hassle" part I was referring to =).

Maybe we need to invent a new file format that can store all kinds of 
formats? (https://xkcd.com/927/)

> If you want to do so, I would like to reuse code from the v4l2convert library.
> The code should be moved to a library that doesn't depend on V4L2, as the
> current API encapsulate conversion in other operations. Other tools such as
> raw2rgbpnm could then be ported to use that library;

Yep, so I agree that doing color format conversions shouldn't really be 
kms++'s job, but at the same time I'd like to be able to export 
framebuffers.

And I'm fine with adding dependencies to kms++, as long as all those are 
optional.

Aren't there "big" image conversion libraries that would do the job? 
Imagemagick? Or something? I have used "convert" command to do some 
conversions, that comes from ImageMagick.
Tomi Valkeinen Dec. 18, 2017, 11:49 a.m. UTC | #5
On 16/12/17 18:13, Kieran Bingham wrote:

>>> +void save_raw_frame(IFramebuffer& fb, const char *filename)
>>> +{
>>> +    unique_ptr<ofstream> os;
>>> +    os = unique_ptr<ofstream>(new ofstream(filename, ofstream::binary));
>>> +
>>> +    for (unsigned i = 0; i < fb.num_planes(); ++i)
>>> +        os->write((char*)fb.map(i), fb.size(i));
>>> +}
>>
>> You don't need any of that unique_ptr stuff here. I needed it as the code needed
>> to handle the case where we don't save, i.e. os = null.
> 
> Ah OK - I thought it was providing the hook up to automatically close the stream
> at the end of the function.
> 
> I guess an explicit close would be just as clean :)

You don't need an explicit close. The ofstream instance will be 
destructed automatically, and thus the stream will be closed.
Laurent Pinchart Dec. 18, 2017, 11:50 a.m. UTC | #6
Hi Tomi,

On Monday, 18 December 2017 13:46:22 EET Tomi Valkeinen wrote:
> On 18/12/17 13:36, Laurent Pinchart wrote:
> > The problem with PNG (or any other format really) is that you not only
> > need to encode the image into the target format (PNG or JPG would require
> > external libraries, simpler formats such as BMP or PNM could be handled
> > internally), but you also need to convert the image to a particular RGB
> > or YUV format depending on what the output format requires.
> 
> Yes, that's the "hassle" part I was referring to =).
> 
> Maybe we need to invent a new file format that can store all kinds of
> formats? (https://xkcd.com/927/)
> 
> > If you want to do so, I would like to reuse code from the v4l2convert
> > library. The code should be moved to a library that doesn't depend on
> > V4L2, as the current API encapsulate conversion in other operations.
> > Other tools such as raw2rgbpnm could then be ported to use that library;
> 
> Yep, so I agree that doing color format conversions shouldn't really be
> kms++'s job, but at the same time I'd like to be able to export
> framebuffers.
> 
> And I'm fine with adding dependencies to kms++, as long as all those are
> optional.
> 
> Aren't there "big" image conversion libraries that would do the job?
> Imagemagick? Or something? I have used "convert" command to do some
> conversions, that comes from ImageMagick.

That's an option too. I had a look at the code once to find out how 
ImageMagick was performing scaling and gave up with a headache soon 
afterwards. We need more formats than what ImageMagick currently supports 
(it's mostly focused on image file formats instead of raw image formats), with 
all kind of RGB, YUV (and ideally Bayer) formats, and I don't think extending 
ImageMagick would be the way to go.
Tomi Valkeinen Dec. 18, 2017, 12:04 p.m. UTC | #7
On 18/12/17 13:50, Laurent Pinchart wrote:

> That's an option too. I had a look at the code once to find out how
> ImageMagick was performing scaling and gave up with a headache soon
> afterwards. We need more formats than what ImageMagick currently supports
> (it's mostly focused on image file formats instead of raw image formats), with
> all kind of RGB, YUV (and ideally Bayer) formats, and I don't think extending
> ImageMagick would be the way to go.

Yep, I can image that ImageMagick can't handle it all. I don't really 
have much experience with it. I did find that it has enough tunables to 
manage rgbx8888 with different byte orders and the "extra" alpha channel:

convert -depth 8 -size $1x$2 -color-matrix "0 0 1 0 1 0 1 0 0" -alpha 
deactivate rgba:$3 png:-

But things like argb1555 or yuv422 might prove to be too difficult for 
ImageMagick.

Where's the source for v4l2convert? What does it do?

I wonder how difficult it would be to create a 
brute-force-no-optimizations style of a function to which you give the 
exact bit definition of the buffer's pixel format, and which gives you 
RGB888 or YUV444, depending on the input format (I presume most image 
encoders would accept RGB888 & YUV444).

I think the function wouldn't even need to care whether the data is RGB 
or YUV, it would just unpack it according to the format definition.

  Tomi
Geert Uytterhoeven Dec. 18, 2017, 12:06 p.m. UTC | #8
Hi Laurent,

On Mon, Dec 18, 2017 at 12:50 PM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Monday, 18 December 2017 13:46:22 EET Tomi Valkeinen wrote:
>> On 18/12/17 13:36, Laurent Pinchart wrote:
>> > The problem with PNG (or any other format really) is that you not only
>> > need to encode the image into the target format (PNG or JPG would require
>> > external libraries, simpler formats such as BMP or PNM could be handled
>> > internally), but you also need to convert the image to a particular RGB
>> > or YUV format depending on what the output format requires.
>>
>> Yes, that's the "hassle" part I was referring to =).
>>
>> Maybe we need to invent a new file format that can store all kinds of
>> formats? (https://xkcd.com/927/)
>>
>> > If you want to do so, I would like to reuse code from the v4l2convert
>> > library. The code should be moved to a library that doesn't depend on
>> > V4L2, as the current API encapsulate conversion in other operations.
>> > Other tools such as raw2rgbpnm could then be ported to use that library;
>>
>> Yep, so I agree that doing color format conversions shouldn't really be
>> kms++'s job, but at the same time I'd like to be able to export
>> framebuffers.
>>
>> And I'm fine with adding dependencies to kms++, as long as all those are
>> optional.
>>
>> Aren't there "big" image conversion libraries that would do the job?
>> Imagemagick? Or something? I have used "convert" command to do some
>> conversions, that comes from ImageMagick.
>
> That's an option too. I had a look at the code once to find out how
> ImageMagick was performing scaling and gave up with a headache soon
> afterwards. We need more formats than what ImageMagick currently supports
> (it's mostly focused on image file formats instead of raw image formats), with
> all kind of RGB, YUV (and ideally Bayer) formats, and I don't think extending
> ImageMagick would be the way to go.

netpbm is your friend.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Laurent Pinchart Dec. 18, 2017, 3:41 p.m. UTC | #9
Hi Tomi,

On Monday, 18 December 2017 14:04:45 EET Tomi Valkeinen wrote:
> On 18/12/17 13:50, Laurent Pinchart wrote:
> > That's an option too. I had a look at the code once to find out how
> > ImageMagick was performing scaling and gave up with a headache soon
> > afterwards. We need more formats than what ImageMagick currently supports
> > (it's mostly focused on image file formats instead of raw image formats),
> > with all kind of RGB, YUV (and ideally Bayer) formats, and I don't think
> > extending ImageMagick would be the way to go.
> 
> Yep, I can image that ImageMagick can't handle it all. I don't really
> have much experience with it. I did find that it has enough tunables to
> manage rgbx8888 with different byte orders and the "extra" alpha channel:
> 
> convert -depth 8 -size $1x$2 -color-matrix "0 0 1 0 1 0 1 0 0" -alpha
> deactivate rgba:$3 png:-
> 
> But things like argb1555 or yuv422 might prove to be too difficult for
> ImageMagick.
> 
> Where's the source for v4l2convert? What does it do?

Sorry, it's v4lconvert, not v4l2convert. The library is part of v4l-utils 
(available at git://linuxtv.org/pinchartl/v4l-utils.git) and is found in the 
lib/libv4lconvert directory.

The purpose of the library is to convert from lots of weird formats supported 
by V4L2 to RGB or YUV. It was initially written to handle vendor-specific 
compression formats used by webcams, has been extended to support Bayer 
formats and different kind of RGB and YUV formats. The code is simple, I think 
it could be a good base.

> I wonder how difficult it would be to create a brute-force-no-optimizations
> style of a function to which you give the exact bit definition of the
> buffer's pixel format, and which gives you RGB888 or YUV444, depending on
> the input format (I presume most image encoders would accept RGB888 &
> YUV444).

Can you come up with a bit definition format that could describe Bayer or 
tiled formats without requiring the definition to be written in an interpreted 
language ? :-)

> I think the function wouldn't even need to care whether the data is RGB
> or YUV, it would just unpack it according to the format definition.
Tomi Valkeinen Dec. 18, 2017, 3:48 p.m. UTC | #10
On 18/12/17 17:41, Laurent Pinchart wrote:
> Hi Tomi,
> 
> On Monday, 18 December 2017 14:04:45 EET Tomi Valkeinen wrote:
>> On 18/12/17 13:50, Laurent Pinchart wrote:
>>> That's an option too. I had a look at the code once to find out how
>>> ImageMagick was performing scaling and gave up with a headache soon
>>> afterwards. We need more formats than what ImageMagick currently supports
>>> (it's mostly focused on image file formats instead of raw image formats),
>>> with all kind of RGB, YUV (and ideally Bayer) formats, and I don't think
>>> extending ImageMagick would be the way to go.
>>
>> Yep, I can image that ImageMagick can't handle it all. I don't really
>> have much experience with it. I did find that it has enough tunables to
>> manage rgbx8888 with different byte orders and the "extra" alpha channel:
>>
>> convert -depth 8 -size $1x$2 -color-matrix "0 0 1 0 1 0 1 0 0" -alpha
>> deactivate rgba:$3 png:-
>>
>> But things like argb1555 or yuv422 might prove to be too difficult for
>> ImageMagick.
>>
>> Where's the source for v4l2convert? What does it do?
> 
> Sorry, it's v4lconvert, not v4l2convert. The library is part of v4l-utils
> (available at git://linuxtv.org/pinchartl/v4l-utils.git) and is found in the
> lib/libv4lconvert directory.
> 
> The purpose of the library is to convert from lots of weird formats supported
> by V4L2 to RGB or YUV. It was initially written to handle vendor-specific
> compression formats used by webcams, has been extended to support Bayer
> formats and different kind of RGB and YUV formats. The code is simple, I think
> it could be a good base.
> 
>> I wonder how difficult it would be to create a brute-force-no-optimizations
>> style of a function to which you give the exact bit definition of the
>> buffer's pixel format, and which gives you RGB888 or YUV444, depending on
>> the input format (I presume most image encoders would accept RGB888 &
>> YUV444).
> 
> Can you come up with a bit definition format that could describe Bayer or
> tiled formats without requiring the definition to be written in an interpreted
> language ? :-)

I have only worked with RGB and YUV, so that should be enough for 
everybody. ;)

But more seriously, I think kms++ is mainly for display. Do we have any 
display devices that support Bayer? And tiled formats sound a bit 
special platform specific cases.

That said, if we have a library that just does it all, that's obviously 
the best option.
diff mbox

Patch

diff --git a/kms++util/inc/kms++util/kms++util.h b/kms++util/inc/kms++util/kms++util.h
index 8e45b0df3cde..431de0bb159a 100644
--- a/kms++util/inc/kms++util/kms++util.h
+++ b/kms++util/inc/kms++util/kms++util.h
@@ -27,6 +27,8 @@  void draw_text(IFramebuffer& buf, uint32_t x, uint32_t y, const std::string& str
 void draw_color_bar(IFramebuffer& buf, int old_xpos, int xpos, int width);
 
 void draw_test_pattern(IFramebuffer &fb, YUVType yuvt = YUVType::BT601_Lim);
+
+void save_raw_frame(IFramebuffer& fb, const char *filename);
 }
 
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
diff --git a/kms++util/src/verification.cpp b/kms++util/src/verification.cpp
new file mode 100644
index 000000000000..3210bb144d2b
--- /dev/null
+++ b/kms++util/src/verification.cpp
@@ -0,0 +1,21 @@ 
+
+#include <kms++/kms++.h>
+#include <kms++util/kms++util.h>
+
+#include <fstream>
+
+using namespace std;
+
+namespace kms
+{
+
+void save_raw_frame(IFramebuffer& fb, const char *filename)
+{
+	unique_ptr<ofstream> os;
+	os = unique_ptr<ofstream>(new ofstream(filename, ofstream::binary));
+
+	for (unsigned i = 0; i < fb.num_planes(); ++i)
+		os->write((char*)fb.map(i), fb.size(i));
+}
+
+}
diff --git a/py/pykms/pykmsutil.cpp b/py/pykms/pykmsutil.cpp
index 518d5eaa88f0..2d741751ba75 100644
--- a/py/pykms/pykmsutil.cpp
+++ b/py/pykms/pykmsutil.cpp
@@ -59,4 +59,9 @@  void init_pykmstest(py::module &m)
 	} );
 	m.def("draw_text", [](Framebuffer& fb, uint32_t x, uint32_t y, const string& str, RGB color) {
 		draw_text(fb, x, y, str, color); } );
+
+	// Verification and Validation
+	m.def("save_raw_frame", [](Framebuffer& fb, const char * filename) {
+		save_raw_frame(fb, filename);
+	});
 }