1 STATIC
void dec_ctx_cfg(avcodec_params_t
*params
)
5 dec_l
= avcodec_find_dec(params
->codec_id
);
7 fatal("ffmpeg:unable to find a proper decoder\n");
8 avcodec_free_context(&dec_ctx_p
);
9 dec_ctx_p
= avcodec_alloc_ctx(dec_l
);
11 fatal("ffmpeg:unable to allocate a decoder context\n");
13 r
= avcodec_params_to_ctx(dec_ctx_p
, params
);
15 fatal("ffmpeg:unable to apply stream codec parameters in codec context\n");
16 /* XXX: ffmpeg thread count default is 1, set to 0 = auto */
17 dec_ctx_p
->thread_count
= 0;
18 r
= avcodec_open2(dec_ctx_p
, dec_l
, 0);
20 fatal("ffmpeg:unable to open the decoder context\n");
23 #define HAVE_DEC_SET 1
25 STATIC u8
dec_set_try_receive(void)
30 if (dec_sets_p
.eof_receive
)
32 if (dec_sets_p
.n
== dec_sets_p
.n_max
)
35 /* will unref any previous dec_sets_p.a[x] bufs for us */
36 r
= avcodec_receive_audio_set(dec_ctx_p
, dec_sets_p
.a
[last
]);
37 if (r
== AVUTIL_AVERROR(EAGAIN
))
42 npv_perr("DEBUG:audio:received set pts=%ld\n", dec_sets_p
.a
[last
]->pts
);
46 } else if (r
== AVUTIL_AVERROR_EOF
) {
47 pout("ffmpeg:last decoder set of frames reached (receiving)\n");
48 dec_sets_p
.eof_receive
= true;
51 fatal("ffmpeg:error while receiving a set of frames from the decoder\n");
57 #define HAVE_DEC_SET 1
60 * this can be long and we don't want to lock that long the q of audio frs
61 * for the alsa writer, then do finer-grained locking here
63 STATIC
void dec_sets_receive_avail(void) { loop
69 r
= dec_set_try_receive();
72 if (r
== HAVE_DEC_SET
)
74 else if (r
== AGAIN
|| r
== EOF_DEC
)
80 STATIC
void draining_state_evt(void)
85 r
= read(draining_timer_fd_p
, &exps_n
, sizeof(exps_n
));
87 fatal("unable to read the number of draining state timer expirations\n");
88 draining_state_handle();
92 #define INCOMPLETE_WRITE 1
94 STATIC
void evt_pcm_write(void)
97 snd_pcm_sfrs_t alsa_r
;
98 snd_pcm_ufrs_t ufrs_n
;
101 pre_x
= atomic_load(&npv_pre_x_p
);
102 if (pre_x
!= NONE
) /* TODO: play silence here */
104 alsa_r
= snd_pcm_avail(pcm_p
);
105 r
= alsa_recover(alsa_r
);
106 if (r
== AGAIN
|| r
== RECOVERED
)
109 ufrs_n
= (snd_pcm_ufrs_t
)alsa_r
;
111 pcm_silence_frs_write(ufrs_n
);
114 r
= pcm_filt_frs_write(&ufrs_n
);
115 if (r
== INCOMPLETE_WRITE
)
116 pcm_silence_frs_write(ufrs_n
);
117 /* DRAINING | ALL_FRS_WRITTEN | RECOVERED */
121 #undef INCOMPLETE_WRITE
123 STATIC
void pcm_silence_bufs_cfg(snd_pcm_t
*pcm
, bool print_info
)
126 snd_pcm_hw_params_t
*hw_params
;
127 snd_pcm_ufrs_t buf_ufrs_n
;
129 snd_pcm_access_t access
;
130 unsigned int chans_n
;
133 r
= snd_pcm_hw_params_malloc(&hw_params
);
135 fatal("silence:alsa:unable to allocate memory for a hardware parameters container\n");
136 r
= snd_pcm_hw_params_current(pcm
, hw_params
);
138 fatal("silence:alsa:unable to get the pcm hardware parameters\n");
139 r
= snd_pcm_hw_params_get_buf_sz(hw_params
, &buf_ufrs_n
);
141 fatal("silence:alsa:unable to get the number of frames in the pcm buffer\n");
142 r
= snd_pcm_hw_params_get_format(hw_params
, &fmt
);
144 fatal("silence:alsa:unable to get the pcm format\n");
145 r
= snd_pcm_hw_params_get_access(hw_params
, &access
);
147 fatal("silence:alsa:unable to get the pcm access mode\n");
148 r
= snd_pcm_hw_params_get_channels(hw_params
, &chans_n
);
150 fatal("silence:alsa:unable to get the pcm number of channels\n");
152 /* wipe silence bufs first */
155 if (c
== AVUTIL_DATA_PTRS_N
)
157 if (pcm_silence_bufs_l
[c
] != 0) {
158 free(pcm_silence_bufs_l
[c
]);
159 pcm_silence_bufs_l
[c
] = 0;
163 if (access
== SND_PCM_ACCESS_RW_INTERLEAVED
164 || access
== SND_PCM_ACCESS_MMAP_INTERLEAVED
) {
167 buf_bytes_n
= snd_pcm_frames_to_bytes(pcm
,
168 (snd_pcm_sframes_t
)buf_ufrs_n
);
169 if (buf_bytes_n
<= 0)
170 fatal("silence:alsa:interleaved:unable to get the pcm number of bytes of all buffer frames\n");
171 pcm_silence_bufs_l
[0] = malloc((size_t)buf_bytes_n
);
172 if (pcm_silence_bufs_l
[0] == 0)
173 fatal("silence:interleaved:unable to allocate the silence buffer of %d bytes\n", (int)buf_bytes_n
);
175 pout("silence:interleaved:buffer of %d bytes is allocated\n", (int)buf_bytes_n
);
176 r
= snd_pcm_format_set_silence(fmt
, pcm_silence_bufs_l
[0],
177 (unsigned int)buf_ufrs_n
);
179 fatal("silence:interleaved:unable to fill with silence the buffer\n");
180 pout("silence:interleaved:silence buffer filled with %u silence frames\n", buf_ufrs_n
);
181 } else if (access
== SND_PCM_ACCESS_RW_NONINTERLEAVED
182 || access
== SND_PCM_ACCESS_MMAP_NONINTERLEAVED
) {
186 buf_samples_n
= (long)buf_ufrs_n
;
187 buf_bytes_n
= snd_pcm_samples_to_bytes(pcm
, buf_samples_n
);
188 if (buf_bytes_n
<= 0)
189 fatal("silence:alsa:non interleaved:unable to get the pcm number of total bytes of all buffer samples\n");
194 pcm_silence_bufs_l
[c
] = malloc((size_t)buf_bytes_n
);
195 if (pcm_silence_bufs_l
[c
] == 0)
196 fatal("silence:non interleaved:unable to allocate silence buffer %u of %d bytes\n", c
, (int)buf_bytes_n
);
197 r
= snd_pcm_format_set_silence(fmt
,
198 pcm_silence_bufs_l
[c
],
199 (unsigned int)buf_samples_n
);
201 fatal("silence:non interleaved:unable to fill with silence the buffer\n");
203 pout("silence:non interleaved:buffer[%u] of %d bytes is allocated\n", c
, (int)buf_bytes_n
);
207 pout("silence:non interleaved:allocated %u silence buffers for %u frames\n", chans_n
, (unsigned int)buf_ufrs_n
);
209 fatal("silence:the pcm access type is not supported\n");
210 snd_pcm_hw_params_free(hw_params
);
212 STATIC
void init_once(u8
*pcm_str
)
215 init_once_public(pcm_str
);
217 STATIC
void dec_flush(void)
219 npv_pkt_q_unref_all(pkt_q_p
);
221 dec_sets_p
.eof_receive
= false;
222 avcodec_flush_bufs(dec_ctx_p
);
224 STATIC
void dec_ctx_lock(void)
228 r
= pthread_mutex_lock(&dec_ctx_mutex_l
);
230 fatal("%d:unable to lock the decoder context\n", r
);
232 STATIC
void dec_ctx_unlock(void)
236 r
= pthread_mutex_unlock(&dec_ctx_mutex_l
);
238 fatal("%d:unable to unlock the decoder context\n", r
);
240 STATIC
void dec_sets_lock(void)
244 r
= pthread_mutex_lock(&dec_sets_p
.mutex
);
246 fatal("%d:unable to lock the array of decoder sets\n", r
);
248 STATIC
void dec_sets_unlock(void)
252 r
= pthread_mutex_unlock(&dec_sets_p
.mutex
);
254 fatal("%d:unable to unlock the array of decoder sets\n", r
);
256 STATIC
void pcm_cfg_hw_best_effort(snd_pcm_t
*pcm
, int chans_n
, int rate
,
257 enum avutil_audio_fr_fmt_t ff_fmt
)
261 snd_pcm_access_t access
;
262 snd_pcm_hw_params_t
*hw_params
;
264 pout("ALSA:HW_PARAMS START------------------------------------------------------------\n");
265 r
= snd_pcm_hw_params_malloc(&hw_params
);
267 fatal("alsa:unable to allocate hardware parameters context\n");
268 pcm_cfg_hw_core_best_effort(pcm
, hw_params
, chans_n
, rate
, ff_fmt
);
269 r
= snd_pcm_hw_params(pcm
, hw_params
);
271 fatal("alsa:unable to install the hardware parameters\n");
272 r
= snd_pcm_hw_params_current(pcm
, hw_params
);
274 fatal("alsa:unable to get current hardware parameters\n");
275 snd_pcm_hw_params_dump(hw_params
, pcm_pout_l
);
277 selected_ts_type_p
= -1;
279 if (i
== ARRAY_N(kernel_ts_types_str_l
))
281 r
= snd_pcm_hw_params_supports_audio_ts_type(hw_params
, i
);
283 selected_ts_type_p
= i
;
284 pout("kernel audio timestamp type \"%s\" is supported for the current configuration\n", kernel_ts_types_str_l
[i
]);
289 * we selected the most accurate, namely with the highest idx, audio ts
292 pout("%s will be used for the audio based clock\n", kernel_ts_types_str_l
[selected_ts_type_p
]);
293 snd_pcm_hw_params_free(hw_params
);
294 pout("ALSA:HW_PARAMS END--------------------------------------------------------------\n");
296 STATIC
void pcm_cfg_sw(snd_pcm_t
*pcm
)
299 snd_pcm_sw_params_t
*sw_params
;
301 pout("ALSA:SW_PARAMS START------------------------------------------------------------\n");
302 r
= snd_pcm_sw_params_malloc(&sw_params
);
304 fatal("alsa:unable to allocate software parameters structure\n");
305 r
= snd_pcm_sw_params_current(pcm
, sw_params
);
307 fatal("alsa:unable to get current software parameters\n");
308 r
= snd_pcm_sw_params_set_period_evt(pcm
, sw_params
, 1);
310 fatal("alsa:unable to enable period event\n");
311 /* enable ts to be sure */
312 r
= snd_pcm_sw_params_set_tstamp_mode(pcm
, sw_params
,
313 SND_PCM_TSTAMP_ENABLE
);
315 fatal("unable to set timestamp mode:%s\n", snd_strerror(r
));
316 r
= snd_pcm_sw_params(pcm
, sw_params
);
318 fatal("alsa:unable to install sotfware parameters\n");
319 snd_pcm_sw_params_dump(sw_params
, pcm_pout_l
);
320 snd_pcm_sw_params_free(sw_params
);
321 pout("ALSA:SW_PARAMS END--------------------------------------------------------------\n");
323 /* we do per-loop fine-grained locking */
325 STATIC
void pkts_send(void) { loop
328 avcodec_pkt_ref_t
*pr
;
330 npv_pkt_q_lock(pkt_q_p
);
332 goto unlock_and_return
;
335 r
= avcodec_send_pkt(dec_ctx_p
, pr
);
337 if (r
== AVERROR(EAGAIN
)) /* dec is full and the pkt is rejected */
338 goto unlock_and_return
;
339 else if (r
== AVUTIL_AVERROR_EOF
) /* the dec is in draining mode */
340 goto unlock_and_return
;
342 fatal("error while sending a packet to the decoder\n");
344 npv_pipeline_limits_lock();
345 npv_pipeline_limits_p
.pkts
.audio_bytes_n
-= pr
->sz
;
346 npv_pipeline_limits_unlock();
348 npv_pkt_q_deq(pkt_q_p
);
349 avcodec_pkt_unref(pr
);
350 npv_pkt_q_unlock(pkt_q_p
);
354 npv_pkt_q_unlock(pkt_q_p
);
358 #define CHANS_N_NOT_OVERRIDDEN 0
359 #define RATE_NOT_OVERRIDDEN 0
360 #define AUDIO_FR_FMT_NOT_OVERRIDDEN AVUTIL_AUDIO_FR_FMT_NONE
361 #define PRINT_INFO true
362 STATIC
void npv_audio_prepare(int override_initial_ff_chans_n
,
363 int override_initial_ff_rate
,
364 enum avutil_audio_fr_fmt_t override_initial_ff_fmt
)
367 enum avutil_audio_fr_fmt_t dst_fmt
;
368 int initial_ff_chans_n
;
370 enum avutil_audio_fr_fmt_t initial_ff_fmt
;
374 * do our best to match the pcm cfg to audio ff dec output OR the user
375 * overrides, BUT we don't expect to match it "exactly": a ff filt
376 * will bridge the difference
378 if (override_initial_ff_chans_n
== CHANS_N_NOT_OVERRIDDEN
)
379 /* we presume the dec_ctx has at least a valid chans_n */
380 initial_ff_chans_n
= dec_ctx_p
->ch_layout
.nb_channels
;
382 initial_ff_chans_n
= override_initial_ff_chans_n
;
383 if (override_initial_ff_rate
== RATE_NOT_OVERRIDDEN
)
384 initial_ff_rate
= dec_ctx_p
->fr_rate
;
386 initial_ff_rate
= override_initial_ff_rate
;
387 if (override_initial_ff_fmt
== AUDIO_FR_FMT_NOT_OVERRIDDEN
)
388 initial_ff_fmt
= dec_ctx_p
->fr_fmt
;
390 initial_ff_fmt
= override_initial_ff_fmt
;
391 npv_audio_pcm_cfg_hw_best_effort(pcm_p
, initial_ff_chans_n
,
392 initial_ff_rate
, initial_ff_fmt
);
393 npv_audio_pcm_silence_bufs_cfg(pcm_p
, PRINT_INFO
);
394 npv_audio_pcm_cfg_sw(pcm_p
);
395 pout("ALSA PCM DUMP START-------------------------------------------------------------\n");
396 snd_pcm_dump(pcm_p
, pcm_pout_l
);
397 pout("ALSA PCM DUMP END---------------------------------------------------------------\n");
399 #undef CHANS_N_NOT_OVERRIDDEN
400 #undef RATE_NOT_OVERRIDDEN
401 #undef AUDIO_FR_FMT_NOT_OVERRIDDEN