我正在回答自己的问题。
希望能看到更好的答案...
我找到了一个使用两个IPP函数的解决方案:
我选择使用固定点数学运算的函数,以获得更好的性能。
- 通过扩展、缩放和移位来执行
0.859
缩放的定点实现。例如:b = (a*scale + (1<<7)) >> 8;
[当 scale
= (0.859)*2^8
时]。
ippsMulC_8u_Sfs
函数的 val
参数设置为 round(0.859*2^8)
= 220
。
ippsMulC_8u_Sfs
函数的 scaleFactor
参数设置为 8
(将缩放后的结果除以 2^8
)。
代码示例:
void GrayscaleToNV12(const unsigned char I[],
int image_width,
int image_height,
unsigned char J[])
{
IppStatus ipp_status;
const int image_size = image_width*image_height;
unsigned char *UV = &J[image_size];
const Ipp8u expanded_scaling = (Ipp8u)(0.859 * 256.0 + 0.5);
ipp_status = ippsMulC_8u_Sfs(I,
expanded_scaling,
J,
image_size,
8);
ipp_status = ippsAddC_8u_ISfs(16,
J,
image_size,
0);
memset(UV, 128, image_width*image_height/2);
}
不是主题的注记:
有一种方法可以将视频流标记为“全范围”(其中Y
范围为[0,255],而不是[16
,235
],而且U
,V
范围也为[0,255])。
使用“全范围”标准允许在Y= I
的位置放置I
。
使用Intel Media SDK将流设置为“全范围”是可能的(但文档不太好)。
将H.264流标记为“全范围”需要向指向mfxExtBuffer ** ExtParam
列表(在结构mfxVideoParam
中)添加指针:
应添加指向类型为mfxExtVideoSignalInfo
的结构的指针,其中包括以下值:
typedef struct {
mfxExtBuffer Header; //MFX_EXTBUFF_VIDEO_SIGNAL_INFO and sizeof(mfxExtVideoSignalInfo)
mfxU16 VideoFormat; //Most likely 5 ("Unspecified video format")
mfxU16 VideoFullRange; //1 (video_full_range_flag is equal to 1)
mfxU16 ColourDescriptionPresent; //0 (description_present_flag equal to 0)
mfxU16 ColourPrimaries; //0 (no affect when ColourDescriptionPresent = 0)
mfxU16 TransferCharacteristics; //0 (no affect when ColourDescriptionPresent = 0)
mfxU16 MatrixCoefficients; //0 (no affect when ColourDescriptionPresent = 0)
} mfxExtVideoSignalInfo;
VideoFullRange = 1
是设置“全范围”视频的唯一相关参数,但我们必须填充整个结构。
MFX_CHROMAFORMAT_MONOCHROME
呢? - apalopohapa