command: make commands dynamic

Ensure format object type.
This commit is contained in:
Wim Taymans 2017-03-22 10:04:24 +01:00
parent 4d9f2c5161
commit c44a7c9735
36 changed files with 549 additions and 604 deletions

View file

@ -155,20 +155,17 @@ do_command (SpaLoop *loop,
{
SpaALSASink *this = user_data;
SpaResult res;
SpaNodeCommand *cmd = data;
SpaCommand *cmd = data;
switch (SPA_NODE_COMMAND_TYPE (cmd)) {
case SPA_NODE_COMMAND_START:
case SPA_NODE_COMMAND_PAUSE:
res = spa_node_port_send_command (&this->node,
SPA_DIRECTION_INPUT,
0,
cmd);
break;
default:
res = SPA_RESULT_NOT_IMPLEMENTED;
break;
if (SPA_COMMAND_TYPE (cmd) == this->uri.node_commands.Start ||
SPA_COMMAND_TYPE (cmd) == this->uri.node_commands.Pause) {
res = spa_node_port_send_command (&this->node,
SPA_DIRECTION_INPUT,
0,
cmd);
}
else
res = SPA_RESULT_NOT_IMPLEMENTED;
if (async) {
SpaNodeEventAsyncComplete ac = SPA_NODE_EVENT_ASYNC_COMPLETE_INIT (this->uri.node_events.AsyncComplete,
@ -184,8 +181,8 @@ do_command (SpaLoop *loop,
}
static SpaResult
spa_alsa_sink_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_alsa_sink_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaALSASink *this;
@ -194,34 +191,24 @@ spa_alsa_sink_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaALSASink, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start ||
SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
case SPA_NODE_COMMAND_START:
case SPA_NODE_COMMAND_PAUSE:
{
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
return spa_loop_invoke (this->data_loop,
do_command,
++this->seq,
SPA_POD_SIZE (command),
command,
this);
return spa_loop_invoke (this->data_loop,
do_command,
++this->seq,
SPA_POD_SIZE (command),
command,
this);
}
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
}
return SPA_RESULT_OK;
else
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
@ -325,18 +312,18 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_URI, 3, this->uri.audio_formats.S16,
this->uri.audio_formats.S16,
this->uri.audio_formats.S32),
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_URI, 3, this->uri.audio_formats.S16,
this->uri.audio_formats.S16,
this->uri.audio_formats.S32),
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break;
case 1:
spa_pod_builder_format (&b, &f[0],
this->uri.media_types.audio, this->uri.media_subtypes_audio.aac,
SPA_POD_TYPE_NONE);
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.audio, this->uri.media_subtypes_audio.aac,
SPA_POD_TYPE_NONE);
break;
default:
return SPA_RESULT_ENUM_END;
@ -622,7 +609,7 @@ static SpaResult
spa_alsa_sink_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
SpaALSASink *this;
SpaResult res;
@ -635,25 +622,19 @@ spa_alsa_sink_node_port_send_command (SpaNode *node,
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_PAUSE:
{
if (SPA_RESULT_IS_OK (res = spa_alsa_pause (this, false))) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
break;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
if (SPA_RESULT_IS_OK (res = spa_alsa_pause (this, false))) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
case SPA_NODE_COMMAND_START:
{
if (SPA_RESULT_IS_OK (res = spa_alsa_start (this, false))) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
break;
}
default:
res = SPA_RESULT_NOT_IMPLEMENTED;
break;
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
if (SPA_RESULT_IS_OK (res = spa_alsa_start (this, false))) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
}
else
res = SPA_RESULT_NOT_IMPLEMENTED;
return res;
}
@ -796,12 +777,15 @@ alsa_sink_init (const SpaHandleFactory *factory,
return SPA_RESULT_ERROR;
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
this->uri.format = spa_id_map_get_id (this->map, SPA_FORMAT_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_media_subtypes_audio_map (this->map, &this->uri.media_subtypes_audio);
spa_prop_audio_map (this->map, &this->uri.prop_audio);
spa_audio_formats_map (this->map, &this->uri.audio_formats);
spa_node_events_map (this->map, &this->uri.node_events);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = alsasink_node;
this->stream = SND_PCM_STREAM_PLAYBACK;

View file

@ -205,8 +205,8 @@ do_pause (SpaLoop *loop,
}
static SpaResult
spa_alsa_source_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_alsa_source_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaALSASource *this;
@ -215,47 +215,37 @@ spa_alsa_source_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaALSASource, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
case SPA_NODE_COMMAND_START:
{
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
return spa_loop_invoke (this->data_loop,
do_start,
++this->seq,
0,
NULL,
this);
}
case SPA_NODE_COMMAND_PAUSE:
{
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
return spa_loop_invoke (this->data_loop,
do_pause,
++this->seq,
0,
NULL,
this);
}
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
return spa_loop_invoke (this->data_loop,
do_start,
++this->seq,
0,
NULL,
this);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
return spa_loop_invoke (this->data_loop,
do_pause,
++this->seq,
0,
NULL,
this);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
@ -360,18 +350,18 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_URI, 3, this->uri.audio_formats.S16,
this->uri.audio_formats.S16,
this->uri.audio_formats.S32),
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_URI, 3, this->uri.audio_formats.S16,
this->uri.audio_formats.S16,
this->uri.audio_formats.S32),
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break;
case 1:
spa_pod_builder_format (&b, &f[0],
this->uri.media_types.audio, this->uri.media_subtypes_audio.aac,
SPA_POD_TYPE_NONE);
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.audio, this->uri.media_subtypes_audio.aac,
SPA_POD_TYPE_NONE);
default:
return SPA_RESULT_ENUM_END;
}
@ -679,7 +669,7 @@ static SpaResult
spa_alsa_source_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
SpaALSASource *this;
SpaResult res;
@ -692,25 +682,17 @@ spa_alsa_source_node_port_send_command (SpaNode *node,
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_PAUSE:
{
if (SPA_RESULT_IS_OK (res = spa_alsa_pause (this, false))) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
break;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
if (SPA_RESULT_IS_OK (res = spa_alsa_pause (this, false))) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
case SPA_NODE_COMMAND_START:
{
if (SPA_RESULT_IS_OK (res = spa_alsa_start (this, false))) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
break;
} else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
if (SPA_RESULT_IS_OK (res = spa_alsa_start (this, false))) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
default:
res = SPA_RESULT_NOT_IMPLEMENTED;
break;
}
} else
res = SPA_RESULT_NOT_IMPLEMENTED;
return res;
}
@ -862,6 +844,7 @@ alsa_source_init (const SpaHandleFactory *factory,
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
this->uri.format = spa_id_map_get_id (this->map, SPA_FORMAT_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
@ -869,6 +852,7 @@ alsa_source_init (const SpaHandleFactory *factory,
spa_prop_audio_map (this->map, &this->uri.prop_audio);
spa_audio_formats_map (this->map, &this->uri.audio_formats);
spa_node_events_map (this->map, &this->uri.node_events);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = alsasource_node;
this->clock = alsasource_clock;

View file

@ -29,6 +29,7 @@ extern "C" {
#include <asoundlib.h>
#include <spa/id-map.h>
#include <spa/clock.h>
#include <spa/log.h>
#include <spa/list.h>
#include <spa/node.h>
@ -62,12 +63,14 @@ struct _SpaALSABuffer {
typedef struct {
uint32_t node;
uint32_t clock;
uint32_t format;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaMediaSubtypesAudio media_subtypes_audio;
SpaPropAudio prop_audio;
SpaAudioFormats audio_formats;
SpaNodeEvents node_events;
SpaNodeCommands node_commands;
} URI;
struct _SpaALSAState {

View file

@ -58,6 +58,7 @@ typedef struct {
typedef struct {
uint32_t node;
SpaNodeCommands node_commands;
} URI;
struct _SpaAudioMixer {
@ -107,8 +108,8 @@ update_state (SpaAudioMixer *this, SpaNodeState state)
}
static SpaResult
spa_audiomixer_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_audiomixer_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaAudioMixer *this;
@ -117,24 +118,15 @@ spa_audiomixer_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaAudioMixer, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
case SPA_NODE_COMMAND_START:
update_state (this, SPA_NODE_STATE_STREAMING);
break;
case SPA_NODE_COMMAND_PAUSE:
update_state (this, SPA_NODE_STATE_PAUSED);
break;
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
@ -463,7 +455,7 @@ static SpaResult
spa_audiomixer_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@ -703,6 +695,7 @@ spa_audiomixer_init (const SpaHandleFactory *factory,
return SPA_RESULT_ERROR;
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = audiomixer_node;

View file

@ -24,6 +24,7 @@
#include <sys/timerfd.h>
#include <spa/id-map.h>
#include <spa/clock.h>
#include <spa/log.h>
#include <spa/loop.h>
#include <spa/node.h>
@ -39,11 +40,13 @@
typedef struct {
uint32_t node;
uint32_t clock;
uint32_t format;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropAudio prop_audio;
SpaAudioFormats audio_formats;
SpaNodeEvents node_events;
SpaNodeCommands node_commands;
} URI;
typedef struct _SpaAudioTestSrc SpaAudioTestSrc;
@ -300,8 +303,8 @@ update_state (SpaAudioTestSrc *this, SpaNodeState state)
}
static SpaResult
spa_audiotestsrc_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_audiotestsrc_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaAudioTestSrc *this;
@ -310,58 +313,47 @@ spa_audiotestsrc_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaAudioTestSrc, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
struct timespec now;
case SPA_NODE_COMMAND_START:
{
struct timespec now;
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (this->started)
return SPA_RESULT_OK;
if (this->started)
return SPA_RESULT_OK;
clock_gettime (CLOCK_MONOTONIC, &now);
if (this->props.live)
this->start_time = SPA_TIMESPEC_TO_TIME (&now);
else
this->start_time = 0;
this->sample_count = 0;
this->elapsed_time = 0;
clock_gettime (CLOCK_MONOTONIC, &now);
if (this->props.live)
this->start_time = SPA_TIMESPEC_TO_TIME (&now);
else
this->start_time = 0;
this->sample_count = 0;
this->elapsed_time = 0;
this->started = true;
set_timer (this, true);
update_state (this, SPA_NODE_STATE_STREAMING);
break;
}
case SPA_NODE_COMMAND_PAUSE:
{
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (!this->started)
return SPA_RESULT_OK;
this->started = false;
set_timer (this, false);
update_state (this, SPA_NODE_STATE_PAUSED);
break;
}
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
this->started = true;
set_timer (this, true);
update_state (this, SPA_NODE_STATE_STREAMING);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (!this->started)
return SPA_RESULT_OK;
this->started = false;
set_timer (this, false);
update_state (this, SPA_NODE_STATE_PAUSED);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
@ -471,13 +463,13 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_URI, 3, this->uri.audio_formats.S16,
this->uri.audio_formats.S16,
this->uri.audio_formats.S32),
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_URI, 3, this->uri.audio_formats.S16,
this->uri.audio_formats.S16,
this->uri.audio_formats.S32),
PROP_U_MM (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX),
PROP_U_MM (&f[1], this->uri.prop_audio.channels, SPA_POD_TYPE_INT, 2, 1, INT32_MAX));
break;
default:
return SPA_RESULT_ENUM_END;
@ -589,7 +581,7 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node,
return SPA_RESULT_NO_FORMAT;
spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer));
spa_pod_builder_format (&b, &f[0],
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_URI, this->current_format.info.raw.format),
PROP (&f[1], this->uri.prop_audio.rate, SPA_POD_TYPE_INT, this->current_format.info.raw.rate),
@ -790,7 +782,7 @@ static SpaResult
spa_audiotestsrc_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@ -957,11 +949,13 @@ audiotestsrc_init (const SpaHandleFactory *factory,
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
this->uri.format = spa_id_map_get_id (this->map, SPA_FORMAT_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_prop_audio_map (this->map, &this->uri.prop_audio);
spa_audio_formats_map (this->map, &this->uri.audio_formats);
spa_node_events_map (this->map, &this->uri.node_events);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = audiotestsrc_node;
this->clock = audiotestsrc_clock;

View file

@ -52,6 +52,7 @@ typedef struct {
typedef struct {
uint32_t node;
SpaNodeCommands node_commands;
} URI;
struct _SpaFFMpegDec {
@ -94,8 +95,8 @@ update_state (SpaFFMpegDec *this, SpaNodeState state)
}
static SpaResult
spa_ffmpeg_dec_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_ffmpeg_dec_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaFFMpegDec *this;
@ -104,24 +105,15 @@ spa_ffmpeg_dec_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaFFMpegDec, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
case SPA_NODE_COMMAND_START:
update_state (this, SPA_NODE_STATE_STREAMING);
break;
case SPA_NODE_COMMAND_PAUSE:
update_state (this, SPA_NODE_STATE_PAUSED);
break;
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
@ -453,7 +445,7 @@ static SpaResult
spa_ffmpeg_dec_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@ -533,6 +525,7 @@ spa_ffmpeg_dec_init (SpaHandle *handle,
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->node = ffmpeg_dec_node;
spa_node_commands_map (this->map, &this->uri.node_commands);
this->in_ports[0].info.flags = SPA_PORT_INFO_FLAG_NONE;
this->out_ports[0].info.flags = SPA_PORT_INFO_FLAG_NONE;

View file

@ -59,6 +59,7 @@ typedef struct {
uint32_t node;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaNodeCommands node_commands;
} URI;
struct _SpaFFMpegEnc {
@ -101,8 +102,8 @@ spa_ffmpeg_enc_node_set_props (SpaNode *node,
}
static SpaResult
spa_ffmpeg_enc_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_ffmpeg_enc_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaFFMpegEnc *this;
@ -111,24 +112,15 @@ spa_ffmpeg_enc_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaFFMpegEnc, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
case SPA_NODE_COMMAND_START:
update_state (this, SPA_NODE_STATE_STREAMING);
break;
case SPA_NODE_COMMAND_PAUSE:
update_state (this, SPA_NODE_STATE_PAUSED);
break;
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
@ -435,7 +427,7 @@ static SpaResult
spa_ffmpeg_enc_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@ -546,6 +538,7 @@ spa_ffmpeg_enc_init (SpaHandle *handle,
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = ffmpeg_enc_node;

View file

@ -26,6 +26,7 @@
#include <spa/node.h>
#include <spa/video/format-utils.h>
#include <spa/clock.h>
#include <spa/list.h>
#include <spa/log.h>
#include <spa/loop.h>
@ -65,12 +66,14 @@ struct _V4l2Buffer {
typedef struct {
uint32_t node;
uint32_t clock;
uint32_t format;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaMediaSubtypesVideo media_subtypes_video;
SpaPropVideo prop_video;
SpaVideoFormats video_formats;
SpaNodeEvents node_events;
SpaNodeCommands node_commands;
} URI;
typedef struct {
@ -248,7 +251,7 @@ do_pause (SpaLoop *loop,
{
SpaV4l2Source *this = user_data;
SpaResult res;
SpaNodeCommand *cmd = data;
SpaCommand *cmd = data;
res = spa_node_port_send_command (&this->node,
SPA_DIRECTION_OUTPUT,
@ -299,7 +302,7 @@ do_start (SpaLoop *loop,
{
SpaV4l2Source *this = user_data;
SpaResult res;
SpaNodeCommand *cmd = data;
SpaCommand *cmd = data;
res = spa_node_port_send_command (&this->node,
SPA_DIRECTION_OUTPUT,
@ -321,8 +324,8 @@ do_start (SpaLoop *loop,
}
static SpaResult
spa_v4l2_source_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_v4l2_source_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaV4l2Source *this;
@ -331,66 +334,53 @@ spa_v4l2_source_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaV4l2Source, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
SpaV4l2State *state = &this->state[0];
SpaResult res;
case SPA_NODE_COMMAND_START:
{
SpaV4l2State *state = &this->state[0];
SpaResult res;
if (!state->have_format)
return SPA_RESULT_NO_FORMAT;
if (!state->have_format)
return SPA_RESULT_NO_FORMAT;
if (state->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (state->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (state->started)
return SPA_RESULT_OK;
if ((res = spa_v4l2_stream_on (this)) < 0)
return res;
return spa_loop_invoke (this->state[0].data_loop,
do_start,
++this->seq,
SPA_POD_SIZE (command),
command,
this);
}
case SPA_NODE_COMMAND_PAUSE:
{
SpaV4l2State *state = &this->state[0];
if (!state->have_format)
return SPA_RESULT_NO_FORMAT;
if (state->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (!state->started)
return SPA_RESULT_OK;
return spa_loop_invoke (this->state[0].data_loop,
do_pause,
++this->seq,
SPA_POD_SIZE (command),
command,
this);
}
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
return SPA_RESULT_NOT_IMPLEMENTED;
case SPA_NODE_COMMAND_CLOCK_UPDATE:
{
if (state->started)
return SPA_RESULT_OK;
}
if ((res = spa_v4l2_stream_on (this)) < 0)
return res;
return spa_loop_invoke (this->state[0].data_loop,
do_start,
++this->seq,
SPA_POD_SIZE (command),
command,
this);
}
return SPA_RESULT_OK;
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
SpaV4l2State *state = &this->state[0];
if (!state->have_format)
return SPA_RESULT_NO_FORMAT;
if (state->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (!state->started)
return SPA_RESULT_OK;
return spa_loop_invoke (this->state[0].data_loop,
do_pause,
++this->seq,
SPA_POD_SIZE (command),
command,
this);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.ClockUpdate) {
return SPA_RESULT_OK;
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
@ -577,7 +567,7 @@ spa_v4l2_source_node_port_get_format (SpaNode *node,
b.data = state->format_buffer;
b.size = sizeof (state->format_buffer);
spa_pod_builder_push_format (&b, &f[0],
spa_pod_builder_push_format (&b, &f[0], this->uri.format,
state->current_format.media_type,
state->current_format.media_subtype);
@ -784,7 +774,7 @@ static SpaResult
spa_v4l2_source_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
SpaV4l2Source *this;
SpaResult res;
@ -797,19 +787,14 @@ spa_v4l2_source_node_port_send_command (SpaNode *node,
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_PAUSE:
res = spa_v4l2_port_set_enabled (this, false);
break;
case SPA_NODE_COMMAND_START:
res = spa_v4l2_port_set_enabled (this, true);
break;
default:
res = SPA_RESULT_NOT_IMPLEMENTED;
break;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
res = spa_v4l2_port_set_enabled (this, false);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
res = spa_v4l2_port_set_enabled (this, true);
} else
res = SPA_RESULT_NOT_IMPLEMENTED;
return res;
}
@ -972,12 +957,14 @@ v4l2_source_init (const SpaHandleFactory *factory,
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
this->uri.format = spa_id_map_get_id (this->map, SPA_FORMAT_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_media_subtypes_video_map (this->map, &this->uri.media_subtypes_video);
spa_prop_video_map (this->map, &this->uri.prop_video);
spa_video_formats_map (this->map, &this->uri.video_formats);
spa_node_events_map (this->map, &this->uri.node_events);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = v4l2source_node;
this->clock = v4l2source_clock;

View file

@ -662,7 +662,7 @@ have_size:
media_subtype = *SPA_MEMBER (&this->uri, info->media_subtype_offset, uint32_t);
video_format = *SPA_MEMBER (&this->uri, info->format_offset, uint32_t);
spa_pod_builder_push_format (&b, &f[0],
spa_pod_builder_push_format (&b, &f[0], this->uri.format,
media_type,
media_subtype);

View file

@ -25,6 +25,7 @@
#include <sys/timerfd.h>
#include <spa/id-map.h>
#include <spa/clock.h>
#include <spa/log.h>
#include <spa/loop.h>
#include <spa/node.h>
@ -39,11 +40,13 @@
typedef struct {
uint32_t node;
uint32_t clock;
uint32_t format;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropVideo prop_video;
SpaVideoFormats video_formats;
SpaNodeEvents node_events;
SpaNodeCommands node_commands;
} URI;
typedef struct _SpaVideoTestSrc SpaVideoTestSrc;
@ -283,8 +286,8 @@ update_state (SpaVideoTestSrc *this, SpaNodeState state)
}
static SpaResult
spa_videotestsrc_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_videotestsrc_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaVideoTestSrc *this;
@ -293,58 +296,47 @@ spa_videotestsrc_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaVideoTestSrc, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
struct timespec now;
case SPA_NODE_COMMAND_START:
{
struct timespec now;
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (this->started)
return SPA_RESULT_OK;
if (this->started)
return SPA_RESULT_OK;
clock_gettime (CLOCK_MONOTONIC, &now);
if (this->props.live)
this->start_time = SPA_TIMESPEC_TO_TIME (&now);
else
this->start_time = 0;
this->frame_count = 0;
this->elapsed_time = 0;
clock_gettime (CLOCK_MONOTONIC, &now);
if (this->props.live)
this->start_time = SPA_TIMESPEC_TO_TIME (&now);
else
this->start_time = 0;
this->frame_count = 0;
this->elapsed_time = 0;
this->started = true;
set_timer (this, true);
update_state (this, SPA_NODE_STATE_STREAMING);
break;
}
case SPA_NODE_COMMAND_PAUSE:
{
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (!this->started)
return SPA_RESULT_OK;
this->started = false;
set_timer (this, false);
update_state (this, SPA_NODE_STATE_PAUSED);
break;
}
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
this->started = true;
set_timer (this, true);
update_state (this, SPA_NODE_STATE_STREAMING);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (!this->started)
return SPA_RESULT_OK;
this->started = false;
set_timer (this, false);
update_state (this, SPA_NODE_STATE_PAUSED);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
@ -454,7 +446,7 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.video, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_URI, 3,
this->uri.video_formats.RGB,
@ -592,7 +584,7 @@ spa_videotestsrc_node_port_get_format (SpaNode *node,
spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer));
spa_pod_builder_format (&b, &f[0],
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.video, this->uri.media_subtypes.raw,
PROP (&f[1], this->uri.prop_video.format, SPA_POD_TYPE_URI, this->current_format.info.raw.format),
PROP (&f[1], this->uri.prop_video.size, -SPA_POD_TYPE_RECTANGLE, &this->current_format.info.raw.size),
@ -792,7 +784,7 @@ static SpaResult
spa_videotestsrc_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@ -959,11 +951,13 @@ videotestsrc_init (const SpaHandleFactory *factory,
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.clock = spa_id_map_get_id (this->map, SPA_CLOCK_URI);
this->uri.format = spa_id_map_get_id (this->map, SPA_FORMAT_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_prop_video_map (this->map, &this->uri.prop_video);
spa_video_formats_map (this->map, &this->uri.video_formats);
spa_node_events_map (this->map, &this->uri.node_events);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = videotestsrc_node;
this->clock = videotestsrc_clock;

View file

@ -63,11 +63,13 @@ typedef struct {
typedef struct {
uint32_t node;
uint32_t format;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaPropAudio prop_audio;
SpaAudioFormats audio_formats;
SpaNodeEvents node_events;
SpaNodeCommands node_commands;
} URI;
struct _SpaVolume {
@ -178,8 +180,8 @@ spa_volume_node_set_props (SpaNode *node,
}
static SpaResult
spa_volume_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_volume_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaVolume *this;
@ -188,24 +190,15 @@ spa_volume_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaVolume, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
case SPA_NODE_COMMAND_START:
update_state (this, SPA_NODE_STATE_STREAMING);
break;
case SPA_NODE_COMMAND_PAUSE:
update_state (this, SPA_NODE_STATE_PAUSED);
break;
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
@ -312,7 +305,7 @@ next:
switch (index++) {
case 0:
spa_pod_builder_format (&b, &f[0],
spa_pod_builder_format (&b, &f[0], this->uri.format,
this->uri.media_types.audio, this->uri.media_subtypes.raw,
PROP_U_EN (&f[1], this->uri.prop_audio.format, SPA_POD_TYPE_URI, 3,
this->uri.audio_formats.S16,
@ -629,7 +622,7 @@ static SpaResult
spa_volume_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@ -844,10 +837,13 @@ volume_init (const SpaHandleFactory *factory,
return SPA_RESULT_ERROR;
}
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
this->uri.format = spa_id_map_get_id (this->map, SPA_FORMAT_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_prop_audio_map (this->map, &this->uri.prop_audio);
spa_audio_formats_map (this->map, &this->uri.audio_formats);
spa_node_events_map (this->map, &this->uri.node_events);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = volume_node;
reset_volume_props (&this->props);

View file

@ -73,6 +73,7 @@ typedef struct {
uint32_t node;
SpaMediaTypes media_types;
SpaMediaSubtypes media_subtypes;
SpaNodeCommands node_commands;
} URI;
struct _SpaXvSink {
@ -166,8 +167,8 @@ spa_xv_sink_node_set_props (SpaNode *node,
}
static SpaResult
spa_xv_sink_node_send_command (SpaNode *node,
SpaNodeCommand *command)
spa_xv_sink_node_send_command (SpaNode *node,
SpaCommand *command)
{
SpaXvSink *this;
@ -176,27 +177,19 @@ spa_xv_sink_node_send_command (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaXvSink, node);
switch (SPA_NODE_COMMAND_TYPE (command)) {
case SPA_NODE_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Start) {
spa_xv_start (this);
case SPA_NODE_COMMAND_START:
spa_xv_start (this);
update_state (this, SPA_NODE_STATE_STREAMING);
break;
case SPA_NODE_COMMAND_PAUSE:
spa_xv_stop (this);
update_state (this, SPA_NODE_STATE_PAUSED);
break;
case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN:
case SPA_NODE_COMMAND_MARKER:
case SPA_NODE_COMMAND_CLOCK_UPDATE:
return SPA_RESULT_NOT_IMPLEMENTED;
update_state (this, SPA_NODE_STATE_STREAMING);
}
else if (SPA_COMMAND_TYPE (command) == this->uri.node_commands.Pause) {
spa_xv_stop (this);
update_state (this, SPA_NODE_STATE_PAUSED);
}
else
return SPA_RESULT_NOT_IMPLEMENTED;
return SPA_RESULT_OK;
}
@ -471,7 +464,7 @@ static SpaResult
spa_xv_sink_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
SpaCommand *command)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@ -573,6 +566,7 @@ xv_sink_init (const SpaHandleFactory *factory,
this->uri.node = spa_id_map_get_id (this->map, SPA_NODE_URI);
spa_media_types_fill (&this->uri.media_types, this->map);
spa_media_subtypes_map (this->map, &this->uri.media_subtypes);
spa_node_commands_map (this->map, &this->uri.node_commands);
this->node = xvsink_node;
reset_xv_sink_props (&this->props);