SDL_LockTexture()返回意外的音高值

时间:2018-01-03 14:18:13

标签: android textures sdl sdl-2 yuv

我使用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库?

1 个答案:

答案 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_NV21yuv为false且nv12为真(如果听起来很奇怪,请使用调试器进行尝试)。
这意味着分配的大小不是pitch * height。相反,它是:

(pitch * height) + 2 * ((height + 1) / 2) * ((pitch + 1) / 2);

在这种情况下,pitch等于width

在一天结束时,它的大小是图像大小的1.5倍,即每像素12位。

它被授予pitch的价值错误,因为它等于width
实际上,由于分配的空间,它应该是您想象的图像宽度的1.5倍 但是我对此并不确定,因为我不是SDL2的专家。