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)
// =============================================
enum {
STATE_EXPECT_RIFF = 0,
STATE_EXPECT_CHUNK = 1,
STATE_SKIP_CHUNK = 2,
STATE_IN_DATA_CHUNK = 3,
STATE_ERROR = 4
STATE_EXPECT_RIFF,
STATE_EXPECT_CHUNK,
STATE_SKIP_CHUNK,
STATE_IN_DATA_CHUNK,
STATE_IN_FMT_CHUNK,
STATE_ERROR
};
typedef struct AndioWMarkContext {
......@@ -205,7 +206,8 @@ typedef struct AndioWMarkContext {
int fd;
int state;
unsigned int state_skip;
unsigned int chunk_size;
int out_bit_depth;
SP *sp;
int nb_samples;
int eof;
......@@ -324,29 +326,38 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
unsigned char 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')
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
{
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];
unsigned int n = FFMIN (sizeof (buffer), s->state_skip);
unsigned int n = FFMIN (sizeof (buffer), s->chunk_size);
sp_read (s->sp, buffer, n);
s->state_skip -= n;
s->chunk_size -= n;
}
s->state = STATE_EXPECT_CHUNK;
}
bool gen_output = s->state == STATE_IN_DATA_CHUNK;
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)
avail = 2048;
if (avail > 0)
......@@ -357,12 +368,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
return AVERROR(ENOMEM);
}
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];
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);
xd[k] = v << 16;
int32_t *i32buffer = (int32_t *) buffer;
for (int k = 0; k < todo; k++)
xd[k] = AV_RL32 (i32buffer + k);
}
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