Commit 4a465a05 authored by Stefan Westerfeld's avatar Stefan Westerfeld

avfilter/asubprocess: add checks for subprocess output (should be wav)

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 58bad47d
...@@ -486,14 +486,20 @@ static int write_frame(AVFilterContext *ctx, ASubProcessContext *s, AVFilterLink ...@@ -486,14 +486,20 @@ static int write_frame(AVFilterContext *ctx, ASubProcessContext *s, AVFilterLink
return ret; return ret;
} }
static int try_read_frame(ASubProcessContext *s, AVFilterLink *outlink) static int try_read_frame(AVFilterContext *ctx)
{ {
AVFilterLink *outlink = ctx->outputs[0];
ASubProcessContext *s = ctx->priv;
int ret; int ret;
if (s->state == STATE_EXPECT_RIFF && sp_can_read(s->sp) >= 12) if (s->state == STATE_EXPECT_RIFF && sp_can_read(s->sp) >= 12)
{ {
char buffer[12]; char buffer[12];
sp_read(s->sp, buffer, 12); sp_read(s->sp, buffer, 12);
if ((memcmp (buffer, "RIFF", 4) && memcmp (buffer, "RF64", 4)) || memcmp (buffer + 8, "WAVE", 4)) {
av_log(ctx, AV_LOG_ERROR, "Subprocess output is not a valid wav file.\n");
return AVERROR_INVALIDDATA;
}
s->state = STATE_EXPECT_CHUNK; s->state = STATE_EXPECT_CHUNK;
} }
if (s->state == STATE_EXPECT_CHUNK && sp_can_read(s->sp) >= 8) if (s->state == STATE_EXPECT_CHUNK && sp_can_read(s->sp) >= 8)
...@@ -501,9 +507,9 @@ static int try_read_frame(ASubProcessContext *s, AVFilterLink *outlink) ...@@ -501,9 +507,9 @@ static int try_read_frame(ASubProcessContext *s, AVFilterLink *outlink)
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); s->chunk_size = AV_RL32 (x + 4);
if (x[0] == 'd' && x[1] == 'a' && x[2] == 't' && x[3] == 'a') if (!memcmp (x, "data", 4))
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) else if (!memcmp (x, "fmt ", 4) && s->chunk_size >= 16)
s->state = STATE_IN_FMT_CHUNK; s->state = STATE_IN_FMT_CHUNK;
else else
s->state = STATE_SKIP_CHUNK; s->state = STATE_SKIP_CHUNK;
...@@ -511,8 +517,35 @@ static int try_read_frame(ASubProcessContext *s, AVFilterLink *outlink) ...@@ -511,8 +517,35 @@ static int try_read_frame(ASubProcessContext *s, AVFilterLink *outlink)
if (s->state == STATE_IN_FMT_CHUNK && sp_can_read(s->sp) >= 16) if (s->state == STATE_IN_FMT_CHUNK && sp_can_read(s->sp) >= 16)
{ {
unsigned char data[16]; unsigned char data[16];
int format, nb_channels, sample_rate;
sp_read(s->sp, data, 16); sp_read(s->sp, data, 16);
s->out_bit_depth = AV_RL16 (data + 14);
format = AV_RL16(data);
nb_channels = AV_RL16(data + 2);
sample_rate = AV_RL32(data + 4);
s->out_bit_depth = AV_RL16(data + 14);
if (format != 1 && format != 0xFFFE) { // TODO: check extensible wav format: should be PCM
av_log(ctx, AV_LOG_ERROR,
"Unsupported wav format (%d) from subprocess (expected PCM).\n", format);
return AVERROR_INVALIDDATA;
}
if (nb_channels != outlink->ch_layout.nb_channels) {
av_log(ctx, AV_LOG_ERROR,
"Number of output channels (%d) from subprocess doesn't match input channels (%d).\n",
nb_channels, outlink->ch_layout.nb_channels);
return AVERROR_INVALIDDATA;
}
if (sample_rate != outlink->sample_rate) {
av_log(ctx, AV_LOG_ERROR,
"Sample rate (%d) from subprocess doesn't match input sample rate (%d).\n",
sample_rate, outlink->sample_rate);
return AVERROR_INVALIDDATA;
}
if (s->out_bit_depth != 8 && s->out_bit_depth != 16 && s->out_bit_depth != 24 && s->out_bit_depth != 32) {
av_log(ctx, AV_LOG_ERROR, "Unsupported output wav bit depth (%d) from subprocess.\n", s->out_bit_depth);
return AVERROR_INVALIDDATA;
}
s->chunk_size -= 16; s->chunk_size -= 16;
s->state = STATE_SKIP_CHUNK; s->state = STATE_SKIP_CHUNK;
} }
...@@ -560,7 +593,7 @@ static int activate(AVFilterContext *ctx) ...@@ -560,7 +593,7 @@ static int activate(AVFilterContext *ctx)
FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
ret = try_read_frame(s, outlink); ret = try_read_frame(ctx);
if (ret != 0) if (ret != 0)
return ret; return ret;
ret = ff_inlink_consume_frame(inlink, &in); ret = ff_inlink_consume_frame(inlink, &in);
...@@ -588,11 +621,15 @@ static int activate(AVFilterContext *ctx) ...@@ -588,11 +621,15 @@ static int activate(AVFilterContext *ctx)
return ret; return ret;
} }
} }
ret = try_read_frame(s, outlink); ret = try_read_frame(ctx);
if (ret != 0) if (ret != 0)
return ret; return ret;
if (s->eof) { if (s->eof) {
if (s->state != STATE_IN_DATA_CHUNK) {
av_log(ctx, AV_LOG_ERROR, "Subprocess output wav is incomplete (no data chunk found)\n");
return AVERROR_INVALIDDATA;
}
// s->last_pts // s->last_pts
ff_outlink_set_status(outlink, AVERROR_EOF, AV_NOPTS_VALUE); ff_outlink_set_status(outlink, AVERROR_EOF, AV_NOPTS_VALUE);
return 0; return 0;
......
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