Nevcairiel / LAVFilters

LAV Filters - Open-Source DirectShow Media Splitter and Decoders
GNU General Public License v2.0
7.34k stars 789 forks source link

RGB48 pitch not aligned 4 #488

Closed v0lt closed 2 years ago

v0lt commented 2 years ago

I tested this Avisynth+ script: Colorbars(Width=1023,Height=100,Pixel_type="RGB48")

Pitch after AVI/WAV File Source is 6140. Pitch after LAV Splitter Source is 6138.

Nevcairiel commented 2 years ago

DirectShow uses the number of pixel to communicate pitch, not bytes. Pitch is communicated through BITMAPINFOHEADER biWidth, which is a value in pixel width, which means it has to be a multiple of bytes per pixel - in this case 6.

6140 is not a possible value here, as it does not divide by 6.

In general, LAV Splitter is a splitter filter, not a video decoder or video processor, it does not perform any pitch padding or other corrections, but just output the video as-is, and as required by DirectShow. If you need further processing to happen, you can use LAV Video to process the video output from LAV Splitter - LAV Video can acccept any raw video formats output by LAV Splitter and will honor any pitch requirements set by the video renderer - do note that the same limitations apply, RGB48 needs to be a multiple of 6 first, anything else second.

v0lt commented 2 years ago

6140 is not a possible value here, as it does not divide by 6.

6140/6 = 1023 The remainder 2 can be simply discarded.

DirectShow uses the number of pixel to communicate pitch, not bytes.

The RGB24 pitch is a multiple of 4 bytes. MEDIASUBTYPE_RGB4 returns Generate Still Video from Microsoft if you open BMP or JPEG.

The pitch of some other formats is also a multiple of 4. I think there is a requirement in the specs that the beginning of lines should be aligned at a multiple of 4.

v0lt commented 2 years ago

I found the spec. https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader

For uncompressed RGB formats, the minimum stride is always the image width in bytes, rounded up to the nearest DWORD. You can use the following formula to calculate the stride:

stride = ((((biWidth * biBitCount) + 31) & ~31) >> 3)

Nevcairiel commented 2 years ago

These rules only apply if biCompression is BI_RGB, I don't think thats ever used by LAV Splitter.

In fact looking at it, I don't think LAV Splitter is even capable of outputting RGB48 directly without LAV Video.

v0lt commented 2 years ago

Let's say. Then please fix lSampleSize and biSizeImage sizes in LAV Splitter Source. Now these parameters are the same as in AVI/WAV File Source.

As you said the formula should be: biSizeImage = biWidth biBitCount/8 biHeight And the result: biSizeImage = 1023 48/8 100 = 613800

But I see 614000:

LAV Splitter Source
lSampleSize: 614000
biWidth: 1023
biHeight: 100
biBitCount: 48
biSizeImage: 614000

As in Avisynth+:

AVI/WAV File Source
lSampleSize: 614000
biWidth: 1023
biHeight: 100
biBitCount: 48
biSizeImage: 614000

biSizeImage = Aling4(1023 48/8) 100 = 614000