summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2018-11-22 10:18:50 +0100
committerWim Taymans <wtaymans@redhat.com>2018-11-22 10:18:50 +0100
commit16b6a51b789b9d714418087f0797d29fb7b86c60 (patch)
tree7a36da88ba3513ae35d6761d275297a19f722f06
parent1ea84b2869d5506851ee4f52c98e16d14333b46d (diff)
examples: add video crop example
Add support for video crop metadata in video-play and draw only the cropped areas. Add support for video crop in video-src and make it generate cropping regions that grow and shrink dynamically.
-rw-r--r--src/examples/meson.build2
-rw-r--r--src/examples/video-play.c28
-rw-r--r--src/examples/video-src.c33
3 files changed, 55 insertions, 8 deletions
diff --git a/src/examples/meson.build b/src/examples/meson.build
index 4890f68e..37b3d4ff 100644
--- a/src/examples/meson.build
+++ b/src/examples/meson.build
@@ -1,7 +1,7 @@
executable('video-src',
'video-src.c',
install: false,
- dependencies : [pipewire_dep],
+ dependencies : [pipewire_dep, mathlib],
)
executable('export-source',
'export-source.c',
diff --git a/src/examples/video-play.c b/src/examples/video-play.c
index b259a86b..287c2c4d 100644
--- a/src/examples/video-play.c
+++ b/src/examples/video-play.c
@@ -73,6 +73,7 @@ struct data {
int32_t stride;
int counter;
+ SDL_Rect rect;
};
static void handle_events(struct data *data)
@@ -96,6 +97,7 @@ on_stream_process(void *_data)
struct spa_buffer *b;
void *sdata, *ddata;
int sstride, dstride, ostride;
+ struct spa_meta_video_crop *mc;
uint32_t i;
uint8_t *src, *dst;
@@ -114,6 +116,17 @@ on_stream_process(void *_data)
fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError());
goto done;
}
+ if ((mc = spa_buffer_find_meta(b, data->t->meta.VideoCrop))) {
+ if (data->rect.x != mc->x ||
+ data->rect.y != mc->y ||
+ data->rect.w != mc->width ||
+ data->rect.h != mc->height) {
+ data->rect.x = mc->x;
+ data->rect.y = mc->y;
+ data->rect.w = mc->width;
+ data->rect.h = mc->height;
+ }
+ }
sstride = b->datas[0].chunk->stride;
ostride = SPA_MIN(sstride, dstride);
@@ -127,7 +140,7 @@ on_stream_process(void *_data)
SDL_UnlockTexture(data->texture);
SDL_RenderClear(data->renderer);
- SDL_RenderCopy(data->renderer, data->texture, NULL, NULL);
+ SDL_RenderCopy(data->renderer, data->texture, &data->rect, NULL);
SDL_RenderPresent(data->renderer);
done:
@@ -226,7 +239,7 @@ on_stream_format_changed(void *_data, const struct spa_pod *format)
struct pw_type *t = data->t;
uint8_t params_buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
- const struct spa_pod *params[2];
+ const struct spa_pod *params[3];
Uint32 sdl_format;
void *d;
@@ -254,6 +267,11 @@ on_stream_format_changed(void *_data, const struct spa_pod *format)
SDL_LockTexture(data->texture, NULL, &d, &data->stride);
SDL_UnlockTexture(data->texture);
+ data->rect.x = 0;
+ data->rect.y = 0;
+ data->rect.w = data->format.size.width;
+ data->rect.h = data->format.size.height;
+
params[0] = spa_pod_builder_object(&b,
t->param.idBuffers, t->param_buffers.Buffers,
":", t->param_buffers.size, "i", data->stride * data->format.size.height,
@@ -266,8 +284,12 @@ on_stream_format_changed(void *_data, const struct spa_pod *format)
t->param.idMeta, t->param_meta.Meta,
":", t->param_meta.type, "I", t->meta.Header,
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
+ params[2] = spa_pod_builder_object(&b,
+ t->param.idMeta, t->param_meta.Meta,
+ ":", t->param_meta.type, "I", t->meta.VideoCrop,
+ ":", t->param_meta.size, "i", sizeof(struct spa_meta_video_crop));
- pw_stream_finish_format(stream, 0, params, 2);
+ pw_stream_finish_format(stream, 0, params, 3);
}
static const struct pw_stream_events stream_events = {
diff --git a/src/examples/video-src.c b/src/examples/video-src.c
index 5960bd88..db508a59 100644
--- a/src/examples/video-src.c
+++ b/src/examples/video-src.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <errno.h>
#include <time.h>
+#include <math.h>
#include <sys/mman.h>
#include <spa/support/type-map.h>
@@ -44,7 +45,12 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
spa_type_video_format_map(map, &type->video_format);
}
-#define BPP 3
+#define BPP 3
+#define WIDTH 320
+#define HEIGHT 200
+#define CROP 8
+
+#define M_PI_M2 ( M_PI + M_PI )
struct data {
struct type type;
@@ -65,6 +71,8 @@ struct data {
int counter;
uint32_t seq;
+ double crop;
+ double accumulator;
};
static void on_timeout(void *userdata, uint64_t expirations)
@@ -73,6 +81,7 @@ static void on_timeout(void *userdata, uint64_t expirations)
int i, j;
uint8_t *p;
struct spa_meta_header *h;
+ struct spa_meta_video_crop *mc;
struct pw_buffer *buf;
struct spa_buffer *b;
@@ -97,6 +106,18 @@ static void on_timeout(void *userdata, uint64_t expirations)
h->seq = data->seq++;
h->dts_offset = 0;
}
+ if ((mc = spa_buffer_find_meta(b, data->t->meta.VideoCrop))) {
+ mc->x = data->crop;
+ mc->y = data->crop;
+ mc->width = WIDTH - data->crop*2;
+ mc->height = HEIGHT - data->crop*2;
+
+ data->accumulator += M_PI_M2 / 50.0;
+ if (data->accumulator >= M_PI_M2)
+ data->accumulator -= M_PI_M2;
+
+ data->crop = (sin(data->accumulator) + 1.0) * 32.0;
+ }
for (i = 0; i < data->format.size.height; i++) {
for (j = 0; j < data->format.size.width * BPP; j++) {
@@ -148,7 +169,7 @@ on_stream_format_changed(void *_data, const struct spa_pod *format)
struct pw_type *t = data->t;
uint8_t params_buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
- const struct spa_pod *params[2];
+ const struct spa_pod *params[3];
if (format == NULL) {
pw_stream_finish_format(stream, 0, NULL, 0);
@@ -170,8 +191,12 @@ on_stream_format_changed(void *_data, const struct spa_pod *format)
t->param.idMeta, t->param_meta.Meta,
":", t->param_meta.type, "I", t->meta.Header,
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
+ params[2] = spa_pod_builder_object(&b,
+ t->param.idMeta, t->param_meta.Meta,
+ ":", t->param_meta.type, "I", t->meta.VideoCrop,
+ ":", t->param_meta.size, "i", sizeof(struct spa_meta_video_crop));
- pw_stream_finish_format(stream, 0, params, 2);
+ pw_stream_finish_format(stream, 0, params, 3);
}
static const struct pw_stream_events stream_events = {
@@ -214,7 +239,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
"I", data->type.media_type.video,
"I", data->type.media_subtype.raw,
":", data->type.format_video.format, "I", data->type.video_format.RGB,
- ":", data->type.format_video.size, "Rru", &SPA_RECTANGLE(320, 240),
+ ":", data->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT),
SPA_POD_PROP_MIN_MAX(&SPA_RECTANGLE(1, 1),
&SPA_RECTANGLE(4096, 4096)),
":", data->type.format_video.framerate, "F", &SPA_FRACTION(25, 1));