examples: add support for YUV data

This commit is contained in:
Wim Taymans 2020-07-31 11:44:20 +02:00
parent a5f85deabe
commit 6fd373ac83

View file

@ -66,6 +66,7 @@ struct data {
int counter; int counter;
SDL_Rect rect; SDL_Rect rect;
SDL_Rect cursor_rect; SDL_Rect cursor_rect;
bool is_yuv;
}; };
static void handle_events(struct data *data) static void handle_events(struct data *data)
@ -127,11 +128,6 @@ on_process(void *_data)
if ((sdata = buf->datas[0].data) == NULL) if ((sdata = buf->datas[0].data) == NULL)
goto done; goto done;
if (SDL_LockTexture(data->texture, NULL, &ddata, &dstride) < 0) {
fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError());
goto done;
}
/* get the videocrop metadata if any */ /* get the videocrop metadata if any */
if ((mc = spa_buffer_find_meta_data(buf, SPA_META_VideoCrop, sizeof(*mc))) && if ((mc = spa_buffer_find_meta_data(buf, SPA_META_VideoCrop, sizeof(*mc))) &&
spa_meta_region_is_valid(mc)) { spa_meta_region_is_valid(mc)) {
@ -184,33 +180,50 @@ on_process(void *_data)
} }
/* copy video image in texture */ /* copy video image in texture */
sstride = buf->datas[0].chunk->stride; if (data->is_yuv) {
ostride = SPA_MIN(sstride, dstride); sstride = data->stride;
SDL_UpdateYUVTexture(data->texture,
src = sdata; NULL,
dst = ddata; sdata,
sstride,
if (data->format.media_subtype == SPA_MEDIA_SUBTYPE_dsp) { SPA_MEMBER(sdata, sstride * data->size.height, void),
for (i = 0; i < data->size.height; i++) { sstride / 2,
struct pixel *p = (struct pixel *) src; SPA_MEMBER(sdata, 5 * (sstride * data->size.height) / 4, void),
for (j = 0; j < data->size.width; j++) { sstride / 2);
dst[j * 4 + 0] = SPA_CLAMP(p[j].r * 255.0f, 0, 255);
dst[j * 4 + 1] = SPA_CLAMP(p[j].g * 255.0f, 0, 255);
dst[j * 4 + 2] = SPA_CLAMP(p[j].b * 255.0f, 0, 255);
dst[j * 4 + 3] = SPA_CLAMP(p[j].a * 255.0f, 0, 255);
}
src += sstride;
dst += dstride;
}
} }
else { else {
for (i = 0; i < data->size.height; i++) { if (SDL_LockTexture(data->texture, NULL, &ddata, &dstride) < 0) {
memcpy(dst, src, ostride); fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError());
src += sstride; goto done;
dst += dstride;
} }
sstride = buf->datas[0].chunk->stride;
ostride = SPA_MIN(sstride, dstride);
src = sdata;
dst = ddata;
if (data->format.media_subtype == SPA_MEDIA_SUBTYPE_dsp) {
for (i = 0; i < data->size.height; i++) {
struct pixel *p = (struct pixel *) src;
for (j = 0; j < data->size.width; j++) {
dst[j * 4 + 0] = SPA_CLAMP(p[j].r * 255.0f, 0, 255);
dst[j * 4 + 1] = SPA_CLAMP(p[j].g * 255.0f, 0, 255);
dst[j * 4 + 2] = SPA_CLAMP(p[j].b * 255.0f, 0, 255);
dst[j * 4 + 3] = SPA_CLAMP(p[j].a * 255.0f, 0, 255);
}
src += sstride;
dst += dstride;
}
} else {
for (i = 0; i < data->size.height; i++) {
memcpy(dst, src, ostride);
src += sstride;
dst += dstride;
}
}
SDL_UnlockTexture(data->texture);
} }
SDL_UnlockTexture(data->texture);
SDL_RenderClear(data->renderer); SDL_RenderClear(data->renderer);
/* now render the video and then the cursor if any */ /* now render the video and then the cursor if any */
@ -275,7 +288,7 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
const struct spa_pod *params[5]; const struct spa_pod *params[5];
Uint32 sdl_format; Uint32 sdl_format;
void *d; void *d;
int32_t mult; int32_t mult, size;
/* NULL means to clear the format */ /* NULL means to clear the format */
if (param == NULL || id != SPA_PARAM_Format) if (param == NULL || id != SPA_PARAM_Format)
@ -326,6 +339,17 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
SDL_LockTexture(data->texture, NULL, &d, &data->stride); SDL_LockTexture(data->texture, NULL, &d, &data->stride);
SDL_UnlockTexture(data->texture); SDL_UnlockTexture(data->texture);
switch(sdl_format) {
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
size = (data->stride * data->size.height) * 3 / 2;
data->is_yuv = true;
break;
default:
size = data->stride * data->size.height;
break;
}
data->rect.x = 0; data->rect.x = 0;
data->rect.y = 0; data->rect.y = 0;
data->rect.w = data->size.width; data->rect.w = data->size.width;
@ -337,7 +361,7 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(8, 2, MAX_BUFFERS), SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(8, 2, MAX_BUFFERS),
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
SPA_PARAM_BUFFERS_size, SPA_POD_Int(data->stride * mult * data->size.height), SPA_PARAM_BUFFERS_size, SPA_POD_Int(size * mult),
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(data->stride * mult), SPA_PARAM_BUFFERS_stride, SPA_POD_Int(data->stride * mult),
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16)); SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));