Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
a2cd9be2
Commit
a2cd9be2
authored
May 04, 2012
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi: add an audio buffer sink.
parent
4c66c407
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
129 additions
and
5 deletions
+129
-5
filters.texi
doc/filters.texi
+7
-0
allfilters.c
libavfilter/allfilters.c
+4
-0
buffersink.c
libavfilter/buffersink.c
+98
-4
buffersink.h
libavfilter/buffersink.h
+20
-1
No files found.
doc/filters.texi
View file @
a2cd9be2
...
...
@@ -191,6 +191,13 @@ Null audio sink, do absolutely nothing with the input audio. It is
mainly useful as a template and to be employed in analysis / debugging
tools.
@section abuffersink
This sink is intended for programmatic use. Frames that arrive on this sink can
be retrieved by the calling program using the interface defined in
@file{libavfilter/buffersink.h}.
This filter accepts no parameters.
@c man end AUDIO SINKS
@chapter Video Filters
...
...
libavfilter/allfilters.c
View file @
a2cd9be2
...
...
@@ -103,6 +103,10 @@ void avfilter_register_all(void)
extern
AVFilter
avfilter_vsink_buffer
;
avfilter_register
(
&
avfilter_vsink_buffer
);
}
{
extern
AVFilter
avfilter_asink_abuffer
;
avfilter_register
(
&
avfilter_asink_abuffer
);
}
{
extern
AVFilter
avfilter_vf_scale
;
avfilter_register
(
&
avfilter_vf_scale
);
...
...
libavfilter/buffersink.c
View file @
a2cd9be2
...
...
@@ -23,13 +23,20 @@
* buffer sink
*/
#include "libavutil/audio_fifo.h"
#include "libavutil/audioconvert.h"
#include "libavutil/fifo.h"
#include "libavutil/mathematics.h"
#include "audio.h"
#include "avfilter.h"
#include "buffersink.h"
typedef
struct
{
AVFifoBuffer
*
fifo
;
///< FIFO buffer of video frame references
AVFifoBuffer
*
fifo
;
///< FIFO buffer of frame references
AVAudioFifo
*
audio_fifo
;
///< FIFO for audio samples
int64_t
next_pts
;
///< interpolating audio pts
}
BufferSinkContext
;
#define FIFO_INIT_SIZE 8
...
...
@@ -44,6 +51,9 @@ static av_cold void uninit(AVFilterContext *ctx)
avfilter_unref_buffer
(
buf
);
}
av_fifo_free
(
sink
->
fifo
);
if
(
sink
->
audio_fifo
)
av_audio_fifo_free
(
sink
->
audio_fifo
);
}
static
av_cold
int
init
(
AVFilterContext
*
ctx
,
const
char
*
args
,
void
*
opaque
)
...
...
@@ -58,9 +68,8 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
return
0
;
}
static
void
end_frame
(
AVFilterLink
*
link
)
static
void
write_buf
(
AVFilterContext
*
ctx
,
AVFilterBufferRef
*
buf
)
{
AVFilterContext
*
ctx
=
link
->
dst
;
BufferSinkContext
*
sink
=
ctx
->
priv
;
if
(
av_fifo_space
(
sink
->
fifo
)
<
sizeof
(
AVFilterBufferRef
*
)
&&
...
...
@@ -69,10 +78,20 @@ static void end_frame(AVFilterLink *link)
return
;
}
av_fifo_generic_write
(
sink
->
fifo
,
&
link
->
cur_buf
,
sizeof
(
link
->
cur_buf
),
NULL
);
av_fifo_generic_write
(
sink
->
fifo
,
&
buf
,
sizeof
(
buf
),
NULL
);
}
static
void
end_frame
(
AVFilterLink
*
link
)
{
write_buf
(
link
->
dst
,
link
->
cur_buf
);
link
->
cur_buf
=
NULL
;
}
static
void
filter_samples
(
AVFilterLink
*
link
,
AVFilterBufferRef
*
buf
)
{
write_buf
(
link
->
dst
,
buf
);
}
int
av_buffersink_read
(
AVFilterContext
*
ctx
,
AVFilterBufferRef
**
buf
)
{
BufferSinkContext
*
sink
=
ctx
->
priv
;
...
...
@@ -98,6 +117,66 @@ int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
return
0
;
}
static
int
read_from_fifo
(
AVFilterContext
*
ctx
,
AVFilterBufferRef
**
pbuf
,
int
nb_samples
)
{
BufferSinkContext
*
s
=
ctx
->
priv
;
AVFilterLink
*
link
=
ctx
->
inputs
[
0
];
AVFilterBufferRef
*
buf
;
if
(
!
(
buf
=
ff_get_audio_buffer
(
link
,
AV_PERM_WRITE
,
nb_samples
)))
return
AVERROR
(
ENOMEM
);
av_audio_fifo_read
(
s
->
audio_fifo
,
(
void
**
)
buf
->
extended_data
,
nb_samples
);
buf
->
pts
=
s
->
next_pts
;
s
->
next_pts
+=
av_rescale_q
(
nb_samples
,
(
AVRational
){
1
,
link
->
sample_rate
},
link
->
time_base
);
*
pbuf
=
buf
;
return
0
;
}
int
av_buffersink_read_samples
(
AVFilterContext
*
ctx
,
AVFilterBufferRef
**
pbuf
,
int
nb_samples
)
{
BufferSinkContext
*
s
=
ctx
->
priv
;
AVFilterLink
*
link
=
ctx
->
inputs
[
0
];
int
ret
=
0
;
if
(
!
s
->
audio_fifo
)
{
int
nb_channels
=
av_get_channel_layout_nb_channels
(
link
->
channel_layout
);
if
(
!
(
s
->
audio_fifo
=
av_audio_fifo_alloc
(
link
->
format
,
nb_channels
,
nb_samples
)))
return
AVERROR
(
ENOMEM
);
}
while
(
ret
>=
0
)
{
AVFilterBufferRef
*
buf
;
if
(
av_audio_fifo_size
(
s
->
audio_fifo
)
>=
nb_samples
)
return
read_from_fifo
(
ctx
,
pbuf
,
nb_samples
);
ret
=
av_buffersink_read
(
ctx
,
&
buf
);
if
(
ret
==
AVERROR_EOF
&&
av_audio_fifo_size
(
s
->
audio_fifo
))
return
read_from_fifo
(
ctx
,
pbuf
,
av_audio_fifo_size
(
s
->
audio_fifo
));
else
if
(
ret
<
0
)
return
ret
;
if
(
buf
->
pts
!=
AV_NOPTS_VALUE
)
{
s
->
next_pts
=
buf
->
pts
-
av_rescale_q
(
av_audio_fifo_size
(
s
->
audio_fifo
),
(
AVRational
){
1
,
link
->
sample_rate
},
link
->
time_base
);
}
ret
=
av_audio_fifo_write
(
s
->
audio_fifo
,
(
void
**
)
buf
->
extended_data
,
buf
->
audio
->
nb_samples
);
avfilter_unref_buffer
(
buf
);
}
return
ret
;
}
AVFilter
avfilter_vsink_buffer
=
{
.
name
=
"buffersink"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Buffer video frames, and make them available to the end of the filter graph."
),
...
...
@@ -112,3 +191,18 @@ AVFilter avfilter_vsink_buffer = {
{
.
name
=
NULL
}},
.
outputs
=
(
AVFilterPad
[])
{{
.
name
=
NULL
}},
};
AVFilter
avfilter_asink_abuffer
=
{
.
name
=
"abuffersink"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Buffer audio frames, and make them available to the end of the filter graph."
),
.
priv_size
=
sizeof
(
BufferSinkContext
),
.
init
=
init
,
.
uninit
=
uninit
,
.
inputs
=
(
AVFilterPad
[])
{{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
filter_samples
=
filter_samples
,
.
min_perms
=
AV_PERM_READ
,
},
{
.
name
=
NULL
}},
.
outputs
=
(
AVFilterPad
[])
{{
.
name
=
NULL
}},
};
libavfilter/buffersink.h
View file @
a2cd9be2
...
...
@@ -29,7 +29,7 @@
/**
* Get a buffer with filtered data from sink and put it in buf.
*
* @param sink pointer to a context of a buffersink AVFilter.
* @param sink pointer to a context of a buffersink
or abuffersink
AVFilter.
* @param buf pointer to the buffer will be written here if buf is non-NULL. buf
* must be freed by the caller using avfilter_unref_buffer().
* Buf may also be NULL to query whether a buffer is ready to be
...
...
@@ -40,4 +40,23 @@
*/
int
av_buffersink_read
(
AVFilterContext
*
sink
,
AVFilterBufferRef
**
buf
);
/**
* Same as av_buffersink_read, but with the ability to specify the number of
* samples read. This function is less efficient than av_buffersink_read(),
* because it copies the data around.
*
* @param sink pointer to a context of the abuffersink AVFilter.
* @param buf pointer to the buffer will be written here if buf is non-NULL. buf
* must be freed by the caller using avfilter_unref_buffer(). buf
* will contain exactly nb_samples audio samples, except at the end
* of stream, when it can contain less than nb_samples.
* Buf may also be NULL to query whether a buffer is ready to be
* output.
*
* @warning do not mix this function with av_buffersink_read(). Use only one or
* the other with a single sink, not both.
*/
int
av_buffersink_read_samples
(
AVFilterContext
*
ctx
,
AVFilterBufferRef
**
buf
,
int
nb_samples
);
#endif
/* AVFILTER_BUFFERSINK_H */
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