mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
handle set_format with existing format
If one calls set-format with the current format, we return success Remove some unused utils now Work on cleanup of buffers
This commit is contained in:
parent
55c3262a6a
commit
ab0537305f
9 changed files with 82 additions and 143 deletions
|
|
@ -212,7 +212,6 @@ libpinoscore_@PINOS_MAJORMINOR@_la_SOURCES = \
|
|||
server/node.c server/node.h \
|
||||
server/port.c server/port.h \
|
||||
server/node-factory.c server/node-factory.h \
|
||||
server/utils.c server/utils.h \
|
||||
modules/gst/gst-manager.c modules/gst/gst-manager.h \
|
||||
modules/gst/gst-source.c modules/gst/gst-source.h \
|
||||
modules/gst/gst-sink.c modules/gst/gst-sink.h \
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
#include "pinos/server/daemon.h"
|
||||
#include "pinos/server/client-node.h"
|
||||
#include "pinos/server/utils.h"
|
||||
#include "pinos/server/link.h"
|
||||
|
||||
#include "pinos/dbus/org-pinos.h"
|
||||
|
|
|
|||
|
|
@ -267,12 +267,22 @@ do_allocation (PinosLink *this)
|
|||
{
|
||||
PinosLinkPrivate *priv = this->priv;
|
||||
SpaResult res;
|
||||
const SpaPortInfo *iinfo, *oinfo;
|
||||
|
||||
g_debug ("link %p: doing alloc buffers", this);
|
||||
/* find out what's possible */
|
||||
if ((res = spa_node_port_get_info (priv->output_node, priv->output_port, &oinfo)) < 0) {
|
||||
g_warning ("error get port info: %d", res);
|
||||
return res;
|
||||
}
|
||||
if ((res = spa_node_port_get_info (priv->input_node, priv->input_port, &iinfo)) < 0) {
|
||||
g_warning ("error get port info: %d", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
priv->n_buffers = 16;
|
||||
if ((res = spa_node_port_alloc_buffers (priv->output_node, priv->output_port,
|
||||
NULL, 0,
|
||||
iinfo->params, iinfo->n_params,
|
||||
priv->buffers, &priv->n_buffers)) < 0) {
|
||||
g_warning ("error alloc buffers: %d", res);
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ node_add_port (PinosNode *node,
|
|||
"id", id,
|
||||
NULL);
|
||||
if (port) {
|
||||
g_hash_table_insert (priv->ports, GUINT_TO_POINTER (id), port);
|
||||
g_hash_table_insert (priv->ports, GUINT_TO_POINTER (port->id), port);
|
||||
g_signal_connect (port, "remove", (GCallback) do_remove_port, node);
|
||||
g_signal_emit (node, signals[SIGNAL_PORT_ADDED], 0, port);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "pinos/server/port.h"
|
||||
#include "pinos/server/node.h"
|
||||
#include "pinos/server/utils.h"
|
||||
|
||||
#define PINOS_PORT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_PORT, PinosPortPrivate))
|
||||
|
|
|
|||
|
|
@ -1,84 +0,0 @@
|
|||
/* Pinos
|
||||
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "pinos/server/utils.h"
|
||||
|
||||
GBytes *
|
||||
pinos_format_filter (GBytes *format,
|
||||
GBytes *filter,
|
||||
GError **error)
|
||||
{
|
||||
GstCaps *tmp, *caps, *cfilter;
|
||||
gchar *str;
|
||||
GBytes *res;
|
||||
|
||||
if (filter) {
|
||||
cfilter = gst_caps_from_string (g_bytes_get_data (filter, NULL));
|
||||
if (cfilter == NULL)
|
||||
goto invalid_filter;
|
||||
} else {
|
||||
cfilter = NULL;
|
||||
}
|
||||
|
||||
if (format)
|
||||
caps = gst_caps_from_string (g_bytes_get_data (format, NULL));
|
||||
else
|
||||
caps = gst_caps_new_any ();
|
||||
|
||||
if (caps && cfilter) {
|
||||
tmp = gst_caps_intersect_full (caps, cfilter, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_take (&caps, tmp);
|
||||
}
|
||||
g_clear_pointer (&cfilter, gst_caps_unref);
|
||||
|
||||
if (caps == NULL || gst_caps_is_empty (caps))
|
||||
goto no_format;
|
||||
|
||||
str = gst_caps_to_string (caps);
|
||||
gst_caps_unref (caps);
|
||||
res = g_bytes_new_take (str, strlen (str) + 1);
|
||||
|
||||
return res;
|
||||
|
||||
invalid_filter:
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_ARGUMENT,
|
||||
"Invalid filter received");
|
||||
return NULL;
|
||||
}
|
||||
no_format:
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"No compatible format found");
|
||||
if (cfilter)
|
||||
gst_caps_unref (cfilter);
|
||||
if (caps)
|
||||
gst_caps_unref (caps);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/* Pinos
|
||||
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PINOS_UTILS_H__
|
||||
#define __PINOS_UTILS_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GBytes * pinos_format_filter (GBytes *format1, GBytes *format2, GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PINOS_UTILS_H__ */
|
||||
|
|
@ -91,7 +91,7 @@ typedef struct {
|
|||
void *cookie;
|
||||
|
||||
V4l2Format format[2];
|
||||
SpaFormat *current_format;
|
||||
V4l2Format *current_format;
|
||||
|
||||
int fd;
|
||||
bool opened;
|
||||
|
|
@ -412,12 +412,21 @@ spa_v4l2_source_node_port_set_format (SpaNode *node,
|
|||
f = (V4l2Format*)format;
|
||||
}
|
||||
|
||||
if (state->current_format) {
|
||||
if (f->fmt.media_type == state->current_format->fmt.media_type &&
|
||||
f->fmt.media_subtype == state->current_format->fmt.media_subtype &&
|
||||
f->format == state->current_format->format &&
|
||||
f->size.width == state->current_format->size.width &&
|
||||
f->size.height == state->current_format->size.height)
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
if (spa_v4l2_set_format (this, f, flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY) < 0)
|
||||
return SPA_RESULT_INVALID_MEDIA_TYPE;
|
||||
|
||||
if (!(flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY)) {
|
||||
memcpy (tf, f, fs);
|
||||
state->current_format = &tf->fmt;
|
||||
state->current_format = tf;
|
||||
}
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
|
@ -444,7 +453,7 @@ spa_v4l2_source_node_port_get_format (SpaNode *node,
|
|||
if (state->current_format == NULL)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
||||
*format = state->current_format;
|
||||
*format = &state->current_format->fmt;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,7 +325,11 @@ again:
|
|||
i = ++state->frmival.index;
|
||||
}
|
||||
fmt->infos[pi].n_range_values = i;
|
||||
fmt->fmt.props.unset_mask |= 1 << pi;
|
||||
if (i == 1) {
|
||||
fmt->framerate = fmt->framerates[0];
|
||||
} else {
|
||||
fmt->fmt.props.unset_mask |= 1 << pi;
|
||||
}
|
||||
pi = ++fmt->fmt.props.n_prop_info;
|
||||
|
||||
*format = &state->format[0].fmt;
|
||||
|
|
@ -488,6 +492,9 @@ spa_v4l2_buffer_recycle (SpaV4l2Source *this, uint32_t buffer_id)
|
|||
SpaV4l2State *state = &this->state[0];
|
||||
V4l2Buffer *b = &state->alloc_buffers[buffer_id];
|
||||
|
||||
if (!b->outstanding)
|
||||
return;
|
||||
|
||||
b->outstanding = false;
|
||||
|
||||
if (xioctl (state->fd, VIDIOC_QBUF, &b->v4l2_buffer) < 0) {
|
||||
|
|
@ -495,6 +502,38 @@ spa_v4l2_buffer_recycle (SpaV4l2Source *this, uint32_t buffer_id)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_buffers (SpaV4l2Source *this)
|
||||
{
|
||||
SpaV4l2State *state = &this->state[0];
|
||||
int i;
|
||||
|
||||
if (!state->have_buffers)
|
||||
return;
|
||||
|
||||
for (i = 0; i < state->reqbuf.count; i++) {
|
||||
V4l2Buffer *b;
|
||||
SpaMemory *mem;
|
||||
|
||||
b = &state->alloc_buffers[i];
|
||||
if (b->outstanding) {
|
||||
fprintf (stderr, "queueing outstanding buffer %p\n", b);
|
||||
spa_v4l2_buffer_recycle (this, i);
|
||||
}
|
||||
mem = spa_memory_find (&b->datas[0].mem.mem);
|
||||
if (state->export_buf) {
|
||||
close (mem->fd);
|
||||
} else {
|
||||
munmap (mem->ptr, mem->size);
|
||||
}
|
||||
spa_memory_unref (&mem->mem);
|
||||
}
|
||||
if (state->alloc_mem)
|
||||
spa_memory_unref (&state->alloc_mem->mem);
|
||||
|
||||
state->have_buffers = false;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_import_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_buffers)
|
||||
{
|
||||
|
|
@ -502,6 +541,11 @@ spa_v4l2_import_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_bu
|
|||
struct v4l2_requestbuffers reqbuf;
|
||||
int i;
|
||||
|
||||
if (buffers == NULL) {
|
||||
clear_buffers (this);
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
state->memtype = V4L2_MEMORY_USERPTR;
|
||||
|
||||
CLEAR(reqbuf);
|
||||
|
|
@ -715,6 +759,18 @@ spa_v4l2_alloc_buffers (SpaV4l2Source *this,
|
|||
{
|
||||
SpaResult res;
|
||||
SpaV4l2State *state = &this->state[0];
|
||||
unsigned int i;
|
||||
|
||||
if (state->have_buffers) {
|
||||
if (*n_buffers < state->reqbuf.count)
|
||||
return SPA_RESULT_NO_BUFFERS;
|
||||
|
||||
*n_buffers = state->reqbuf.count;
|
||||
for (i = 0; i < state->reqbuf.count; i++) {
|
||||
buffers[i] = &state->alloc_buffers[i].buffer;
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
if (state->cap.capabilities & V4L2_CAP_STREAMING) {
|
||||
if ((res = mmap_init (this, params, n_params, buffers, n_buffers)) < 0)
|
||||
|
|
@ -774,7 +830,6 @@ spa_v4l2_stop (SpaV4l2Source *this)
|
|||
SpaV4l2State *state = &this->state[0];
|
||||
enum v4l2_buf_type type;
|
||||
SpaEvent event;
|
||||
int i;
|
||||
|
||||
if (!state->opened)
|
||||
return SPA_RESULT_OK;
|
||||
|
|
@ -785,24 +840,7 @@ spa_v4l2_stop (SpaV4l2Source *this)
|
|||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < state->reqbuf.count; i++) {
|
||||
V4l2Buffer *b;
|
||||
SpaMemory *mem;
|
||||
|
||||
b = &state->alloc_buffers[i];
|
||||
if (b->outstanding) {
|
||||
fprintf (stderr, "queueing outstanding buffer %p\n", b);
|
||||
spa_v4l2_buffer_recycle (this, i);
|
||||
}
|
||||
mem = spa_memory_find (&b->datas[0].mem.mem);
|
||||
if (state->export_buf) {
|
||||
close (mem->fd);
|
||||
} else {
|
||||
munmap (mem->ptr, mem->size);
|
||||
}
|
||||
spa_memory_unref (&mem->mem);
|
||||
}
|
||||
state->have_buffers = false;
|
||||
clear_buffers (this);
|
||||
|
||||
event.type = SPA_EVENT_TYPE_REMOVE_POLL;
|
||||
event.port_id = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue