mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
more work on audioconvert
Implement audioconvert as a complex element of fmtconver, channelmix and resample. Make copying resample just to test. Plug the converter into pw_stream.
This commit is contained in:
parent
de36330917
commit
b3b47d3fe9
9 changed files with 1454 additions and 542 deletions
|
|
@ -73,6 +73,8 @@ struct port {
|
|||
uint32_t blocks;
|
||||
uint32_t size;
|
||||
|
||||
uint32_t offset;
|
||||
|
||||
struct buffer buffers[MAX_BUFFERS];
|
||||
uint32_t n_buffers;
|
||||
|
||||
|
|
@ -153,22 +155,6 @@ struct impl {
|
|||
#define GET_OUT_PORT(this,id) (&this->out_port)
|
||||
#define GET_PORT(this,d,id) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,id) : GET_OUT_PORT(this,id))
|
||||
|
||||
static void convert_generic (void *data, int n_dst, void *dst[n_dst],
|
||||
int n_src, const void *src[n_src], int n_bytes)
|
||||
{
|
||||
#if 0
|
||||
struct port *inport, *outport;
|
||||
|
||||
inport = GET_PORT(this, SPA_DIRECTION_INPUT, 0);
|
||||
outport = GET_PORT(this, SPA_DIRECTION_OUTPUT, 0);
|
||||
|
||||
if (inport->format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int setup_convert(struct impl *this)
|
||||
{
|
||||
struct port *inport, *outport;
|
||||
|
|
@ -181,12 +167,12 @@ static int setup_convert(struct impl *this)
|
|||
src_fmt = inport->format.info.raw.format;
|
||||
dst_fmt = outport->format.info.raw.format;
|
||||
|
||||
spa_log_info(this->log, NAME " %p: %d/%d@%d.%d->%d/%d@%d.%d", this,
|
||||
src_fmt,
|
||||
spa_log_info(this->log, NAME " %p: %s/%d@%d.%d->%s/%d@%d.%d", this,
|
||||
spa_type_map_get_type(this->map, src_fmt),
|
||||
inport->format.info.raw.channels,
|
||||
inport->format.info.raw.rate,
|
||||
inport->format.info.raw.layout,
|
||||
dst_fmt,
|
||||
spa_type_map_get_type(this->map, dst_fmt),
|
||||
outport->format.info.raw.channels,
|
||||
outport->format.info.raw.rate,
|
||||
outport->format.info.raw.layout);
|
||||
|
|
@ -214,16 +200,7 @@ static int setup_convert(struct impl *this)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* go through intermediate format */
|
||||
this->conv[0] = find_conv_info(&t->audio_format, src_fmt, t->audio_format.F32);
|
||||
this->conv[1] = find_conv_info(&t->audio_format, t->audio_format.F32, dst_fmt);
|
||||
if (this->conv[0] == NULL || this->conv[1] == NULL)
|
||||
return -ENOTSUP;
|
||||
|
||||
this->convert = convert_generic;
|
||||
|
||||
return 0;
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int impl_node_enum_params(struct spa_node *node,
|
||||
|
|
@ -368,17 +345,9 @@ static int port_enum_formats(struct spa_node *node,
|
|||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "Ieu", other->format.info.raw.format,
|
||||
SPA_POD_PROP_ENUM(11, t->audio_format.U8,
|
||||
t->audio_format.S16,
|
||||
t->audio_format.S16_OE,
|
||||
t->audio_format.F32,
|
||||
t->audio_format.F32_OE,
|
||||
t->audio_format.S32,
|
||||
t->audio_format.S32_OE,
|
||||
t->audio_format.S24,
|
||||
t->audio_format.S24_OE,
|
||||
t->audio_format.S24_32,
|
||||
t->audio_format.S24_32_OE),
|
||||
SPA_POD_PROP_ENUM(3, other->format.info.raw.format,
|
||||
t->audio_format.F32,
|
||||
t->audio_format.F32_OE),
|
||||
":", t->format_audio.layout, "ieu", other->format.info.raw.layout,
|
||||
SPA_POD_PROP_ENUM(2, SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_AUDIO_LAYOUT_NON_INTERLEAVED),
|
||||
|
|
@ -834,7 +803,7 @@ static int impl_node_process(struct spa_node *node)
|
|||
spa_return_val_if_fail(outio != NULL, -EIO);
|
||||
spa_return_val_if_fail(inio != NULL, -EIO);
|
||||
|
||||
spa_log_trace(this->log, NAME " %p: status %d", this, outio->status);
|
||||
spa_log_trace(this->log, NAME " %p: status %d %d", this, inio->status, outio->status);
|
||||
|
||||
if (outio->status == SPA_STATUS_HAVE_BUFFER)
|
||||
return outio->status;
|
||||
|
|
@ -857,24 +826,33 @@ static int impl_node_process(struct spa_node *node)
|
|||
sbuf = &inport->buffers[inio->buffer_id];
|
||||
|
||||
{
|
||||
int i, n_bytes;
|
||||
int i, n_bytes, maxsize;
|
||||
struct spa_buffer *sb = sbuf->outbuf, *db = dbuf->outbuf;
|
||||
uint32_t n_src_datas = sb->n_datas;
|
||||
uint32_t n_dst_datas = db->n_datas;
|
||||
const void *src_datas[n_src_datas];
|
||||
void *dst_datas[n_dst_datas];
|
||||
uint32_t size;
|
||||
|
||||
n_bytes = sb->datas[0].chunk->size;
|
||||
size = sb->datas[0].chunk->size;
|
||||
maxsize = (db->datas[0].maxsize / outport->stride) * inport->stride;
|
||||
n_bytes = SPA_MIN(size - inport->offset, maxsize);
|
||||
|
||||
for (i = 0; i < n_src_datas; i++)
|
||||
src_datas[i] = sb->datas[i].data;
|
||||
src_datas[i] = SPA_MEMBER(sb->datas[i].data, inport->offset, void);
|
||||
for (i = 0; i < n_dst_datas; i++) {
|
||||
dst_datas[i] = db->datas[i].data;
|
||||
db->datas[i].chunk->size =
|
||||
(n_bytes / inport->stride) * outport->stride;
|
||||
db->datas[i].chunk->size = (n_bytes / inport->stride) * outport->stride;
|
||||
}
|
||||
|
||||
this->convert(this, n_dst_datas, dst_datas, n_src_datas, src_datas, n_bytes);
|
||||
|
||||
inport->offset += n_bytes;
|
||||
if (inport->offset >= size) {
|
||||
inio->status = SPA_STATUS_NEED_BUFFER;
|
||||
inport->offset = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
outio->status = SPA_STATUS_HAVE_BUFFER;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue