Use the expected plane size when capturing Android camera frames
On the Samsung Galaxy A52 the camera plane size is (pitch * (h - 1) + w) instead of (pitch * h). This led to us copying off the end of the plane when uploading the texture, so we pad out to our expected size.
This commit is contained in:
parent
9955e1dc0d
commit
02e85a153f
1 changed files with 22 additions and 13 deletions
|
@ -327,31 +327,40 @@ static SDL_CameraFrameResult ANDROIDCAMERA_AcquireFrame(SDL_Camera *device, SDL_
|
||||||
num_planes--; // treat the interleaved planes as one.
|
num_planes--; // treat the interleaved planes as one.
|
||||||
}
|
}
|
||||||
|
|
||||||
// !!! FIXME: we have an open issue in SDL3 to allow SDL_Surface to support non-contiguous planar data, but we don't have it yet.
|
|
||||||
size_t buflen = 0;
|
size_t buflen = 0;
|
||||||
|
pAImage_getPlaneRowStride(image, 0, &frame->pitch);
|
||||||
for (int i = 0; (i < num_planes) && (i < 3); i++) {
|
for (int i = 0; (i < num_planes) && (i < 3); i++) {
|
||||||
uint8_t *data = NULL;
|
int32_t expected;
|
||||||
int32_t datalen = 0;
|
if (i == 0) {
|
||||||
pAImage_getPlaneData(image, i, &data, &datalen);
|
expected = frame->pitch * frame->h;
|
||||||
buflen += (int) datalen;
|
} else {
|
||||||
|
expected = frame->pitch * (frame->h + 1) / 2;
|
||||||
|
}
|
||||||
|
buflen += expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), buflen);
|
frame->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), buflen);
|
||||||
if (frame->pixels == NULL) {
|
if (frame->pixels == NULL) {
|
||||||
result = SDL_CAMERA_FRAME_ERROR;
|
result = SDL_CAMERA_FRAME_ERROR;
|
||||||
} else {
|
} else {
|
||||||
int32_t row_stride = 0;
|
|
||||||
Uint8 *dst = frame->pixels;
|
Uint8 *dst = frame->pixels;
|
||||||
pAImage_getPlaneRowStride(image, 0, &row_stride);
|
|
||||||
frame->pitch = (int) row_stride; // this is what SDL3 currently expects, probably incorrectly.
|
|
||||||
|
|
||||||
for (int i = 0; (i < num_planes) && (i < 3); i++) {
|
for (int i = 0; (i < num_planes) && (i < 3); i++) {
|
||||||
uint8_t *data = NULL;
|
uint8_t *data = NULL;
|
||||||
int32_t datalen = 0;
|
int32_t datalen = 0;
|
||||||
|
int32_t expected;
|
||||||
|
if (i == 0) {
|
||||||
|
expected = frame->pitch * frame->h;
|
||||||
|
} else {
|
||||||
|
expected = frame->pitch * (frame->h + 1) / 2;
|
||||||
|
}
|
||||||
pAImage_getPlaneData(image, i, &data, &datalen);
|
pAImage_getPlaneData(image, i, &data, &datalen);
|
||||||
const void *src = data;
|
|
||||||
SDL_memcpy(dst, src, datalen);
|
int32_t row_stride = 0;
|
||||||
dst += datalen;
|
pAImage_getPlaneRowStride(image, i, &row_stride);
|
||||||
|
SDL_assert(row_stride == frame->pitch);
|
||||||
|
SDL_memcpy(dst, data, SDL_min(expected, datalen));
|
||||||
|
dst += expected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,8 +640,8 @@ static void GatherCameraSpecs(const char *devid, CameraFormatAddData *add_data,
|
||||||
const int32_t *i32ptr = cfgentry.data.i32;
|
const int32_t *i32ptr = cfgentry.data.i32;
|
||||||
for (int i = 0; i < cfgentry.count; i++, i32ptr += 4) {
|
for (int i = 0; i < cfgentry.count; i++, i32ptr += 4) {
|
||||||
const int32_t fmt = i32ptr[0];
|
const int32_t fmt = i32ptr[0];
|
||||||
const int w = (int) i32ptr[1];
|
const int w = i32ptr[1];
|
||||||
const int h = (int) i32ptr[2];
|
const int h = i32ptr[2];
|
||||||
const int32_t type = i32ptr[3];
|
const int32_t type = i32ptr[3];
|
||||||
SDL_PixelFormat sdlfmt = SDL_PIXELFORMAT_UNKNOWN;
|
SDL_PixelFormat sdlfmt = SDL_PIXELFORMAT_UNKNOWN;
|
||||||
SDL_Colorspace colorspace = SDL_COLORSPACE_UNKNOWN;
|
SDL_Colorspace colorspace = SDL_COLORSPACE_UNKNOWN;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue