Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
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
Hide 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
...
@@ -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
mainly useful as a template and to be employed in analysis / debugging
tools.
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
@c man end AUDIO SINKS
@chapter Video Filters
@chapter Video Filters
...
...
libavfilter/allfilters.c
View file @
a2cd9be2
...
@@ -103,6 +103,10 @@ void avfilter_register_all(void)
...
@@ -103,6 +103,10 @@ void avfilter_register_all(void)
extern
AVFilter
avfilter_vsink_buffer
;
extern
AVFilter
avfilter_vsink_buffer
;
avfilter_register
(
&
avfilter_vsink_buffer
);
avfilter_register
(
&
avfilter_vsink_buffer
);
}
}
{
extern
AVFilter
avfilter_asink_abuffer
;
avfilter_register
(
&
avfilter_asink_abuffer
);
}
{
{
extern
AVFilter
avfilter_vf_scale
;
extern
AVFilter
avfilter_vf_scale
;
avfilter_register
(
&
avfilter_vf_scale
);
avfilter_register
(
&
avfilter_vf_scale
);
...
...
libavfilter/buffersink.c
View file @
a2cd9be2
...
@@ -23,13 +23,20 @@
...
@@ -23,13 +23,20 @@
* buffer sink
* buffer sink
*/
*/
#include "libavutil/audio_fifo.h"
#include "libavutil/audioconvert.h"
#include "libavutil/fifo.h"
#include "libavutil/fifo.h"
#include "libavutil/mathematics.h"
#include "audio.h"
#include "avfilter.h"
#include "avfilter.h"
#include "buffersink.h"
#include "buffersink.h"
typedef
struct
{
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
;
}
BufferSinkContext
;
#define FIFO_INIT_SIZE 8
#define FIFO_INIT_SIZE 8
...
@@ -44,6 +51,9 @@ static av_cold void uninit(AVFilterContext *ctx)
...
@@ -44,6 +51,9 @@ static av_cold void uninit(AVFilterContext *ctx)
avfilter_unref_buffer
(
buf
);
avfilter_unref_buffer
(
buf
);
}
}
av_fifo_free
(
sink
->
fifo
);
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
)
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)
...
@@ -58,9 +68,8 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
return
0
;
return
0
;
}
}
static
void
end_frame
(
AVFilterLink
*
link
)
static
void
write_buf
(
AVFilterContext
*
ctx
,
AVFilterBufferRef
*
buf
)
{
{
AVFilterContext
*
ctx
=
link
->
dst
;
BufferSinkContext
*
sink
=
ctx
->
priv
;
BufferSinkContext
*
sink
=
ctx
->
priv
;
if
(
av_fifo_space
(
sink
->
fifo
)
<
sizeof
(
AVFilterBufferRef
*
)
&&
if
(
av_fifo_space
(
sink
->
fifo
)
<
sizeof
(
AVFilterBufferRef
*
)
&&
...
@@ -69,10 +78,20 @@ static void end_frame(AVFilterLink *link)
...
@@ -69,10 +78,20 @@ static void end_frame(AVFilterLink *link)
return
;
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
;
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
)
int
av_buffersink_read
(
AVFilterContext
*
ctx
,
AVFilterBufferRef
**
buf
)
{
{
BufferSinkContext
*
sink
=
ctx
->
priv
;
BufferSinkContext
*
sink
=
ctx
->
priv
;
...
@@ -98,6 +117,66 @@ int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
...
@@ -98,6 +117,66 @@ int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
return
0
;
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
=
{
AVFilter
avfilter_vsink_buffer
=
{
.
name
=
"buffersink"
,
.
name
=
"buffersink"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Buffer video frames, and make them available to the end of the filter graph."
),
.
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 = {
...
@@ -112,3 +191,18 @@ AVFilter avfilter_vsink_buffer = {
{
.
name
=
NULL
}},
{
.
name
=
NULL
}},
.
outputs
=
(
AVFilterPad
[])
{{
.
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 @@
...
@@ -29,7 +29,7 @@
/**
/**
* Get a buffer with filtered data from sink and put it in buf.
* 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
* @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().
* must be freed by the caller using avfilter_unref_buffer().
* Buf may also be NULL to query whether a buffer is ready to be
* Buf may also be NULL to query whether a buffer is ready to be
...
@@ -40,4 +40,23 @@
...
@@ -40,4 +40,23 @@
*/
*/
int
av_buffersink_read
(
AVFilterContext
*
sink
,
AVFilterBufferRef
**
buf
);
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 */
#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