我使用SDL2.0.7(Nexus 5,armeabi-v7a,ndk 16.1)在本机应用上显示Android相机预览。
我正在使用 N21 YUV图片格式,我希望创建SDL_Texture
该格式, pitch 值返回SDL_LockTexture()
会比我现在得到的更大。
示例代码:
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_NV21, SDL_TEXTUREACCESS_STREAMING, 720, 480);
int res = SDL_LockTexture(texture, nullptr, &pixels, &pitch);
我希望得到720 * 12 / 8
的音高值,即1080
,其中720
是一行的宽度,12
是单个YUV N21像素的位数,8
是一个字节中的位数,因为the SDL2 documentation表示:
音高:这是用锁定像素的音高填充的; pitch是一行的长度,以字节为单位
现在,函数调用实际返回的音高值为720
。事实是,如果我使用720
值,相机预览将以不自然的绿色优势显示,而如果我忽略720
音高并使用我预期的1080
音高,相机预览很好(应用程序运行也很流畅)。
我的假设是否有问题(例如,N21像素的位数是12,正如Android ImageFormat.getBitsPerPixel()
建议的那样)?我是否以错误的方式使用SDL库?
答案 0 :(得分:2)
流纹理的创建纹理实用程序在内部执行此操作:
// ...
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
size_t size;
data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
size = texture->h * data->pitch;
if (data->yuv) {
/* Need to add size for the U and V planes */
size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
}
if (data->nv12) {
/* Need to add size for the U/V plane */
size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
}
data->pixel_data = SDL_calloc(1, size);
if (!data->pixel_data) {
SDL_free(data);
return SDL_OutOfMemory();
}
}
// ...
在您的情况下,对于您正在使用SDL_PIXELFORMAT_NV21
,yuv
为false且nv12
为真(如果听起来很奇怪,请使用调试器进行尝试)。
这意味着分配的大小不是pitch * height
。相反,它是:
(pitch * height) + 2 * ((height + 1) / 2) * ((pitch + 1) / 2);
在这种情况下,pitch
等于width
。
在一天结束时,它的大小是图像大小的1.5倍,即每像素12位。
它被授予pitch
的价值错误,因为它等于width
。
实际上,由于分配的空间,它应该是您想象的图像宽度的1.5倍
但是我对此并不确定,因为我不是SDL2的专家。