SDL_LockTexture() 返回意外的音高值

SDL_LockTexture() returning an unexpected pitch value

我正在使用 SDL2.0.7(Nexus 5、armeabi-v7a、ndk 16.1)在本机应用程序上显示 Android 相机预览。

我正在使用 N21 YUV 图像格式,我期待创建该格式的 SDL_Texturepitch 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: this is filled in with the pitch of the locked pixels; the pitch is the length of one row in bytes

现在,函数调用实际返回的pitch值是720。事实是,如果我使用 720 值,相机预览将以不自然的绿色优势显示,而如果我忽略 720 间距并使用我预期的 1080 间距,相机预览很好(应用程序运行也很流畅)。

我的假设有什么问题吗(例如,N21 像素的位数是 12,正如 Android 的 ImageFormat.getBitsPerPixel() 所暗示的那样)?我是否以错误的方式使用了 SDL 库?

流式纹理的创建纹理实用程序在内部执行此操作:

// ...

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 是假的,nv12 是真的(如果听起来很奇怪,用调试器试试)。
这意味着分配的大小不是 pitch * height。相反,它是:

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

在这种情况下,pitch 等于 width

归根结底,它是图像大小的 1.5 倍,即每像素 12 位。


当然 pitch 的值在某种程度上是 错误的 ,因为它等于 width.
实际上,由于分配了 space,它应该是您期望的图像宽度的 1.5 倍。
但是我不太确定,因为我不是 SDL2 的专家。