Commit 0bee9b20 authored by Stefan Westerfeld's avatar Stefan Westerfeld

avfilter/asubprocess: supprt 8, 16, 24 and 32 bit subprocess output wavs

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 7778b293
...@@ -191,11 +191,12 @@ sp_write (SP *sp, char *buffer, int count) ...@@ -191,11 +191,12 @@ sp_write (SP *sp, char *buffer, int count)
// ============================================= // =============================================
enum { enum {
STATE_EXPECT_RIFF = 0, STATE_EXPECT_RIFF,
STATE_EXPECT_CHUNK = 1, STATE_EXPECT_CHUNK,
STATE_SKIP_CHUNK = 2, STATE_SKIP_CHUNK,
STATE_IN_DATA_CHUNK = 3, STATE_IN_DATA_CHUNK,
STATE_ERROR = 4 STATE_IN_FMT_CHUNK,
STATE_ERROR
}; };
typedef struct AndioWMarkContext { typedef struct AndioWMarkContext {
...@@ -205,7 +206,8 @@ typedef struct AndioWMarkContext { ...@@ -205,7 +206,8 @@ typedef struct AndioWMarkContext {
int fd; int fd;
int state; int state;
unsigned int state_skip; unsigned int chunk_size;
int out_bit_depth;
SP *sp; SP *sp;
int nb_samples; int nb_samples;
int eof; int eof;
...@@ -324,29 +326,38 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -324,29 +326,38 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{ {
unsigned char x[8]; unsigned char x[8];
sp_read (s->sp, x, 8); sp_read (s->sp, x, 8);
s->chunk_size = AV_RL32 (x + 4);
if (x[0] == 'd' && x[1] == 'a' && x[2] == 't' && x[3] == 'a') if (x[0] == 'd' && x[1] == 'a' && x[2] == 't' && x[3] == 'a')
s->state = STATE_IN_DATA_CHUNK; s->state = STATE_IN_DATA_CHUNK;
else if (x[0] == 'f' && x[1] == 'm' && x[2] == 't' && x[3] == ' ' && s->chunk_size >= 16)
s->state = STATE_IN_FMT_CHUNK;
else else
{
s->state = STATE_SKIP_CHUNK; s->state = STATE_SKIP_CHUNK;
s->state_skip = x[4] + (x[5] << 8) + (x[6] << 16) + (x[7] << 24);
}
} }
if (s->state == STATE_SKIP_CHUNK && sp_can_read (s->sp) >= s->state_skip) if (s->state == STATE_IN_FMT_CHUNK && sp_can_read (s->sp) >= 16)
{
unsigned char data[16];
sp_read (s->sp, data, 16);
s->out_bit_depth = AV_RL16 (data + 14);
s->chunk_size -= 16;
s->state = STATE_SKIP_CHUNK;
}
if (s->state == STATE_SKIP_CHUNK && sp_can_read (s->sp) >= s->chunk_size)
{ {
while (s->state_skip) while (s->chunk_size)
{ {
char buffer[1024]; char buffer[1024];
unsigned int n = FFMIN (sizeof (buffer), s->state_skip); unsigned int n = FFMIN (sizeof (buffer), s->chunk_size);
sp_read (s->sp, buffer, n); sp_read (s->sp, buffer, n);
s->state_skip -= n; s->chunk_size -= n;
} }
s->state = STATE_EXPECT_CHUNK; s->state = STATE_EXPECT_CHUNK;
} }
bool gen_output = s->state == STATE_IN_DATA_CHUNK; bool gen_output = s->state == STATE_IN_DATA_CHUNK;
while (gen_output) while (gen_output)
{ {
int avail = sp_can_read (s->sp) / 2 / inlink->ch_layout.nb_channels; int sample_size = s->out_bit_depth / 8;
int avail = sp_can_read (s->sp) / sample_size / inlink->ch_layout.nb_channels;
if (avail > 2048) if (avail > 2048)
avail = 2048; avail = 2048;
if (avail > 0) if (avail > 0)
...@@ -357,12 +368,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ...@@ -357,12 +368,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
short buffer[100000]; // FIXME avail * inlink->ch_layout.nb_channels]; short buffer[100000]; // FIXME avail * inlink->ch_layout.nb_channels];
sp_read (s->sp, buffer, avail * 2 * inlink->ch_layout.nb_channels); sp_read (s->sp, buffer, avail * sample_size * inlink->ch_layout.nb_channels);
int32_t *xd = (int32_t *)out->data[0]; int32_t *xd = (int32_t *)out->data[0];
for (int k = 0; k < avail * inlink->ch_layout.nb_channels; k++) int todo = avail * inlink->ch_layout.nb_channels;
if (s->out_bit_depth == 8)
{
int8_t *in = (int8_t *) buffer;
for (int k = 0; k < todo; k++)
xd[k] = (in[k] << 24) + 0x80000000;
}
if (s->out_bit_depth == 16)
{
for (int k = 0; k < todo; k++)
xd[k] = AV_RL16 (buffer + k) << 16;
}
if (s->out_bit_depth == 24)
{
uint8_t *in = (uint8_t *) buffer;
for (int k = 0; k < todo; k++)
{
xd[k] = AV_RL24 (in) << 8;
in += 3;
}
}
if (s->out_bit_depth == 32)
{ {
short v = AV_RL16 (buffer + k); int32_t *i32buffer = (int32_t *) buffer;
xd[k] = v << 16; for (int k = 0; k < todo; k++)
xd[k] = AV_RL32 (i32buffer + k);
} }
ret = ff_filter_frame(outlink, out); ret = ff_filter_frame(outlink, out);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment