SDL_LockTexture()返回意外的音高值

问题描述 投票:1回答:1

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

我正在使用N21 YUV图像格式,我期待着,创建一个这种格式的SDL_TextureSDL_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库?

android textures sdl sdl-2 yuv
1个回答
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是假的,nv12是真的(如果听起来很奇怪,请尝试使用调试器)。 这意味着分配的大小不是pitch * height。相反,它是:

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

在这种情况下,pitch等于width

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


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

© www.soinside.com 2019 - 2024. All rights reserved.