mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-02-11 04:27:56 -05:00
examples: Make fixate examples start inactive
The actual formats are sent just before activating. This is done in preparation for supporting device ID negotiation.
This commit is contained in:
parent
58b958860e
commit
fc5b43a0b0
2 changed files with 130 additions and 19 deletions
|
|
@ -18,6 +18,7 @@
|
|||
#include <spa/param/video/format-utils.h>
|
||||
#include <spa/param/props.h>
|
||||
#include <spa/debug/format.h>
|
||||
#include <spa/debug/pod.h>
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
|
|
@ -68,8 +69,12 @@ struct data {
|
|||
struct modifier_info mod_info[2];
|
||||
|
||||
int counter;
|
||||
|
||||
bool capabilities_known;
|
||||
};
|
||||
|
||||
static int build_formats(struct data *data, struct spa_pod_builder *b, const struct spa_pod **params);
|
||||
|
||||
static struct pw_version parse_pw_version(const char* version) {
|
||||
struct pw_version pw_version;
|
||||
sscanf(version, "%d.%d.%d", &pw_version.major, &pw_version.minor,
|
||||
|
|
@ -278,6 +283,34 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_tag_changed(struct data *data, const struct spa_pod *param)
|
||||
{
|
||||
struct pw_stream *stream = data->stream;
|
||||
|
||||
printf("tag param changed: \n");
|
||||
spa_debug_pod(4, NULL, param);
|
||||
|
||||
if (!data->capabilities_known) {
|
||||
const struct spa_pod *params[2];
|
||||
uint32_t n_params = 0;
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
|
||||
data->capabilities_known = true;
|
||||
|
||||
/* build the extra parameters to connect with. To connect, we can provide
|
||||
* a list of supported formats. We use a builder that writes the param
|
||||
* object to the stack. */
|
||||
printf("supported formats:\n");
|
||||
n_params = build_formats(data, &b, params);
|
||||
pw_stream_update_params(data->stream, params, n_params);
|
||||
|
||||
printf("activating stream\n");
|
||||
pw_stream_set_active(stream, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Be notified when the stream format param changes.
|
||||
*
|
||||
* We are now supposed to call pw_stream_finish_format() with success or
|
||||
|
|
@ -357,6 +390,9 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
|
|||
return;
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_Tag:
|
||||
on_stream_tag_changed(data, param);
|
||||
break;
|
||||
case SPA_PARAM_Format:
|
||||
on_stream_format_changed(data, param);
|
||||
break;
|
||||
|
|
@ -421,8 +457,10 @@ int main(int argc, char *argv[])
|
|||
const struct spa_pod *params[2];
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
struct spa_pod_frame f;
|
||||
struct pw_properties *props;
|
||||
int res, n_params;
|
||||
int res, n_params = 0;
|
||||
SDL_RendererInfo info;
|
||||
|
||||
pw_init(&argc, &argv);
|
||||
|
||||
|
|
@ -472,11 +510,28 @@ int main(int argc, char *argv[])
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* build the extra parameters to connect with. To connect, we can provide
|
||||
* a list of supported formats. We use a builder that writes the param
|
||||
* object to the stack. */
|
||||
printf("supported formats:\n");
|
||||
n_params = build_formats(&data, &b, params);
|
||||
SDL_GetRendererInfo(data.renderer, &info);
|
||||
|
||||
/* Push bare minimum video format to inactive stream, and wait for
|
||||
* sending actual format until capability discovery is done. */
|
||||
spa_pod_builder_push_object(&b, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
|
||||
spa_pod_builder_add(&b, SPA_FORMAT_mediaType,
|
||||
SPA_POD_Id (SPA_MEDIA_TYPE_video),
|
||||
0);
|
||||
spa_pod_builder_add(&b, SPA_FORMAT_mediaSubtype,
|
||||
SPA_POD_Id (SPA_MEDIA_SUBTYPE_raw),
|
||||
0);
|
||||
spa_pod_builder_add(&b, SPA_FORMAT_VIDEO_format,
|
||||
SPA_POD_Id(SPA_VIDEO_FORMAT_RGBA),
|
||||
0);
|
||||
spa_pod_builder_add(&b, SPA_FORMAT_VIDEO_size,
|
||||
SPA_POD_CHOICE_RANGE_Rectangle(
|
||||
&SPA_RECTANGLE(WIDTH, HEIGHT),
|
||||
&SPA_RECTANGLE(1,1),
|
||||
&SPA_RECTANGLE(info.max_texture_width,
|
||||
info.max_texture_height)),
|
||||
0);
|
||||
params[n_params++] = spa_pod_builder_pop(&b, &f);
|
||||
|
||||
/* now connect the stream, we need a direction (input/output),
|
||||
* an optional target node to connect to, some flags and parameters
|
||||
|
|
@ -485,6 +540,7 @@ int main(int argc, char *argv[])
|
|||
PW_DIRECTION_INPUT,
|
||||
PW_ID_ANY,
|
||||
PW_STREAM_FLAG_AUTOCONNECT | /* try to automatically connect this stream */
|
||||
PW_STREAM_FLAG_INACTIVE | /* set active after capability discovery */
|
||||
PW_STREAM_FLAG_MAP_BUFFERS, /* mmap the buffer data for us */
|
||||
params, n_params)) /* extra parameters, see above */ < 0) {
|
||||
fprintf(stderr, "can't connect: %s\n", spa_strerror(res));
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <spa/param/tag-utils.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
#include <spa/debug/format.h>
|
||||
#include <spa/debug/pod.h>
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
|
|
@ -50,6 +52,8 @@ struct data {
|
|||
|
||||
double crop;
|
||||
double accumulator;
|
||||
|
||||
bool capabilities_known;
|
||||
};
|
||||
|
||||
static void draw_elipse(uint32_t *dst, int width, int height, uint32_t color)
|
||||
|
|
@ -363,6 +367,43 @@ static void on_stream_remove_buffer(void *_data, struct pw_buffer *buffer)
|
|||
close(d[0].fd);
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_tag_changed(struct data *data, const struct spa_pod *param)
|
||||
{
|
||||
struct pw_stream *stream = data->stream;
|
||||
|
||||
printf("tag param changed: \n");
|
||||
spa_debug_pod(4, NULL, param);
|
||||
|
||||
if (!data->capabilities_known) {
|
||||
const struct spa_pod *params[2];
|
||||
uint32_t n_params = 0;
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
|
||||
data->capabilities_known = true;
|
||||
|
||||
/* build the extra parameter for the connection. Here we make an
|
||||
* EnumFormat parameter which lists the possible formats we can provide.
|
||||
* The server will select a format that matches and informs us about this
|
||||
* in the stream param_changed event.
|
||||
*/
|
||||
params[n_params++] = build_format(&b, SPA_VIDEO_FORMAT_RGBA,
|
||||
supported_modifiers, SPA_N_ELEMENTS(supported_modifiers));
|
||||
params[n_params++] = build_format(&b, SPA_VIDEO_FORMAT_RGBA, NULL, 0);
|
||||
|
||||
printf("announcing starting EnumFormats\n");
|
||||
for (unsigned int i=0; i < n_params; i++) {
|
||||
spa_debug_format(4, NULL, params[i]);
|
||||
}
|
||||
|
||||
pw_stream_update_params(data->stream, params, n_params);
|
||||
|
||||
printf("activating stream\n");
|
||||
pw_stream_set_active(stream, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Be notified when the stream format param changes.
|
||||
*
|
||||
* We are now supposed to call pw_stream_update_params() with success or
|
||||
|
|
@ -390,6 +431,9 @@ on_stream_format_changed(struct data *data, const struct spa_pod *param)
|
|||
|
||||
data->stride = SPA_ROUND_UP_N(data->format.size.width * BPP, 4);
|
||||
|
||||
if (data->stride == 0)
|
||||
return;
|
||||
|
||||
const struct spa_pod_prop *prop_modifier;
|
||||
// check if client supports modifier
|
||||
if ((prop_modifier = spa_pod_find_prop(param, NULL, SPA_FORMAT_VIDEO_modifier)) == NULL) {
|
||||
|
|
@ -479,6 +523,9 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
|
|||
return;
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_Tag:
|
||||
on_stream_tag_changed(data, param);
|
||||
break;
|
||||
case SPA_PARAM_Format:
|
||||
on_stream_format_changed(data, param);
|
||||
break;
|
||||
|
|
@ -507,6 +554,7 @@ int main(int argc, char *argv[])
|
|||
uint32_t n_params = 0;
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
struct spa_pod_frame f;
|
||||
|
||||
srand(32);
|
||||
|
||||
|
|
@ -550,19 +598,25 @@ int main(int argc, char *argv[])
|
|||
/* make a timer to schedule our frames */
|
||||
data.timer = pw_loop_add_timer(pw_thread_loop_get_loop(data.loop), on_timeout, &data);
|
||||
|
||||
/* build the extra parameter for the connection. Here we make an
|
||||
* EnumFormat parameter which lists the possible formats we can provide.
|
||||
* The server will select a format that matches and informs us about this
|
||||
* in the stream param_changed event.
|
||||
*/
|
||||
params[n_params++] = build_format(&b, SPA_VIDEO_FORMAT_RGBA,
|
||||
supported_modifiers, SPA_N_ELEMENTS(supported_modifiers));
|
||||
params[n_params++] = build_format(&b, SPA_VIDEO_FORMAT_RGBA, NULL, 0);
|
||||
|
||||
printf("announcing starting EnumFormats\n");
|
||||
for (unsigned int i=0; i < 2; i++) {
|
||||
spa_debug_format(4, NULL, params[i]);
|
||||
}
|
||||
/* Push bare minimum video format to inactive stream, and wait for
|
||||
* sending actual format until capability discovery is done. */
|
||||
spa_pod_builder_push_object(&b, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
|
||||
spa_pod_builder_add(&b, SPA_FORMAT_mediaType,
|
||||
SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
0);
|
||||
spa_pod_builder_add(&b, SPA_FORMAT_mediaSubtype,
|
||||
SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
0);
|
||||
spa_pod_builder_add(&b, SPA_FORMAT_VIDEO_format,
|
||||
SPA_POD_Id(SPA_VIDEO_FORMAT_RGBA),
|
||||
0);
|
||||
spa_pod_builder_add(&b, SPA_FORMAT_VIDEO_size,
|
||||
SPA_POD_CHOICE_RANGE_Rectangle(
|
||||
&SPA_RECTANGLE(320, 240),
|
||||
&SPA_RECTANGLE(1,1),
|
||||
&SPA_RECTANGLE(4096,4096)),
|
||||
0);
|
||||
params[n_params++] = spa_pod_builder_pop(&b, &f);
|
||||
|
||||
/* now connect the stream, we need a direction (input/output),
|
||||
* an optional target node to connect to, some flags and parameters.
|
||||
|
|
@ -575,6 +629,7 @@ int main(int argc, char *argv[])
|
|||
PW_DIRECTION_OUTPUT,
|
||||
PW_ID_ANY,
|
||||
PW_STREAM_FLAG_DRIVER |
|
||||
PW_STREAM_FLAG_INACTIVE |
|
||||
PW_STREAM_FLAG_ALLOC_BUFFERS,
|
||||
params, n_params);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue