Video encoders like Intel® Media SDK do not accept 8 bits Grayscale image as input format.
8 bits Grayscale format applies one byte per pixel in range [0, 255].
8 bits YUV format in the context of the question applies YCbCr (BT.601 or BT.709).
Although there is a full range YUV standard, the commonly used format is "limited range" YUV, where range of Y is [16, 235] and range of U,V is [16, 240].
NV12 format is the common input format in this case.
NV12 format is YUV 4:2:0 format ordered in memory with a Y plane first, followed by packed chroma samples in interleaved UV plane:
YYYYYY
YYYYYY
UVUVUV
The Grayscale image will be referred as "I plane":
IIIIII
IIIIII
Setting the UV plane is simple: Set all U,V elements to 128 value.
But what about the Y plane?
In case of full range YUV, we can simply put "I plane" as Y plane (i.e Y = I).
In case of "limited" YUV format, a transformation is required:
Setting R=G=B in the conversion formula results: Y = round(I*0.859 + 16).
What is the efficient way to do the above conversion using IPP?
I am adding an answer to my own question.
I hope to see a better answer...
I found a solution using two IPP functions:
I selected functions that uses fixed point math, for better performance.
0.859
scaling is performed by expanding, scaling and shifting. Example:b = (a*scale + (1<<7)) >> 8;
[Whenscale
=(0.859)*2^8
].val
parameter toippsMulC_8u_Sfs
set toround(0.859*2^8)
=220
.scaleFactor
parameter toippsMulC_8u_Sfs
set to8
(divide the scaled result by2^8
).Code sample:
Out of topic note:
There is a way to mark a video stream as "full range" (where
Y
range is [0, 255] instead of [16
,235
], andU
,V
range is also [0, 255]).Using the "full range" standard allows placing
I
in place ofY
(i.e Y = I).Marking the stream as "full range" using Intel Media SDK, is possible (but not well documented).
Marking H.264 stream as "full range" requires to add pointer to
mfxExtBuffer **ExtParam
list (in structuremfxVideoParam
):A pointer to structure of type
mfxExtVideoSignalInfo
should be added with the following values:VideoFullRange = 1
is the only relevant parameter of setting "full range" video, but we must fill the entire structure.