Commit 1bb6f13f authored by Stefan Westerfeld's avatar Stefan Westerfeld

avfilter/asubprocess: improve eof handling

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 550a36be
#include "libavutil/opt.h"
#include "libavutil/mem.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/avassert.h"
#include "libavformat/avio.h"
#include "libavformat/avio_internal.h"
......@@ -21,7 +22,6 @@
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <poll.h>
#include <stdlib.h>
#include <stdbool.h>
......@@ -31,18 +31,19 @@
typedef struct SPB
{
struct SPB *next;
int offset;
int count;
char data[BUFFER_SIZE];
struct SPB *next;
int offset;
int count;
char data[BUFFER_SIZE];
} SPB;
typedef struct SP
{
int input_pipe;
int output_pipe;
SPB *out_buffers;
int pid;
int input_pipe;
int output_pipe;
SPB *out_buffers;
int pid;
bool done;
} SP;
static SPB *spb_new(void)
......@@ -90,11 +91,11 @@ sp_new (const char *command)
close (input_pipe[0]);
close (output_pipe[1]);
i = fcntl(output_pipe[0], F_GETFL);
assert(i != -1);
av_assert0(i != -1);
i |= O_NONBLOCK;
fcntl(output_pipe[0], F_SETFL, i);
i = fcntl(input_pipe[1], F_GETFL);
assert(i != -1);
av_assert0(i != -1);
i |= O_NONBLOCK;
fcntl(input_pipe[1], F_SETFL, i);
sp->input_pipe = input_pipe[1];
......@@ -136,7 +137,7 @@ sp_read (SP *sp, char *buffer, int count)
}
}
static bool
static void
sp_write (SP *sp, char *buffer, int count)
{
int offset = 0;
......@@ -183,11 +184,17 @@ sp_write (SP *sp, char *buffer, int count)
int status;
waitpid (sp->pid, &status, 0);
printf ("wstatus=%d\n", WEXITSTATUS (status));
return true;
sp->done = true;
return;
}
}
} while (count);
return false;
}
static bool
sp_done (SP *sp)
{
return sp->done;
}
// =============================================
......@@ -311,7 +318,6 @@ static int config_input(AVFilterLink *inlink)
static void read_samples(ASubProcessContext *s, int32_t *data, int count)
{
int sample_size = s->in_bit_depth / 8;
assert(in->nb_samples <= NB_BUFFER_SAMPLES);
#if !HAVE_BIGENDIAN
if (s->out_bit_depth == 32)
{
......@@ -353,10 +359,9 @@ static void read_samples(ASubProcessContext *s, int32_t *data, int count)
static void write_samples(ASubProcessContext *s, int32_t *data, int count)
{
int sample_size = s->in_bit_depth / 8;
assert(in->nb_samples <= NB_BUFFER_SAMPLES);
#if !HAVE_BIGENDIAN
if (s->out_bit_depth == 32)
if (s->in_bit_depth == 32)
{
/* optimized case: on little endian systems we don't need any conversion */
sp_write(s->sp, (char *)data, sample_size * count);
......@@ -391,13 +396,8 @@ static int write_frame(ASubProcessContext *s, AVFilterLink *inlink, AVFrame *in)
{
int ret = 0;
av_assert0(in->nb_samples <= NB_BUFFER_SAMPLES);
write_samples(s, (int32_t *)in->data[0], in->nb_samples * inlink->ch_layout.nb_channels);
if (s->eof)
{
while (!sp_write (s->sp, 0, 0))
;
printf ("eof\n");
}
av_frame_free(&in);
return ret;
}
......@@ -456,6 +456,7 @@ static int try_read_frame(ASubProcessContext *s, AVFilterLink *outlink)
if (!out) {
return AVERROR(ENOMEM);
}
av_assert0(avail <= NB_BUFFER_SAMPLES);
read_samples(s, (int32_t *)out->data[0], avail * outlink->ch_layout.nb_channels);
ret = ff_filter_frame(outlink, out);
if (ret < 0)
......@@ -498,6 +499,12 @@ static int activate(AVFilterContext *ctx)
if (ret != 0)
return ret;
}
if (s->eof && !sp_done (s->sp))
{
while (!sp_done (s->sp))
sp_write (s->sp, 0, 0);
printf ("eof\n");
}
ret = try_read_frame(s, outlink);
if (ret != 0)
return ret;
......
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