FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavfilter
buffersink.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2011 Stefano Sabatini
3
*
4
* This file is part of FFmpeg.
5
*
6
* FFmpeg is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* FFmpeg is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with FFmpeg; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20
21
/**
22
* @file
23
* buffer sink
24
*/
25
26
#include "
libavutil/audio_fifo.h
"
27
#include "
libavutil/avassert.h
"
28
#include "
libavutil/channel_layout.h
"
29
#include "
libavutil/common.h
"
30
#include "
libavutil/mathematics.h
"
31
32
#include "
audio.h
"
33
#include "
avfilter.h
"
34
#include "
buffersink.h
"
35
#include "
internal.h
"
36
37
typedef
struct
{
38
AVFilterBufferRef
*
cur_buf
;
///< last buffer delivered on the sink
39
AVAudioFifo
*
audio_fifo
;
///< FIFO for audio samples
40
int64_t
next_pts
;
///< interpolating audio pts
41
}
BufferSinkContext
;
42
43
static
av_cold
void
uninit
(
AVFilterContext
*ctx)
44
{
45
BufferSinkContext
*sink = ctx->
priv
;
46
47
if
(sink->
audio_fifo
)
48
av_audio_fifo_free
(sink->
audio_fifo
);
49
}
50
51
static
int
filter_frame
(
AVFilterLink
*link,
AVFilterBufferRef
*buf)
52
{
53
BufferSinkContext
*s = link->
dst
->
priv
;
54
55
// av_assert0(!s->cur_buf);
56
s->
cur_buf
= buf;
57
58
return
0;
59
}
60
61
int
ff_buffersink_read_compat
(
AVFilterContext
*ctx,
AVFilterBufferRef
**buf)
62
{
63
BufferSinkContext
*s = ctx->
priv
;
64
AVFilterLink
*link = ctx->
inputs
[0];
65
int
ret;
66
67
if
(!buf)
68
return
ff_poll_frame
(ctx->
inputs
[0]);
69
70
if
((ret =
ff_request_frame
(link)) < 0)
71
return
ret;
72
73
if
(!s->
cur_buf
)
74
return
AVERROR
(EINVAL);
75
76
*buf = s->
cur_buf
;
77
s->
cur_buf
=
NULL
;
78
79
return
0;
80
}
81
82
static
int
read_from_fifo
(
AVFilterContext
*ctx,
AVFilterBufferRef
**pbuf,
83
int
nb_samples
)
84
{
85
BufferSinkContext
*s = ctx->
priv
;
86
AVFilterLink
*link = ctx->
inputs
[0];
87
AVFilterBufferRef
*buf;
88
89
if
(!(buf =
ff_get_audio_buffer
(link,
AV_PERM_WRITE
, nb_samples)))
90
return
AVERROR
(ENOMEM);
91
av_audio_fifo_read
(s->
audio_fifo
, (
void
**)buf->
extended_data
, nb_samples);
92
93
buf->
pts
= s->
next_pts
;
94
s->
next_pts
+=
av_rescale_q
(nb_samples, (
AVRational
){1, link->
sample_rate
},
95
link->
time_base
);
96
97
*pbuf = buf;
98
return
0;
99
100
}
101
102
int
ff_buffersink_read_samples_compat
(
AVFilterContext
*ctx,
AVFilterBufferRef
**pbuf,
103
int
nb_samples
)
104
{
105
BufferSinkContext
*s = ctx->
priv
;
106
AVFilterLink
*link = ctx->
inputs
[0];
107
int
ret = 0;
108
109
if
(!s->
audio_fifo
) {
110
int
nb_channels
=
av_get_channel_layout_nb_channels
(link->
channel_layout
);
111
if
(!(s->
audio_fifo
=
av_audio_fifo_alloc
(link->
format
, nb_channels, nb_samples)))
112
return
AVERROR
(ENOMEM);
113
}
114
115
while
(ret >= 0) {
116
AVFilterBufferRef
*buf;
117
118
if
(
av_audio_fifo_size
(s->
audio_fifo
) >= nb_samples)
119
return
read_from_fifo
(ctx, pbuf, nb_samples);
120
121
ret =
av_buffersink_read
(ctx, &buf);
122
if
(ret ==
AVERROR_EOF
&&
av_audio_fifo_size
(s->
audio_fifo
))
123
return
read_from_fifo
(ctx, pbuf,
av_audio_fifo_size
(s->
audio_fifo
));
124
else
if
(ret < 0)
125
return
ret;
126
127
if
(buf->
pts
!=
AV_NOPTS_VALUE
) {
128
s->
next_pts
= buf->
pts
-
129
av_rescale_q
(
av_audio_fifo_size
(s->
audio_fifo
),
130
(
AVRational
){ 1, link->
sample_rate
},
131
link->
time_base
);
132
}
133
134
ret =
av_audio_fifo_write
(s->
audio_fifo
, (
void
**)buf->extended_data,
135
buf->audio->
nb_samples
);
136
avfilter_unref_buffer
(buf);
137
}
138
139
return
ret;
140
}
141
142
static
const
AVFilterPad
avfilter_vsink_buffer_inputs
[] = {
143
{
144
.
name
=
"default"
,
145
.type =
AVMEDIA_TYPE_VIDEO
,
146
.filter_frame =
filter_frame
,
147
.min_perms =
AV_PERM_READ
,
148
.needs_fifo = 1
149
},
150
{
NULL
}
151
};
152
153
AVFilter
avfilter_vsink_buffer
= {
154
#if AV_HAVE_INCOMPATIBLE_FORK_ABI
155
.
name
=
"buffersink"
,
156
#else
157
.name =
"buffersink_old"
,
158
#endif
159
.description =
NULL_IF_CONFIG_SMALL
(
"Buffer video frames, and make them available to the end of the filter graph."
),
160
.priv_size =
sizeof
(
BufferSinkContext
),
161
.
uninit
=
uninit
,
162
163
.
inputs
= avfilter_vsink_buffer_inputs,
164
.
outputs
=
NULL
,
165
};
166
167
static
const
AVFilterPad
avfilter_asink_abuffer_inputs
[] = {
168
{
169
.
name
=
"default"
,
170
.type =
AVMEDIA_TYPE_AUDIO
,
171
.filter_frame =
filter_frame
,
172
.min_perms =
AV_PERM_READ
,
173
.needs_fifo = 1
174
},
175
{
NULL
}
176
};
177
178
AVFilter
avfilter_asink_abuffer
= {
179
#if AV_HAVE_INCOMPATIBLE_FORK_ABI
180
.
name
=
"abuffersink"
,
181
#else
182
.name =
"abuffersink_old"
,
183
#endif
184
.description =
NULL_IF_CONFIG_SMALL
(
"Buffer audio frames, and make them available to the end of the filter graph."
),
185
.priv_size =
sizeof
(
BufferSinkContext
),
186
.
uninit
=
uninit
,
187
188
.
inputs
= avfilter_asink_abuffer_inputs,
189
.
outputs
=
NULL
,
190
};
Generated on Sat May 25 2013 03:58:44 for FFmpeg by
1.8.2