3 #define PUSHED_ONE_SET 1
5 #define FILT_SWITCHED_TO_DRAINING 3
6 #define FILT_RECFG_REQUIRED 4
7 STATIC u8
filt_push_dec_set(int *new_chans_n
, uint64_t *new_chans_layout
,
8 int *new_rate
, enum avutil_audio_fr_fmt_t
*new_fmt
)
12 avutil_audio_set_ref_t
**a
;
14 npv_audio_dec_sets_lock();
15 if (npv_audio_dec_sets_p
.n
== 0) {
16 if (npv_audio_dec_sets_p
.eof_receive
) {
17 ri
= avfilter_bufsrc_add_audio_set_flags(abufsrc_l
.ctx
,
18 0, AVFILTER_BUFSRC_FLAG_KEEP_REF
);
20 fatal("ffmpeg:unable to notify the end of data to the filter source audio buffer context\n");
21 pout("ffmpeg:interactive filter switched to draining\n");
22 r8
= FILT_SWITCHED_TO_DRAINING
;
28 a
= npv_audio_dec_sets_p
.a
;
30 * XXX: this is were dynamic audio recfg is triggered and we get out of
31 * the critical section asap
33 if (is_recfg_required(a
[0])) {
34 /* because we are in a critical section */
35 *new_chans_n
= a
[0]->chans_n
;
36 *new_chans_layout
= a
[0]->chans_layout
;
37 *new_rate
= a
[0]->rate
;
39 r8
= FILT_RECFG_REQUIRED
;
42 /* the dec_sets_p bufs will be unref in avcodec_audio_receive_set */
43 ri
= avfilter_bufsrc_add_audio_set_flags(abufsrc_l
.ctx
, a
[0],
44 AVFILTER_BUFSRC_FLAG_KEEP_REF
);
46 /* rotate the ptrs if needed */
47 if (npv_audio_dec_sets_p
.n
> 1) {
48 avutil_audio_set_ref_t
*save
;
51 memmove(&a
[0], &a
[1], sizeof(*a
)
52 * (npv_audio_dec_sets_p
.n
- 1));
53 a
[npv_audio_dec_sets_p
.n
- 1] = save
;
55 npv_audio_dec_sets_p
.n
--;
58 } else if (ri
== AVERROR(EAGAIN
)) {
62 fatal("ffmpeg:unable to submit a decoder set of frames to the filter source audio buffer context\n");
64 npv_audio_dec_sets_unlock();
70 #undef PUSHED_NULL_SET
71 #undef FILT_SWITCHED_TO_DRAINING
72 #undef FILT_RECFG_REQUIRED
73 #define HAVE_FILT_SET 1
75 STATIC u8
filt_set_get(void)
79 * the last dec set should switch the filt in draining mode, and
80 * filt_p.set won't matter.
82 r
= avfilter_bufsink_get_audio_set(abufsink_ctx_l
, filt_p
.set
);
84 filt_p
.pcm_written_ufrs_n
= 0;
86 } else if (r
== AVUTIL_AVERROR_EOF
) {
89 fatal("ffmpeg:error while getting frames from the filter\n");
93 #define DONT_PRINT_INFO false
94 STATIC
void filt_flush(void)
97 enum avutil_audio_fr_fmt_t dst_fmt
;
98 uint64_t src_chans_layout
;
99 uint64_t dst_chans_layout
;
102 avutil_audio_set_unref(filt_p
.set
);
103 filt_p
.pcm_written_ufrs_n
= 0;
105 npv_audio_pcm2ff_strict(npv_audio_pcm_p
, &dst_chans_n
,
106 &dst_chans_layout
, &dst_rate
, &dst_fmt
, DONT_PRINT_INFO
);
107 /* the audio dec ctx may not have a valid chans layout */
108 if (npv_audio_dec_ctx_p
->chans_layout
== 0)
109 src_chans_layout
= avutil_get_default_chans_layout(
110 npv_audio_dec_ctx_p
->chans_n
);
112 src_chans_layout
= npv_audio_dec_ctx_p
->chans_layout
;
113 cfg(npv_audio_dec_ctx_p
->chans_n
, src_chans_layout
,
114 npv_audio_dec_ctx_p
->fr_rate
, npv_audio_dec_ctx_p
->fr_fmt
,
115 filt_p
.muted
, filt_p
.vol
,
116 dst_chans_n
, dst_chans_layout
, dst_rate
, dst_fmt
,
119 #undef DONT_PRINT_INFO
120 STATIC
void init_once(double initial_vol
)
123 init_once_public(initial_vol
);
125 STATIC
void cfg(int src_chans_n
, uint64_t src_chans_layout
, int src_rate
,
126 enum avutil_audio_fr_fmt_t src_fmt
,
127 bool muted
, double vol
,
128 int dst_chans_n
, uint64_t dst_chans_layout
, int dst_rate
,
129 enum avutil_audio_fr_fmt_t dst_fmt
,
135 avfilter_graph_free(&graph_l
);
137 graph_l
= avfilter_graph_alloc();
139 fatal("unable to create filter graph\n");
140 abufsrc_cfg(src_chans_n
, src_chans_layout
, src_rate
, src_fmt
,
142 /*--------------------------------------------------------------------*/
143 abufsrc_l
.key
.chans_n
= src_chans_n
;
144 abufsrc_l
.key
.chans_layout
= src_chans_layout
;
145 abufsrc_l
.key
.rate
= src_rate
;
146 abufsrc_l
.key
.fmt
= src_fmt
;
147 /*--------------------------------------------------------------------*/
149 afmt_cfg(dst_chans_n
, dst_chans_layout
, dst_rate
, dst_fmt
, print_info
);
151 r
= avfilter_link(abufsrc_l
.ctx
, 0, vol_ctx_l
, 0);
153 fatal("unable to connect the audio buffer source filter to the volume filter\n");
154 r
= avfilter_link(vol_ctx_l
, 0, afmt_ctx_l
, 0);
156 fatal("unable to connect the volume filter to the audio format filter\n");
157 r
= avfilter_link(afmt_ctx_l
, 0, abufsink_ctx_l
, 0);
159 fatal("unable to connect the audio format filter to the audio buffer sink filter\n");
160 r
= avfilter_graph_config(graph_l
, 0);
162 fatal("unable to configure the filter graph\n");
165 dump_str
= avfilter_graph_dump(graph_l
, 0);
167 warning("unable to get a filter graph description\n");
170 pout("GRAPH START-------------------------------------------------------\n");
171 npv_pout("%s", dump_str
);
172 avutil_free(dump_str
);
173 pout("GRAPH END---------------------------------------------------------\n");
175 STATIC
void npv_audio_filt_cmd_mute(void)
178 u8 vol_l10n_str
[sizeof("xxx.xx")]; /* should be overkill */
182 pout("COMMAND:unmuting\n");
184 snprintf(vol_l10n_str
, sizeof(vol_l10n_str
), "%f", filt_p
.vol
);
185 r
= avfilter_graph_send_cmd(graph_l
, "vol", "volume",
186 vol_l10n_str
, resp
, sizeof(resp
), 0);
188 warning("ffmpeg:volume context:unable to mute the volume to 0:response from volume filter:%s\n", resp
);
190 filt_p
.muted
= false;
193 pout("COMMAND:muting\n");
195 r
= avfilter_graph_send_cmd(graph_l
, "vol", "volume",
196 double_zero_l10n_str_l
, resp
, sizeof(resp
), 0);
198 warning("ffmpeg:volume context:unable to mute the volume to 0:response from volume filter:%s\n", resp
);
204 STATIC
void npv_audio_filt_cmd_vol_down(void)
207 u8 vol_l10n_str
[sizeof("xxx.xx")]; /* should be overkill */
210 filt_p
.vol
-= VOL_DELTA
;
213 snprintf(vol_l10n_str
, sizeof(vol_l10n_str
), "%f", filt_p
.vol
);
214 pout("COMMAND:volume down to value %s\n", vol_l10n_str
);
216 r
= avfilter_graph_send_cmd(graph_l
, "vol", "volume",
217 vol_l10n_str
, resp
, sizeof(resp
), 0);
219 warning("ffmpeg:volume context:unable to set the volume down to \"%s\":response from volume filter:\"%s\"\n", resp
);
222 STATIC
void npv_audio_filt_cmd_vol_up(void)
225 u8 vol_l10n_str
[sizeof("xxx.xx")]; /* should be overkill */
228 filt_p
.vol
+= VOL_DELTA
;
231 snprintf(vol_l10n_str
, sizeof(vol_l10n_str
), "%f", filt_p
.vol
);
232 pout("COMMAND:volume up to value %s\n", vol_l10n_str
);
234 r
= avfilter_graph_send_cmd(graph_l
, "vol", "volume",
235 vol_l10n_str
, resp
, sizeof(resp
), 0);
237 warning("ffmpeg:volume context:unable to set the volume up to \"%s\":response from volume filter:\"%s\"\n", resp
);