webcamoid / akvcam

akvcam, virtual camera for Linux
GNU General Public License v2.0
626 stars 87 forks source link

Wrong color on little endian machine #68

Closed mantorchan closed 1 year ago

mantorchan commented 1 year ago

After compiling and loaded in android , some color streaming to capture device is wrong, eg. put in rgb24(190,0,0), would get (155,0,11) from the decoded yuy2 reading directly from /dev/video*. I have tried swap the r and b in akvcam_RGB24 struct, and it's blue now. Am I missing something?

hipersayanX commented 1 year ago

After compiling and loaded in android

How you did that? Android camera drivers are not supposed to work with V4L2, if you want to create a virtual camera for Android you must use HAL 3.

some color streaming to capture device is wrong, eg. put in rgb24(190,0,0), would get (155,0,11) from the decoded yuy2 reading directly from /dev/video*.

Here you can see the formulas used to convert between RGB <-> YUV, and here is a code snipped you can use to test it. The conversion should give you:

RGB(190, 0, 0) -> YUV(65, 100, 211)
YUV(65, 100, 211) -> RGB(190, 1, 1)

Idk how did you get that (155,0,11) result. Also take in mind that YUY2 is half of the U plane, and half of the V plane, so the colors will look much darker than the colors of the original image because there is an information loss during the conversion.

mantorchan commented 1 year ago

Kernel 5.10 is used in Android 12 , this module can be compiled just like others either out of tree or in source as a driver module. After loaded, akvcam would be recognized as an external camera.

and half of the V plane, so the colors will look much darker than the colors of the original image because there is an information loss during the conversion.

I have compared the same pic with the same config of akvcam in x86 computer,using ffmpeg and ffplay, which is normal,at least could not tell much difference by eyes. The layout of rgb24 color struct used in akvcam wouldn't affect by endianness,I might point the question to a wrong way . The buffer feed to output device, is a normal r,g,b sequence ,r in [0], the log added in akvcam source where is just before rgb24-yuy2 conversion shows r and b is swapped, just the way tells by the rgb24 color struct definition ,the weird thing comes here, the decoded pic read from capture looks like darker than it should be, but is not r-b swapped. Something might swapped them back after the adjust routine?

hipersayanX commented 1 year ago

Kernel 5.10 is used in Android 12 , this module can be compiled just like others either out of tree or in source as a driver module. After loaded, akvcam would be recognized as an external camera.

Give me a full simple and clear baby step by step tutorial on how you did it. I don't want to compile the whole Android thing, just want to test it in the emulator. I want to try it later :smile:

the weird thing comes here, the decoded pic read from capture looks like darker than it should be, but is not r-b swapped. Something might swapped them back after the adjust routine?

As said before, if the RGB order is ok in the capturing side, let say you draw a red rectangle and you can see it as red, you draw a green rectangle and you can see it as green, and you draw a blue rectangle and you can see it as blue, but you see the colors darker than the originals, it's a normal behavior of the RGB <-> YUY2 conversion. Also, you can try maybe swapping the YUY2 structure. Anyway, the conversion functions are just a quick hack and don't handles endianness. My idea is to port the video converter from Webcamoid (which actually handles endianness) to C, but don't expect it in the near time.