Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefan Westerfeld
ffmpeg
Commits
c82196d6
Commit
c82196d6
authored
Jun 02, 2024
by
Stefan Westerfeld
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/asubprocess: code cleanup, minor error handling improvements
Signed-off-by:
Stefan Westerfeld
<
stefan@space.twc.de
>
parent
bc24058b
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
41 additions
and
33 deletions
+41
-33
af_asubprocess.c
libavfilter/af_asubprocess.c
+41
-33
No files found.
libavfilter/af_asubprocess.c
View file @
c82196d6
...
...
@@ -40,7 +40,7 @@ typedef struct SP
int
output_pipe
;
SPB
*
out_buffers
;
SPB
*
unused_buffers
;
int
pid
;
pid_t
pid
;
size_t
input_count
;
size_t
can_read
;
bool
done
;
...
...
@@ -74,6 +74,17 @@ typedef struct ASubProcessContext {
FFFrameQueue
frame_queue
;
}
ASubProcessContext
;
#define OFFSET(x) offsetof(ASubProcessContext, x)
#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
static
const
AVOption
asubprocess_options
[]
=
{
{
"command"
,
"set command to run as subprocess"
,
OFFSET
(
command
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
0
,
0
,
A
},
{
"bits"
,
"set wav bit depth for subprocess input"
,
OFFSET
(
in_bit_depth
),
AV_OPT_TYPE_INT
,
{.
i64
=
32
},
0
,
32
,
A
},
{
NULL
},
};
AVFILTER_DEFINE_CLASS
(
asubprocess
);
static
SPB
*
spb_new
(
AVFilterContext
*
ctx
)
{
ASubProcessContext
*
s
=
ctx
->
priv
;
...
...
@@ -115,9 +126,9 @@ static void
sp_cleanup
(
SP
*
sp
)
{
if
(
sp
->
input_pipe
>=
0
)
close
(
sp
->
input_pipe
);
close
(
sp
->
input_pipe
);
if
(
sp
->
output_pipe
>=
0
)
close
(
sp
->
output_pipe
);
close
(
sp
->
output_pipe
);
if
(
!
sp
->
done
)
{
int
status
;
...
...
@@ -238,7 +249,7 @@ sp_read(SP *sp, char *buffer, size_t count)
static
int
try_read_frame
(
AVFilterContext
*
ctx
);
static
int
update_state
(
AVFilterContext
*
ctx
)
static
int
process_input
(
AVFilterContext
*
ctx
)
{
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
ASubProcessContext
*
s
=
ctx
->
priv
;
...
...
@@ -300,7 +311,7 @@ static int update_state(AVFilterContext *ctx)
s
->
chunk_size
-=
16
;
s
->
state
=
STATE_SKIP_CHUNK
;
}
else
if
(
s
->
state
==
STATE_SKIP_CHUNK
&&
can_read
>
0
)
{
else
if
(
s
->
state
==
STATE_SKIP_CHUNK
)
{
unsigned
int
to_skip
=
FFMIN
(
s
->
chunk_size
,
can_read
);
s
->
chunk_size
-=
to_skip
;
if
(
!
s
->
chunk_size
)
...
...
@@ -309,7 +320,7 @@ static int update_state(AVFilterContext *ctx)
while
(
to_skip
)
{
char
buffer
[
1024
];
unsigned
int
n
=
FFMIN
(
sizeof
(
buffer
),
to_skip
);
sp_read
(
s
->
sp
,
buffer
,
n
);
sp_read
(
s
->
sp
,
buffer
,
n
);
to_skip
-=
n
;
}
}
...
...
@@ -352,16 +363,22 @@ sp_write(AVFilterContext *ctx, char *buffer, int count)
}
if
(
count
&&
sp
->
done
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Subprocess terminated before all input data could be written.
\n
"
);
return
AVERROR
_EXTERNAL
;
return
AVERROR
(
EIO
)
;
}
do
{
int
rc
;
struct
pollfd
fds
[
2
]
=
{
{
.
fd
=
sp
->
input_pipe
,
.
events
=
POLLOUT
,
.
revents
=
0
},
{
.
fd
=
sp
->
output_pipe
,
.
events
=
POLLIN
,
.
revents
=
0
},
};
poll
(
fds
,
2
,
-
1
);
errno
=
0
;
rc
=
poll
(
fds
,
2
,
-
1
);
if
((
rc
<=
0
&&
errno
!=
EAGAIN
&&
errno
!=
EINTR
)
||
(
fds
[
0
].
revents
&
POLLNVAL
)
||
(
fds
[
1
].
revents
&
(
POLLERR
|
POLLNVAL
)))
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Poll for subprocess failed.
\n
"
);
return
AVERROR
(
errno
?
errno
:
EIO
);
}
if
(
fds
[
0
].
revents
&
(
POLLOUT
|
POLLHUP
))
{
int
rc
=
write
(
sp
->
input_pipe
,
&
buffer
[
offset
],
count
);
rc
=
write
(
sp
->
input_pipe
,
&
buffer
[
offset
],
count
);
if
(
rc
>
0
)
{
offset
+=
rc
;
count
-=
rc
;
...
...
@@ -374,7 +391,7 @@ sp_write(AVFilterContext *ctx, char *buffer, int count)
}
if
(
fds
[
1
].
revents
&
(
POLLIN
|
POLLHUP
))
{
SPB
*
last
;
int
r
c
,
r
et
;
int
ret
;
if
(
!
sp
->
out_buffers
)
{
sp
->
out_buffers
=
spb_new
(
ctx
);
...
...
@@ -397,7 +414,7 @@ sp_write(AVFilterContext *ctx, char *buffer, int count)
last
->
count
+=
rc
;
sp
->
input_count
+=
rc
;
sp
->
can_read
+=
rc
;
ret
=
update_state
(
ctx
);
ret
=
process_input
(
ctx
);
if
(
ret
!=
0
)
return
ret
;
}
...
...
@@ -409,11 +426,11 @@ sp_write(AVFilterContext *ctx, char *buffer, int count)
if
(
exit_status
!=
0
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Subprocess failed with non-zero exit code (%d).
\n
"
,
exit_status
);
return
AVERROR
_EXTERNAL
;
return
AVERROR
(
EIO
)
;
}
if
(
count
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Subprocess terminated before all input data could be written.
\n
"
);
return
AVERROR
_EXTERNAL
;
return
AVERROR
(
EIO
)
;
}
return
0
;
}
...
...
@@ -432,18 +449,6 @@ sp_done (SP *sp)
{
return
sp
->
done
;
}
// =============================================
#define OFFSET(x) offsetof(ASubProcessContext, x)
#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
static
const
AVOption
asubprocess_options
[]
=
{
{
"command"
,
"set command to run as subprocess"
,
OFFSET
(
command
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
0
,
0
,
A
},
{
"bits"
,
"set wav bit depth for subprocess input"
,
OFFSET
(
in_bit_depth
),
AV_OPT_TYPE_INT
,
{.
i64
=
32
},
0
,
32
,
A
},
{
NULL
},
};
AVFILTER_DEFINE_CLASS
(
asubprocess
);
static
av_cold
int
init
(
AVFilterContext
*
ctx
)
{
...
...
@@ -474,8 +479,9 @@ static av_cold void uninit(AVFilterContext *ctx)
av_freep
(
&
s
->
sample_buffer
);
}
static
int
write_wav_header
(
AVFilterContext
*
ctx
,
ASubProcessContext
*
s
,
int
nb_channels
,
int
sample_rate
)
static
int
write_wav_header
(
AVFilterContext
*
ctx
,
int
nb_channels
,
int
sample_rate
)
{
ASubProcessContext
*
s
=
ctx
->
priv
;
int
bit_depth
=
s
->
in_bit_depth
;
AVIOContext
*
wav_header
=
NULL
;
uint8_t
*
buffer
=
NULL
;
...
...
@@ -541,8 +547,9 @@ static void read_samples(ASubProcessContext *s, int32_t *data, int count)
}
}
static
int
write_samples
(
AVFilterContext
*
ctx
,
ASubProcessContext
*
s
,
int32_t
*
data
,
int
count
)
static
int
write_samples
(
AVFilterContext
*
ctx
,
int32_t
*
data
,
int
count
)
{
ASubProcessContext
*
s
=
ctx
->
priv
;
int
sample_size
=
s
->
in_bit_depth
/
8
;
int
bsize
=
count
*
4
;
/* allocate sample buffer for 32 bit per sample (required for conversions of input/output) */
if
(
s
->
sample_buffer_size
<
bsize
)
{
...
...
@@ -578,13 +585,14 @@ static int write_samples(AVFilterContext *ctx, ASubProcessContext *s, int32_t *d
return
sp_write
(
ctx
,
s
->
sample_buffer
,
sample_size
*
count
);
}
static
int
write_frame
(
AVFilterContext
*
ctx
,
A
SubProcessContext
*
s
,
A
VFilterLink
*
inlink
,
AVFrame
*
in
)
static
int
write_frame
(
AVFilterContext
*
ctx
,
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
ASubProcessContext
*
s
=
ctx
->
priv
;
AVFrame
*
out
;
int
ret
;
s
->
nb_input_samples
+=
in
->
nb_samples
;
ret
=
write_samples
(
ctx
,
s
,
(
int32_t
*
)
in
->
data
[
0
],
in
->
nb_samples
*
inlink
->
ch_layout
.
nb_channels
);
ret
=
write_samples
(
ctx
,
(
int32_t
*
)
in
->
data
[
0
],
in
->
nb_samples
*
inlink
->
ch_layout
.
nb_channels
);
if
(
ret
<
0
)
{
av_frame_free
(
&
in
);
return
ret
;
...
...
@@ -651,7 +659,7 @@ static int activate(AVFilterContext *ctx)
s
->
state
=
STATE_EXPECT_RIFF
;
ret
=
write_wav_header
(
ctx
,
s
,
inlink
->
ch_layout
.
nb_channels
,
inlink
->
sample_rate
);
ret
=
write_wav_header
(
ctx
,
inlink
->
ch_layout
.
nb_channels
,
inlink
->
sample_rate
);
if
(
ret
!=
0
)
return
ret
;
}
...
...
@@ -662,7 +670,7 @@ static int activate(AVFilterContext *ctx)
if
(
ret
<
0
)
return
ret
;
if
(
ret
>
0
)
{
ret
=
write_frame
(
ctx
,
s
,
inlink
,
in
);
ret
=
write_frame
(
ctx
,
inlink
,
in
);
if
(
ff_inlink_queued_samples
(
inlink
)
>=
0
)
ff_filter_set_ready
(
ctx
,
100
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment