mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-09-17 10:34:48 +00:00
Fixed YUV size and pitch calculations
This commit is contained in:
@@ -140,6 +140,7 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
int row;
|
||||
size_t length;
|
||||
const int bpp = SDL_BYTESPERPIXEL(swdata->format);
|
||||
const int UVpitch = ((pitch / bpp + 1) / 2) * bpp;
|
||||
|
||||
// Copy the Y plane
|
||||
src = (Uint8 *)pixels;
|
||||
@@ -158,19 +159,19 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
length = ((rect->w + 1) / 2) * bpp;
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += (pitch + 1) / 2;
|
||||
src += UVpitch;
|
||||
dst += swdata->pitches[1];
|
||||
}
|
||||
|
||||
// Copy the next plane
|
||||
src = (Uint8 *)pixels + rect->h * pitch + ((rect->h + 1) / 2) * ((pitch + 1) / 2);
|
||||
src = (Uint8 *)pixels + rect->h * pitch + ((rect->h + 1) / 2) * UVpitch;
|
||||
dst = swdata->pixels + swdata->h * swdata->w +
|
||||
((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
|
||||
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
|
||||
length = ((rect->w + 1) / 2) * bpp;
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += (pitch + 1) / 2;
|
||||
src += UVpitch;
|
||||
dst += swdata->pitches[2];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "../SDL_d3dmath.h"
|
||||
#include "../../video/windows/SDL_windowsvideo.h"
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
#include "../../video/SDL_yuv_c.h"
|
||||
|
||||
#define D3D_DEBUG_INFO
|
||||
#include <d3d9.h>
|
||||
@@ -807,8 +808,12 @@ static bool D3D_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
if (texturedata->yuv) {
|
||||
// It's more efficient to upload directly...
|
||||
if (!texturedata->pixels) {
|
||||
texturedata->pitch = texture->w;
|
||||
texturedata->pixels = (Uint8 *)SDL_malloc((texture->h * texturedata->pitch * 3) / 2);
|
||||
size_t size, calculated_pitch;
|
||||
if (!SDL_CalculateYUVSize(texture->format, texture->w, texture->h, &size, &calculated_pitch)) {
|
||||
return false;
|
||||
}
|
||||
texturedata->pitch = (int)calculated_pitch;
|
||||
texturedata->pixels = (Uint8 *)SDL_malloc(size);
|
||||
if (!texturedata->pixels) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "../SDL_d3dmath.h"
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
#include "../../video/SDL_yuv_c.h"
|
||||
|
||||
#include <d3d11_1.h>
|
||||
#ifdef HAVE_DXGI1_5_H
|
||||
@@ -1608,8 +1609,9 @@ static bool D3D11_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
int Ypitch = srcPitch;
|
||||
int UVpitch = ((Ypitch + 1 * SDL_BYTESPERPIXEL(texture->format)) / 2);
|
||||
const int bpp = SDL_BYTESPERPIXEL(texture->format);
|
||||
const int Ypitch = srcPitch;
|
||||
const int UVpitch = ((Ypitch / bpp + 1) / 2) * bpp;
|
||||
const Uint8 *plane0 = (const Uint8 *)srcPixels;
|
||||
const Uint8 *plane1 = plane0 + rect->h * Ypitch;
|
||||
const Uint8 *plane2 = plane1 + ((rect->h + 1) / 2) * UVpitch;
|
||||
@@ -1795,8 +1797,12 @@ static bool D3D11_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
if (textureData->yuv || textureData->nv12) {
|
||||
// It's more efficient to upload directly...
|
||||
if (!textureData->pixels) {
|
||||
textureData->pitch = texture->w;
|
||||
textureData->pixels = (Uint8 *)SDL_malloc((texture->h * textureData->pitch * 3) / 2);
|
||||
size_t size, calculated_calculated_pitch;
|
||||
if (!SDL_CalculateYUVSize(texture->format, texture->w, texture->h, &size, &calculated_calculated_pitch)) {
|
||||
return false;
|
||||
}
|
||||
textureData->pitch = (int)calculated_calculated_pitch;
|
||||
textureData->pixels = (Uint8 *)SDL_malloc(size);
|
||||
if (!textureData->pixels) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ extern "C" {
|
||||
|
||||
// This must be included here as the function definitions in SDL_pixels.c/_c.h are C, not C++
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
#include "../../video/SDL_yuv_c.h"
|
||||
|
||||
/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when
|
||||
!!! FIXME: textures are needed. */
|
||||
@@ -2079,16 +2080,17 @@ static bool D3D12_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
}
|
||||
} else {
|
||||
const int bpp = SDL_BYTESPERPIXEL(texture->format);
|
||||
const int UVpitch = ((srcPitch / bpp + 1) / 2) * bpp;
|
||||
|
||||
// Skip to the correct offset into the next texture
|
||||
srcPixels = (const void *)((const Uint8 *)srcPixels + rect->h * srcPitch);
|
||||
if (!D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, 0, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1 * bpp) / 2, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateV : &textureData->mainResourceStateU)) {
|
||||
if (!D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, 0, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, UVpitch, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateV : &textureData->mainResourceStateU)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip to the correct offset into the next texture
|
||||
srcPixels = (const void *)((const Uint8 *)srcPixels + ((rect->h + 1) / 2) * ((srcPitch + 1 * bpp) / 2));
|
||||
if (!D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, 0, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1 * bpp) / 2, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateU : &textureData->mainResourceStateV)) {
|
||||
srcPixels = (const void *)((const Uint8 *)srcPixels + ((rect->h + 1) / 2) * UVpitch);
|
||||
if (!D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, 0, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, UVpitch, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateU : &textureData->mainResourceStateV)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2201,8 +2203,12 @@ static bool D3D12_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
if (textureData->yuv || textureData->nv12) {
|
||||
// It's more efficient to upload directly...
|
||||
if (!textureData->pixels) {
|
||||
textureData->pitch = texture->w;
|
||||
textureData->pixels = (Uint8 *)SDL_malloc((texture->h * textureData->pitch * 3) / 2);
|
||||
size_t size, calculated_pitch;
|
||||
if (!SDL_CalculateYUVSize(texture->format, texture->w, texture->h, &size, &calculated_pitch)) {
|
||||
return false;
|
||||
}
|
||||
textureData->pitch = (int)calculated_pitch;
|
||||
textureData->pixels = (Uint8 *)SDL_malloc(size);
|
||||
if (!textureData->pixels) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "../../events/SDL_windowevents_c.h"
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
#include "../../video/SDL_sysvideo.h"
|
||||
#include "../../video/SDL_yuv_c.h"
|
||||
#include "../SDL_d3dmath.h"
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "SDL_gpu_util.h"
|
||||
@@ -321,25 +322,16 @@ static bool GPU_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_
|
||||
data->format = format;
|
||||
|
||||
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
||||
size_t size;
|
||||
data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
|
||||
size = (size_t)texture->h * data->pitch;
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_IYUV ||
|
||||
texture->format == SDL_PIXELFORMAT_I0FL) {
|
||||
// Need to add size for the U and V planes
|
||||
size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
|
||||
}
|
||||
if (texture->format == SDL_PIXELFORMAT_I444 ||
|
||||
texture->format == SDL_PIXELFORMAT_I4FL) {
|
||||
// Need to add size for the U and V planes
|
||||
size += 2 * texture->h * data->pitch;
|
||||
}
|
||||
if (texture->format == SDL_PIXELFORMAT_NV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_NV21 ||
|
||||
texture->format == SDL_PIXELFORMAT_P010) {
|
||||
// Need to add size for the U/V plane
|
||||
size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
|
||||
size_t size, pitch;
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
|
||||
if (!SDL_CalculateYUVSize(texture->format, texture->w, texture->h, &size, &pitch)) {
|
||||
SDL_free(data);
|
||||
return false;
|
||||
}
|
||||
data->pitch = (int)pitch;
|
||||
} else {
|
||||
data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
|
||||
size = (size_t)texture->h * data->pitch;
|
||||
}
|
||||
data->pixels = SDL_calloc(1, size);
|
||||
if (!data->pixels) {
|
||||
@@ -584,8 +576,8 @@ static bool GPU_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, cons
|
||||
retval &= GPU_UpdateTextureInternal(renderdata, cpass, data->textureU, bpp, rect->x, rect->y, rect->w, rect->h, Uplane, pitch);
|
||||
retval &= GPU_UpdateTextureInternal(renderdata, cpass, data->textureV, bpp, rect->x, rect->y, rect->w, rect->h, Vplane, pitch);
|
||||
} else {
|
||||
int Ypitch = pitch;
|
||||
int UVpitch = ((Ypitch + 1 * SDL_BYTESPERPIXEL(texture->format)) / 2);
|
||||
const int Ypitch = pitch;
|
||||
const int UVpitch = ((Ypitch / bpp + 1) / 2) * bpp;
|
||||
const Uint8 *Yplane = (const Uint8 *)pixels;
|
||||
const Uint8 *Uplane = Yplane + rect->h * Ypitch;
|
||||
const Uint8 *Vplane = Uplane + ((rect->h + 1) / 2) * UVpitch;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
#include "../../video/SDL_yuv_c.h"
|
||||
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
#import <Metal/Metal.h>
|
||||
@@ -1003,13 +1004,14 @@ static bool METAL_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
// YV12 stores V before U, so the plane order is swapped for it.
|
||||
id<MTLTexture> firstplane = texture->format == SDL_PIXELFORMAT_YV12 ? texturedata.mtltextureV : texturedata.mtltextureU;
|
||||
id<MTLTexture> secondplane = texture->format == SDL_PIXELFORMAT_YV12 ? texturedata.mtltextureU : texturedata.mtltextureV;
|
||||
const int bpp = SDL_BYTESPERPIXEL(texture->format);
|
||||
int UVpitch;
|
||||
SDL_Rect UVrect;
|
||||
if (texture->format == SDL_PIXELFORMAT_I444 || texture->format == SDL_PIXELFORMAT_I4FL) {
|
||||
UVpitch = pitch;
|
||||
UVrect = *rect;
|
||||
} else {
|
||||
UVpitch = (pitch + 1 * SDL_BYTESPERPIXEL(texture->format)) / 2;
|
||||
UVpitch = ((pitch / bpp + 1) / 2) * bpp;
|
||||
UVrect.x = rect->x / 2;
|
||||
UVrect.y = rect->y / 2;
|
||||
UVrect.w = (rect->w + 1) / 2;
|
||||
@@ -1030,8 +1032,9 @@ static bool METAL_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
}
|
||||
|
||||
if (texturedata.nv12) {
|
||||
const int bpp = SDL_BYTESPERPIXEL(texture->format);
|
||||
const int UVpitch = ((pitch / bpp + 1) / 2) * 2 * bpp;
|
||||
SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 };
|
||||
int UVpitch = 2 * ((pitch + 1) / 2);
|
||||
|
||||
// Skip to the correct offset into the next texture
|
||||
pixels = (const void *)((const Uint8 *)pixels + rect->h * pitch);
|
||||
@@ -1121,24 +1124,26 @@ static bool METAL_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
@autoreleasepool {
|
||||
SDL3METAL_RenderData *data = (__bridge SDL3METAL_RenderData *)renderer->internal;
|
||||
SDL3METAL_TextureData *texturedata = (__bridge SDL3METAL_TextureData *)texture->internal;
|
||||
int buffersize = 0;
|
||||
id<MTLBuffer> lockedbuffer = nil;
|
||||
size_t size, calculated_pitch;
|
||||
|
||||
if (rect->w <= 0 || rect->h <= 0) {
|
||||
return SDL_SetError("Invalid rectangle dimensions for LockTexture.");
|
||||
}
|
||||
|
||||
*pitch = SDL_BYTESPERPIXEL(texture->format) * rect->w;
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (texturedata.yuv || texturedata.nv12) {
|
||||
buffersize = ((*pitch) * rect->h) + (2 * (*pitch + 1) / 2) * ((rect->h + 1) / 2);
|
||||
if (!SDL_CalculateYUVSize(texture->format, rect->w, rect->h, &size, &calculated_pitch)) {
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
buffersize = (*pitch) * rect->h;
|
||||
calculated_pitch = SDL_BYTESPERPIXEL(texture->format) * rect->w;
|
||||
size = rect->h * calculated_pitch;
|
||||
}
|
||||
|
||||
lockedbuffer = [data.mtldevice newBufferWithLength:buffersize options:MTLResourceStorageModeShared];
|
||||
lockedbuffer = [data.mtldevice newBufferWithLength:size options:MTLResourceStorageModeShared];
|
||||
if (lockedbuffer == nil) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -1146,6 +1151,7 @@ static bool METAL_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
texturedata.lockedrect = *rect;
|
||||
texturedata.lockedbuffer = lockedbuffer;
|
||||
*pixels = [lockedbuffer contents];
|
||||
*pitch = (int)calculated_pitch;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1192,7 +1198,8 @@ static void METAL_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
// YV12 stores V before U, so the plane order is swapped for it.
|
||||
id<MTLTexture> firstplane = texture->format == SDL_PIXELFORMAT_YV12 ? texturedata.mtltextureV : texturedata.mtltextureU;
|
||||
id<MTLTexture> secondplane = texture->format == SDL_PIXELFORMAT_YV12 ? texturedata.mtltextureU : texturedata.mtltextureV;
|
||||
int UVpitch = (pitch + 1) / 2;
|
||||
const int bpp = SDL_BYTESPERPIXEL(texture->format);
|
||||
const int UVpitch = ((pitch / bpp + 1) / 2) * bpp;
|
||||
|
||||
[blitcmd copyFromBuffer:texturedata.lockedbuffer
|
||||
sourceOffset:rect.h * pitch
|
||||
@@ -1216,7 +1223,8 @@ static void METAL_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
}
|
||||
|
||||
if (texturedata.nv12) {
|
||||
int UVpitch = 2 * ((pitch + 1) / 2);
|
||||
const int bpp = SDL_BYTESPERPIXEL(texture->format);
|
||||
const int UVpitch = ((pitch / bpp + 1) / 2) * 2 * bpp;
|
||||
|
||||
[blitcmd copyFromBuffer:texturedata.lockedbuffer
|
||||
sourceOffset:rect.h * pitch
|
||||
|
||||
@@ -166,8 +166,9 @@ bool SDL_CalculateYUVSize(SDL_PixelFormat format, int w, int h, size_t *size, si
|
||||
|
||||
case SDL_PIXELFORMAT_NV12: /**< Planar mode: Y + U/V interleaved (2 planes) */
|
||||
case SDL_PIXELFORMAT_NV21: /**< Planar mode: Y + V/U interleaved (2 planes) */
|
||||
case SDL_PIXELFORMAT_P010: /**< Planar mode: Y + U/V interleaved, 10 bit (2 planes) */
|
||||
if (pitch) {
|
||||
*pitch = w;
|
||||
*pitch = w * SDL_BYTESPERPIXEL(format);
|
||||
}
|
||||
|
||||
if (size) {
|
||||
@@ -237,7 +238,7 @@ static bool GetYUVPlanes(int width, int height, SDL_PixelFormat format, const vo
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
pitches[0] = yuv_pitch;
|
||||
pitches[1] = (pitches[0] + 1 * SDL_BYTESPERPIXEL(format)) / 2;
|
||||
pitches[1] = ((pitches[0] / SDL_BYTESPERPIXEL(format) + 1) / 2) * SDL_BYTESPERPIXEL(format);
|
||||
pitches[2] = pitches[1];
|
||||
planes[0] = (const Uint8 *)yuv;
|
||||
planes[1] = planes[0] + pitches[0] * height;
|
||||
@@ -1353,46 +1354,42 @@ static bool SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, SDL_PixelFo
|
||||
}
|
||||
|
||||
if (IsPlanar2x2Format(format)) {
|
||||
const int bpp = SDL_BYTESPERPIXEL(format);
|
||||
|
||||
// Y plane
|
||||
const size_t length = width * bpp;
|
||||
for (i = height; i--;) {
|
||||
SDL_memcpy(dst, src, width);
|
||||
SDL_memcpy(dst, src, length);
|
||||
src = (const Uint8 *)src + src_pitch;
|
||||
dst = (Uint8 *)dst + dst_pitch;
|
||||
}
|
||||
|
||||
if (format == SDL_PIXELFORMAT_YV12 || format == SDL_PIXELFORMAT_IYUV) {
|
||||
if (format == SDL_PIXELFORMAT_YV12 ||
|
||||
format == SDL_PIXELFORMAT_IYUV ||
|
||||
format == SDL_PIXELFORMAT_I0FL) {
|
||||
// U and V planes are a quarter the size of the Y plane, rounded up
|
||||
width = (width + 1) / 2;
|
||||
width = ((width + 1) / 2) * bpp;
|
||||
height = (height + 1) / 2;
|
||||
src_pitch = (src_pitch + 1) / 2;
|
||||
dst_pitch = (dst_pitch + 1) / 2;
|
||||
src_pitch = ((src_pitch / bpp + 1) / 2) * bpp;
|
||||
dst_pitch = ((dst_pitch / bpp + 1) / 2) * bpp;
|
||||
for (i = height * 2; i--;) {
|
||||
SDL_memcpy(dst, src, width);
|
||||
src = (const Uint8 *)src + src_pitch;
|
||||
dst = (Uint8 *)dst + dst_pitch;
|
||||
}
|
||||
} else if (format == SDL_PIXELFORMAT_NV12 || format == SDL_PIXELFORMAT_NV21) {
|
||||
// U/V plane is half the height of the Y plane, rounded up
|
||||
} else if (format == SDL_PIXELFORMAT_NV12 ||
|
||||
format == SDL_PIXELFORMAT_NV21 ||
|
||||
format == SDL_PIXELFORMAT_P010) {
|
||||
// U/V plane is half the height of the Y plane, rounded up, with packed CrCb
|
||||
width = ((width + 1) / 2) * 2 * bpp;
|
||||
height = (height + 1) / 2;
|
||||
width = ((width + 1) / 2) * 2;
|
||||
src_pitch = ((src_pitch + 1) / 2) * 2;
|
||||
dst_pitch = ((dst_pitch + 1) / 2) * 2;
|
||||
src_pitch = ((src_pitch / bpp + 1) / 2) * 2 * bpp;
|
||||
dst_pitch = ((dst_pitch / bpp + 1) / 2) * 2 * bpp;
|
||||
for (i = height; i--;) {
|
||||
SDL_memcpy(dst, src, width);
|
||||
src = (const Uint8 *)src + src_pitch;
|
||||
dst = (Uint8 *)dst + dst_pitch;
|
||||
}
|
||||
} else if (format == SDL_PIXELFORMAT_P010) {
|
||||
// U/V plane is half the height of the Y plane, rounded up
|
||||
height = (height + 1) / 2;
|
||||
width = ((width + 1) / 2) * 2;
|
||||
src_pitch = ((src_pitch + 1) / 2) * 2;
|
||||
dst_pitch = ((dst_pitch + 1) / 2) * 2;
|
||||
for (i = height; i--;) {
|
||||
SDL_memcpy(dst, src, width * sizeof(Uint16));
|
||||
src = (const Uint8 *)src + src_pitch;
|
||||
dst = (Uint8 *)dst + dst_pitch;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -416,15 +416,16 @@ static bool create_textures(SDL_Renderer *renderer, SDL_Surface *original, SDL_P
|
||||
goto done;
|
||||
}
|
||||
if (planar && (yuv_format == SDL_PIXELFORMAT_YV12 || yuv_format == SDL_PIXELFORMAT_IYUV || yuv_format == SDL_PIXELFORMAT_I0FL)) {
|
||||
const int bpp = SDL_BYTESPERPIXEL(yuv_format);
|
||||
const int Yrows = original->h;
|
||||
const int UVrows = ((original->h + 1) / 2);
|
||||
const int src_Ypitch = pitch;
|
||||
const int src_UVpitch = ((pitch + 1 * SDL_BYTESPERPIXEL(yuv_format)) / 2);
|
||||
const int src_UVpitch = ((pitch / bpp + 1) / 2) * bpp;
|
||||
const Uint8 *src_plane0 = (const Uint8 *)raw_yuv;
|
||||
const Uint8 *src_plane1 = src_plane0 + Yrows * src_Ypitch;
|
||||
const Uint8 *src_plane2 = src_plane1 + UVrows * src_UVpitch;
|
||||
const int Ypitch = pitch + 37;
|
||||
const int UVpitch = ((Ypitch + 1 * SDL_BYTESPERPIXEL(yuv_format)) / 2);
|
||||
const int UVpitch = ((Ypitch / bpp + 1) / 2) * bpp;
|
||||
Uint8 *plane0 = (Uint8 *)SDL_calloc(1, Yrows * Ypitch);
|
||||
Uint8 *plane1 = (Uint8 *)SDL_calloc(1, UVrows * UVpitch);
|
||||
Uint8 *plane2 = (Uint8 *)SDL_calloc(1, UVrows * UVpitch);
|
||||
|
||||
Reference in New Issue
Block a user