1 STATIC
bool ff_fmt2pcm_layout_best_effort(enum avutil_audio_fr_fmt_t ff_fmt
,
2 snd_pcm_fmt_t
*alsa_fmt
, snd_pcm_access_t
*alsa_access
)
4 static u8 ff_fmt_str
[STR_SZ
];
6 avutil_get_audio_fr_fmt_str(ff_fmt_str
, STR_SZ
, ff_fmt
);
7 /* XXX: only classic non-mmap ones */
9 case AVUTIL_AUDIO_FR_FMT_U8
:
10 *alsa_fmt
= SND_PCM_FMT_U8
;
11 *alsa_access
= SND_PCM_ACCESS_RW_INTERLEAVED
;
13 case AVUTIL_AUDIO_FR_FMT_S16
:
14 *alsa_fmt
= SND_PCM_FMT_S16
;
15 *alsa_access
= SND_PCM_ACCESS_RW_INTERLEAVED
;
17 case AVUTIL_AUDIO_FR_FMT_S32
:
18 *alsa_fmt
= SND_PCM_FMT_S32
;
19 *alsa_access
= SND_PCM_ACCESS_RW_INTERLEAVED
;
21 case AVUTIL_AUDIO_FR_FMT_FLT
:
22 *alsa_fmt
= SND_PCM_FMT_FLOAT
;
23 *alsa_access
= SND_PCM_ACCESS_RW_INTERLEAVED
;
25 /* ff "planar" fmts are actually non interleaved fmts */
26 case AVUTIL_AUDIO_FR_FMT_U8P
:
27 *alsa_fmt
= SND_PCM_FMT_U8
;
28 *alsa_access
= SND_PCM_ACCESS_RW_NONINTERLEAVED
;
30 case AVUTIL_AUDIO_FR_FMT_S16P
:
31 *alsa_fmt
= SND_PCM_FMT_S16
;
32 *alsa_access
= SND_PCM_ACCESS_RW_NONINTERLEAVED
;
34 case AVUTIL_AUDIO_FR_FMT_S32P
:
35 *alsa_fmt
= SND_PCM_FMT_S32
;
36 *alsa_access
= SND_PCM_ACCESS_RW_NONINTERLEAVED
;
38 case AVUTIL_AUDIO_FR_FMT_FLTP
:
39 *alsa_fmt
= SND_PCM_FMT_FLOAT
;
40 *alsa_access
= SND_PCM_ACCESS_RW_NONINTERLEAVED
;
43 POUTA("best effort:unable to wire ffmpeg sample format \"%sbits\" to alsa sample format, \n,", ff_fmt_str
);
46 POUTA("best effort:ffmpeg format \"%sbits\" (%u bytes) to alsa layout \"%s\" and access \"%s\"\n", ff_fmt_str
, av_get_bytes_per_sample(ff_fmt
), snd_pcm_fmt_desc(*alsa_fmt
), snd_pcm_access_name(*alsa_access
));
49 STATIC
void pcm_hw_chans_n_decide(snd_pcm_t
*pcm
,
50 snd_pcm_hw_params_t
*pcm_hw_params
, unsigned int chans_n
)
53 unsigned int chans_n_max
;
54 unsigned int chans_n_min
;
56 r
= snd_pcm_hw_params_test_chans_n(pcm
, pcm_hw_params
, chans_n
);
58 r
= snd_pcm_hw_params_set_chans_n(pcm
, pcm_hw_params
, chans_n
);
60 FATALA("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n
);
61 POUTA("alsa:using %u channels\n", chans_n
);
64 POUTA("alsa:unable to use %u channels\n", chans_n
);
65 /* try to use the max chans n the pcm can */
66 r
= snd_pcm_hw_params_get_chans_n_max(pcm_hw_params
, &chans_n_max
);
68 FATALA("alsa:unable to get the maximum count of pcm device channels\n");
69 r
= snd_pcm_hw_params_test_chans_n(pcm
, pcm_hw_params
, chans_n_max
);
71 r
= snd_pcm_hw_params_set_chans_n(pcm
, pcm_hw_params
,
74 FATALA("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n_max
);
75 POUTA("alsa:using pcm maximum %u channels\n", chans_n_max
);
78 /* ok... last try, the pcm dev min chans n */
79 r
= snd_pcm_hw_params_get_chans_n_min(pcm_hw_params
, &chans_n_min
);
81 FATALA("alsa:unable to get the minimum count of pcm device channels\n");
82 r
= snd_pcm_hw_params_test_chans_n(pcm
, pcm_hw_params
, chans_n_min
);
84 r
= snd_pcm_hw_params_set_chans_n(pcm
, pcm_hw_params
,
87 FATALA("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n_min
);
88 POUTA("alsa:using pcm device minimum %u channels\n", chans_n_min
);
91 FATALA("alsa:unable to find a suitable count of channels\n");
93 STATIC
void pcm_hw_rate_decide(snd_pcm_t
*pcm
,
94 snd_pcm_hw_params_t
*pcm_hw_params
, unsigned int rate
)
97 unsigned int rate_max
;
98 unsigned int rate_near
;
99 unsigned int rate_min
;
101 r
= snd_pcm_hw_params_test_rate(pcm
, pcm_hw_params
, rate
,
102 SND_PCM_ST_PLAYBACK
);
104 r
= snd_pcm_hw_params_set_rate(pcm
, pcm_hw_params
, rate
,
105 SND_PCM_ST_PLAYBACK
);
107 FATALA("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate
);
108 POUTA("alsa:using %uHz\n", rate
);
111 POUTA("alsa:unable to use %uHz\n", rate
);
112 /* try to use the max rate the pcm can */
113 r
= snd_pcm_hw_params_get_rate_max(pcm_hw_params
, &rate_max
,
114 SND_PCM_ST_PLAYBACK
);
116 FATALA("alsa:unable to get the maximum rate of pcm device\n");
117 r
= snd_pcm_hw_params_test_rate(pcm
, pcm_hw_params
, rate_max
,
118 SND_PCM_ST_PLAYBACK
);
120 r
= snd_pcm_hw_params_set_rate(pcm
, pcm_hw_params
, rate_max
,
121 SND_PCM_ST_PLAYBACK
);
123 FATALA("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate_max
);
124 POUTA("alsa:using pcm device %uHz\n", rate_max
);
127 /* try to use a rate "near" of what the pcm dev can */
129 r
= snd_pcm_hw_params_set_rate_near(pcm
, pcm_hw_params
, &rate_near
,
130 SND_PCM_ST_PLAYBACK
);
132 POUTA("alsa:using pcm device %uHz\n", rate_near
);
135 /* even a "near" rate did failed... try the min */
136 r
= snd_pcm_hw_params_get_rate_min(pcm_hw_params
, &rate_min
,
137 SND_PCM_ST_PLAYBACK
);
139 FATALA("alsa:unable to get the minimum rate of pcm device\n");
140 r
= snd_pcm_hw_params_test_rate(pcm
, pcm_hw_params
, rate_min
,
141 SND_PCM_ST_PLAYBACK
);
143 r
= snd_pcm_hw_params_set_rate(pcm
, pcm_hw_params
, rate_min
,
144 SND_PCM_ST_PLAYBACK
);
146 FATALA("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate_min
);
147 POUTA("alsa:using pcm device %uHz\n", rate_min
);
150 FATALA("alsa:unable to find a suitable rate\n");
152 STATIC
bool pcm_hw_fmt_decide_x(snd_pcm_t
*pcm
,
153 snd_pcm_hw_params_t
*pcm_hw_params
, snd_pcm_fmt_t fmt
)
157 r
= snd_pcm_hw_params_test_fmt(pcm
, pcm_hw_params
, fmt
);
160 r
= snd_pcm_hw_params_set_fmt(pcm
, pcm_hw_params
, fmt
);
162 FATALA("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_fmt_desc(fmt
));
163 POUTA("alsa:using \"%s\" format\n", snd_pcm_fmt_desc(fmt
));
166 #define PCM_HW_FMT_DECIDE_X(fmt) pcm_hw_fmt_decide_x(pcm, pcm_hw_params, fmt)
167 STATIC
void pcm_hw_fmt_decide(snd_pcm_t
*pcm
,
168 snd_pcm_hw_params_t
*pcm_hw_params
, bool force
,
169 snd_pcm_fmt_t forced_fmt
)
175 r
= snd_pcm_hw_params_test_fmt(pcm
, pcm_hw_params
, forced_fmt
);
177 r
= snd_pcm_hw_params_set_fmt(pcm
, pcm_hw_params
,
180 FATALA("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_fmt_desc(forced_fmt
));
181 POUTA("alsa:using forced \"%s\" format\n", snd_pcm_fmt_desc(forced_fmt
));
185 /* then we try to select from the reasonable "best" to the lowest */
186 /* prefer fmts we know supported by ff */
187 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_FLOAT
))
189 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_S32
))
191 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_S16
))
193 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_U8
))
196 * from here, at the time of writting, those fmts have no ff
197 * wiring, but we are alsa centric here, validate that later
199 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_U32
))
201 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_S24
))
203 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_U24
))
205 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_U16
))
207 if (PCM_HW_FMT_DECIDE_X(SND_PCM_FMT_S8
))
209 FATALA("alsa:unable to find a suitable format\n");
211 #undef PCM_HW_FMT_DECIDE_X
212 STATIC
bool pcm_hw_access_decide_x(snd_pcm_t
*pcm
,
213 snd_pcm_hw_params_t
*pcm_hw_params
, snd_pcm_access_t access
)
217 r
= snd_pcm_hw_params_test_access(pcm
, pcm_hw_params
, access
);
220 r
= snd_pcm_hw_params_set_access(pcm
, pcm_hw_params
, access
);
222 FATALA("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_access_name(access
));
223 POUTA("alsa:using \"%s\" access\n", snd_pcm_access_name(access
));
226 #define PCM_HW_ACCESS_DECIDE_X(access) \
227 pcm_hw_access_decide_x(pcm, pcm_hw_params, access)
228 /* XXX: only classic non-mmap ones */
229 STATIC
void pcm_hw_access_decide(snd_pcm_t
*pcm
,
230 snd_pcm_hw_params_t
*pcm_hw_params
, bool force
,
231 snd_pcm_access_t forced_access
)
234 snd_pcm_access_t access
;
237 r
= snd_pcm_hw_params_test_access(pcm
, pcm_hw_params
,
240 r
= snd_pcm_hw_params_set_access(pcm
, pcm_hw_params
,
243 FATALA("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_access_name(forced_access
));
244 POUTA("alsa:using forced \"%s\" access\n", snd_pcm_access_name(forced_access
));
249 if (PCM_HW_ACCESS_DECIDE_X(SND_PCM_ACCESS_RW_INTERLEAVED
))
251 if (PCM_HW_ACCESS_DECIDE_X(SND_PCM_ACCESS_RW_NONINTERLEAVED
))
253 FATALA("alsa:unable to find a suitable access\n");
255 #undef PCM_HW_ACCESS_DECIDE_X
257 * latency control: some audio bufs can be huge (tested on a pulseaudio with 10
258 * secs audio buf). if we are careless, we will quickly fill this buf which is
259 * worth a significant amount of time, hence will add huge latency to our
260 * interactive audio filtering (vol...). in the case of the 10 secs pulseaudio
261 * buf, it means if you want to mute the audio, it will happen 10 secs later.
262 * we add lantency control by limiting the sz of the dev audio buf, in periods
264 * we choose roughly 0.25 secs, or roughly (rate / 4) frs.
266 STATIC
void pcm_hw_buf_sz_cfg(snd_pcm_t
*pcm
,
267 snd_pcm_hw_params_t
*pcm_hw_params
)
270 snd_pcm_ufrs_t latency_control_target_buf_ufrs_n
;
271 snd_pcm_ufrs_t latency_control_buf_ufrs_n
;
274 r
= snd_pcm_hw_params_get_rate(pcm_hw_params
, &rate
, 0);
276 WARNINGA("alsa:latency control:DISABLING LATENCY CONTROL:unable to get the decided rate from the current device parameters\n");
279 latency_control_target_buf_ufrs_n
= (snd_pcm_ufrs_t
)rate
;
280 latency_control_target_buf_ufrs_n
/= 4;
281 latency_control_buf_ufrs_n
= latency_control_target_buf_ufrs_n
;
282 r
= snd_pcm_hw_params_set_buf_sz_near(pcm
, pcm_hw_params
,
283 &latency_control_buf_ufrs_n
);
285 WARNINGA("alsa:latency control:DISABLING_LATENCY_CONTROL:unable to set the audio buffer size (count of frames) to %u periods for the current device parameters\n", latency_control_buf_ufrs_n
);
288 POUTA("alsa:latency control:target buffer frame count is %u (~0.25 sec), got an audio buffer size set to %u frames\n", latency_control_target_buf_ufrs_n
, latency_control_buf_ufrs_n
);
291 * this function will "decide" the pcm dev cfg:
292 * the goal is to be the "closest" to the provided params,
293 * the "gap" will have to "filled" with ff filts
295 * the "strategy" is a "fall-thru" (chans n then ... then ...) which
296 * will "restrict" the pcm dev cfg further at each step
298 * we try to use a sensible restrict order regarding audio props
300 STATIC
void pcm_cfg_hw_core(snd_pcm_t
*pcm
, snd_pcm_hw_params_t
*pcm_hw_params
,
301 int chans_n
, int rate
, enum avutil_audio_fr_fmt_t ff_fmt
)
304 bool best_effort_wiring_success
;
305 snd_pcm_fmt_t fmt_from_best_effort
;
306 snd_pcm_access_t access_from_best_effort
;
308 /* the return value is from a first refine of the raw hw params */
309 r
= snd_pcm_hw_params_any(pcm
, pcm_hw_params
);
311 FATALA("alsa:unable to populate the hardware parameters context\n");
312 pcm_hw_chans_n_decide(pcm
, pcm_hw_params
, (unsigned int)chans_n
);
313 pcm_hw_rate_decide(pcm
, pcm_hw_params
, (unsigned int)rate
);
315 best_effort_wiring_success
= ff_fmt2pcm_layout_best_effort(
316 ff_fmt
, &fmt_from_best_effort
, &access_from_best_effort
);
317 pcm_hw_fmt_decide(pcm
, pcm_hw_params
, best_effort_wiring_success
,
318 fmt_from_best_effort
);
319 pcm_hw_access_decide(pcm
, pcm_hw_params
, best_effort_wiring_success
,
320 access_from_best_effort
);
321 pcm_hw_buf_sz_cfg(pcm
, pcm_hw_params
);
323 /* base on kernel api at the time we wrote this code */
324 STATIC u8
*kernel_ts_types_str
[] = {
332 STATIC
void pcm_cfg_hw(snd_pcm_t
*pcm
, unsigned int chans_n
, unsigned int rate
,
333 enum avutil_audio_fr_fmt_t ff_fmt
)
337 snd_pcm_access_t access
;
338 snd_pcm_hw_params_t
*hw_params
;
340 POUTA("ALSA:HW_PARAMS START------------------------------------------------------------\n");
341 r
= snd_pcm_hw_params_malloc(&hw_params
);
343 FATALA("alsa:unable to allocate hardware parameters context\n");
345 pcm_cfg_hw_core(pcm
, hw_params
, chans_n
, rate
, ff_fmt
);
347 r
= snd_pcm_hw_params(pcm
, hw_params
);
349 FATALA("alsa:unable to install the hardware parameters\n");
350 r
= snd_pcm_hw_params_current(pcm
, hw_params
);
352 FATALA("alsa:unable to get current hardware parameters\n");
353 snd_pcm_hw_params_dump(hw_params
, pcm_pout_l
);
356 selected_ts_type_p
= -1;
358 if (i
== ARRAY_N(kernel_ts_types_str
))
360 r
= snd_pcm_hw_params_supports_audio_ts_type(hw_params
, i
);
362 selected_ts_type_p
= i
;
363 POUTA("kernel audio timestamp type \"%s\" is supported for the current configuration\n", kernel_ts_types_str
[i
]);
368 * we selected the most accurate, namely with the highest idx, audio ts
371 POUTA("%s will be used for the audio based clock\n", kernel_ts_types_str
[selected_ts_type_p
]);
372 snd_pcm_hw_params_free(hw_params
);
373 POUTA("ALSA:HW_PARAMS END--------------------------------------------------------------\n");
375 STATIC
void pcm_cfg_sw(snd_pcm_t
*pcm
)
378 snd_pcm_sw_params_t
*sw_params
;
380 POUTA("ALSA:SW_PARAMS START------------------------------------------------------------\n");
381 r
= snd_pcm_sw_params_malloc(&sw_params
);
383 FATALA("alsa:unable to allocate software parameters structure\n");
384 r
= snd_pcm_sw_params_current(pcm
, sw_params
);
386 FATALA("alsa:unable to get current software parameters\n");
387 r
= snd_pcm_sw_params_set_period_evt(pcm
, sw_params
, 1);
389 FATALA("alsa:unable to enable period event\n");
390 /* enable ts to be sure */
391 r
= snd_pcm_sw_params_set_tstamp_mode(pcm
, sw_params
,
392 SND_PCM_TSTAMP_ENABLE
);
394 FATALA("unable to set timestamp mode:%s\n", snd_strerror(r
));
395 r
= snd_pcm_sw_params(pcm
, sw_params
);
397 FATALA("alsa:unable to install sotfware parameters\n");
398 snd_pcm_sw_params_dump(sw_params
, pcm_pout_l
);
399 snd_pcm_sw_params_free(sw_params
);
400 POUTA("ALSA:SW_PARAMS END--------------------------------------------------------------\n");
402 STATIC
void dec_a_grow(void)
406 new_idx
= dec_sets_p
.n_max
;
407 dec_sets_p
.a
= realloc(dec_sets_p
.a
, sizeof(*dec_sets_p
.a
)
408 * (dec_sets_p
.n_max
+ 1));
409 if (dec_sets_p
.a
== 0)
410 FATALA("unable to allocate memory for an additional pointer on a reference of a decoder set of frames\n");
411 dec_sets_p
.a
[new_idx
] = avutil_audio_set_ref_alloc();
412 if (dec_sets_p
.a
[new_idx
] == 0)
413 FATALA("ffmpeg:unable to allocate a reference of a decoder set of frames\n");
419 STATIC u8
alsa_recover(snd_pcm_sfrs_t r
)
426 else if (r
== -EPIPE
|| r
== -ESTRPIPE
) {
427 /* underrun or suspended */
430 r_recovered
= snd_pcm_recover(pcm_p
, (int)r
, 0);
431 if (r_recovered
== 0) {
432 WARNINGA("alsa:pcm recovered\n");
435 FATALA("alsa:unable to recover from suspend/underrun\n");
437 FATALA("alsa:fatal/unhandled error\n");
445 STATIC
void pcm_silence_frs_write(snd_pcm_ufrs_t ufrs_n
) { loop
453 is_planar_fmt
= avutil_audio_fr_fmt_is_planar(
454 npv_audio_filt_p
.set
->fmt
);
455 if (is_planar_fmt
== NO
)
456 alsa_r
= snd_pcm_writei(pcm_p
, pcm_silence_bufs_l
[0], ufrs_n
);
458 alsa_r
= snd_pcm_writen(pcm_p
, pcm_silence_bufs_l
, ufrs_n
);
459 r_recover
= alsa_recover(alsa_r
);
460 if (r_recover
== AGAIN
)
462 else if (r_recover
== RECOVERED
)
464 /* r_recover == CONTINUE */
465 ufrs_n
-= (snd_pcm_ufrs_t
)alsa_r
;
471 STATIC
void chans_buf_init(u8
**chans_buf
, int start_fr_idx
)
476 sample_bytes_n
= avutil_get_bytes_per_sample(npv_audio_filt_p
.set
->fmt
);
477 is_planar_fmt
= avutil_audio_fr_fmt_is_planar(
478 npv_audio_filt_p
.set
->fmt
);
479 if (is_planar_fmt
== NO
) { /* or is pcm interleaved */
482 fr_bytes_n
= sample_bytes_n
* npv_audio_filt_p
.set
->chans_n
;
483 chans_buf
[0] = (u8
*)npv_audio_filt_p
.set
->data
[0] + start_fr_idx
485 } else { /* ff planar or pcm noninterleaved */
490 if (p
== npv_audio_filt_p
.set
->chans_n
)
492 chans_buf
[p
] = (u8
*)npv_audio_filt_p
.set
->data
[p
]
493 + start_fr_idx
* sample_bytes_n
;
500 STATIC
void chans_buf_inc(u8
**chans_buf
, int inc
)
505 sample_bytes_n
= avutil_get_bytes_per_sample(npv_audio_filt_p
.set
->fmt
);
506 is_planar_fmt
= avutil_audio_fr_fmt_is_planar(
507 npv_audio_filt_p
.set
->fmt
);
508 if (is_planar_fmt
== NO
) { /* or is pcm interleaved */
511 fr_bytes_n
= sample_bytes_n
* npv_audio_filt_p
.set
->chans_n
;
512 chans_buf
[0] = (u8
*)chans_buf
[0] + inc
* fr_bytes_n
;
513 } else { /* ff planar or pcm noninterleaved */
518 if (p
== npv_audio_filt_p
.set
->chans_n
)
520 chans_buf
[p
] = (u8
*)chans_buf
[p
] + inc
* sample_bytes_n
;
526 STATIC
void draining_state_handle(void)
530 r
= snd_pcm_drain(pcm_p
);
532 snd_pcm_state_t state
;
537 * the pcm state can change asynchronously, and if the draining
538 * was successful, the pcm should be in SETUP state, and in
539 * this state, snd_pcm_drain _must_ fail (direct from alsa
542 state
= snd_pcm_state(pcm_p
);
543 if (state
!= SND_PCM_STATE_SETUP
)
544 FATALA("alsa:an error occured switching to/checking the pcm draining state\n");
545 /* here pcm state is SND_PCM_STATE_SETUP */
547 EXIT("alsa pcm drained or similar, exiting\n");
549 STATIC
void draining_state_switch(void)
556 draining_state_handle();
557 /* remove the alsa epoll fds */
560 if (i
== pcm_pollfds_n_p
)
562 /* in theory, it is thread safe */
563 r
= epoll_ctl(npv_ep_fd_p
, EPOLL_CTL_DEL
, pcm_pollfds_p
[i
].fd
,
566 FATALA("unable to remove the alsa file descriptors from epoll\n");
569 /* start the draining timer */
570 memset(&t
, 0, sizeof(t
));
571 /* initial and interval */
572 t
.it_value
.tv_nsec
= DRAINING_TIMER_INTERVAL_NSECS_N
;
573 t
.it_interval
.tv_nsec
= DRAINING_TIMER_INTERVAL_NSECS_N
;
574 r
= timerfd_settime(draining_timer_fd_p
, 0, &t
, 0);
576 FATALA("unable to arm the draining timer\n");
582 #define HAVE_FILT_SET 1
585 STATIC
void pcm_filt_frs_write(snd_pcm_ufrs_t ufrs_n
) { loop
588 u8
*chans_buf
[AVUTIL_DATA_PTRS_N
];
589 snd_pcm_ufrs_t ufrs_to_write_n
;
590 snd_pcm_ufrs_t filt_set_remaining_ufrs_n
; /* for clarity */
592 snd_pcm_ufrs_t written_ufrs_n
; /* for clarity */
597 * in this loop we try to get some filt frs from what we got from the
600 if (npv_audio_filt_p
.set
->frs_n
== 0) loop
{
603 /* we _really_ want audio data */
604 (void)filt_push_dec_sets();
605 r
= npv_audio_filt_set_try_get();
607 draining_state_switch();
609 } else if (r
== HAVE_FILT_SET
) {
610 npv_audio_filt_p
.pcm_written_ufrs_n
= 0;
615 chans_buf_init(chans_buf
, (int)npv_audio_filt_p
.pcm_written_ufrs_n
);
616 filt_set_remaining_ufrs_n
= (snd_pcm_ufrs_t
)npv_audio_filt_p
.set
->frs_n
617 - npv_audio_filt_p
.pcm_written_ufrs_n
;
618 if (filt_set_remaining_ufrs_n
> ufrs_n
)
619 ufrs_to_write_n
= ufrs_n
;
621 ufrs_to_write_n
= filt_set_remaining_ufrs_n
;
622 is_planar_fmt
= avutil_audio_fr_fmt_is_planar(
623 npv_audio_filt_p
.set
->fmt
);
625 loop
{ /* short write loop */
626 snd_pcm_sfrs_t alsa_r
;
629 if (is_planar_fmt
== NO
)
630 alsa_r
= snd_pcm_writei(pcm_p
, chans_buf
[0],
631 ufrs_to_write_n
- written_ufrs_n
);
633 alsa_r
= snd_pcm_writen(pcm_p
, (void**)chans_buf
,
634 ufrs_to_write_n
- written_ufrs_n
);
635 r_recover
= alsa_recover(alsa_r
);
636 if (r_recover
== AGAIN
)
638 else if (r_recover
== RECOVERED
) {
639 /* account for the written frs anyway */
640 if (npv_audio_filt_p
.pcm_written_ufrs_n
== 0)
641 npv_clk_ref_time_point_update(
642 npv_audio_filt_p
.set
->pts
,
644 npv_audio_filt_p
.pcm_written_ufrs_n
+= written_ufrs_n
;
645 if ((int)npv_audio_filt_p
.pcm_written_ufrs_n
==
646 npv_audio_filt_p
.set
->frs_n
)
647 /* set audio_filt_p.set->frs_n = 0 */
648 avutil_audio_set_unref(npv_audio_filt_p
.set
);
651 /* r_recover == CONTINUE */
652 written_ufrs_n
+= (snd_pcm_ufrs_t
)alsa_r
;
653 if (written_ufrs_n
== ufrs_to_write_n
)
655 chans_buf_inc(chans_buf
, (int)alsa_r
);
658 * this is here we update our ref time point for the audio clk
659 * because with a new filt set of frs, we get a new ts
661 * XXX: getting the "right" ts from ff is convoluted
663 if (npv_audio_filt_p
.pcm_written_ufrs_n
== 0)
664 npv_clk_ref_time_point_update(npv_audio_filt_p
.set
->pts
,
666 npv_audio_filt_p
.pcm_written_ufrs_n
+= written_ufrs_n
;
667 ufrs_n
-= written_ufrs_n
;
669 if ((int)npv_audio_filt_p
.pcm_written_ufrs_n
670 == npv_audio_filt_p
.set
->frs_n
)
671 /* set audio_filt_p.av->frs_n = 0 */
672 avutil_audio_set_unref(npv_audio_filt_p
.set
);
681 /* fatal if the wiring cannot be done */
682 STATIC
void pcm_layout2ff_fmt_strict(snd_pcm_fmt_t alsa_fmt
,
683 snd_pcm_access_t alsa_access
, enum avutil_audio_fr_fmt_t
*ff_fmt
,
687 * ff fmt byte order is always native.
688 * here we handle little endian only
691 case SND_PCM_FMT_FLOAT
:
692 if (alsa_access
== SND_PCM_ACCESS_RW_INTERLEAVED
)
693 *ff_fmt
= AVUTIL_AUDIO_FR_FMT_FLT
;
695 *ff_fmt
= AVUTIL_AUDIO_FR_FMT_FLTP
;
697 case SND_PCM_FMT_S32
:
698 if (alsa_access
== SND_PCM_ACCESS_RW_INTERLEAVED
)
699 *ff_fmt
= AVUTIL_AUDIO_FR_FMT_S32
;
701 *ff_fmt
= AVUTIL_AUDIO_FR_FMT_S32P
;
703 case SND_PCM_FMT_S16
:
704 if (alsa_access
== SND_PCM_ACCESS_RW_INTERLEAVED
)
705 *ff_fmt
= AVUTIL_AUDIO_FR_FMT_S16
;
707 *ff_fmt
= AVUTIL_AUDIO_FR_FMT_S16P
;
710 if (alsa_access
== SND_PCM_ACCESS_RW_INTERLEAVED
)
711 *ff_fmt
= AVUTIL_AUDIO_FR_FMT_U8
;
713 *ff_fmt
= AVUTIL_AUDIO_FR_FMT_U8P
;
716 FATALA("unable to wire strictly alsa layout \"%s\"/\"%s\" to a ffmpeg format\n", snd_pcm_fmt_desc(alsa_fmt
), snd_pcm_access_name(alsa_access
));
719 u8 ff_fmt_str
[STR_SZ
];
721 avutil_get_audio_fr_fmt_str(ff_fmt_str
, sizeof(ff_fmt_str
),
723 POUTA("alsa pcm layout \"%s\"/\"%s\" wired strictly to ffmpeg format \"%sbits\"\n", snd_pcm_fmt_desc(alsa_fmt
), snd_pcm_access_name(alsa_access
), ff_fmt_str
);
727 * XXX: if it is ever used significantly, a fine granularity wiring strategy
728 * will be implemented instead of using the default wiring
730 STATIC
uint64_t pcm_chmaps2ff_chans_layout(snd_pcm_t
*pcm
,
731 unsigned int pcm_chans_n
, bool print_info
)
734 uint64_t ff_chans_layout
;
735 snd_pcm_chmap_t
*pcm_chmap
;
736 u8 chans_layout_str
[STR_SZ
]; /* should be overkill */
738 pcm_chmap
= snd_pcm_get_chmap(pcm
);
739 if (pcm_chmap
== 0) {
741 POUTA("alsa:no pcm channel map available, wiring to default ffmpeg channel layout\n");
744 POUTA("alsa:your pcm device support channel maps, but fine granularity wiring strategy is not implemented\n");
747 ff_chans_layout
= avutil_get_default_chans_layout((int)pcm_chans_n
);
748 avutil_get_chans_layout_str(chans_layout_str
, sizeof(chans_layout_str
),
749 (int)pcm_chans_n
, ff_chans_layout
);
751 POUTA("alsa channel map wired to ffmpeg channel layout:\"%s\" (%u pcm channels)\n", chans_layout_str
, pcm_chans_n
);
752 return ff_chans_layout
;
754 STATIC
void init_pcm_once_public(u8
*pcm_str
)
758 r
= snd_pcm_open(&pcm_p
, pcm_str
, SND_PCM_ST_PLAYBACK
,
762 FATALA("alsa:\"%s\" pcm is already in use\n", pcm_str
);
764 FATALA("alsa:unable to open \"%s\" pcm for playback\n", pcm_str
);
767 r
= snd_pcm_poll_descriptors_n(pcm_p
);
768 POUTA("alsa:have %d poll file descriptors\n", r
);
769 if ((r
<= 0) || (r
> pcm_pollfds_n_max
))
770 FATALA("alsa:invalid count of alsa poll file descriptors\n");
771 pcm_pollfds_n_p
=(u8
)r
;
772 memset(pcm_pollfds_p
, 0, sizeof(pcm_pollfds_p
));
773 snd_pcm_poll_descriptors(pcm_p
, pcm_pollfds_p
, pcm_pollfds_n_max
);
775 STATIC
void init_once_public(u8
*pcm_str
)
779 memset(&st_p
, 0, sizeof(st_p
));
780 pkt_q_p
= npv_pkt_q_new("audio");
782 dec_sets_p
.eof_receive
= false;
783 dec_sets_p
.n_max
= 0;
786 init_pcm_once_public(pcm_str
);
787 selected_ts_type_p
= -1;
788 /* linux bug: still no CLOCK_MONOTONIC_RAW for timerfd */
790 draining_timer_fd_p
= timerfd_create(CLOCK_MONOTONIC
, TFD_NONBLOCK
);
791 if (draining_timer_fd_p
== -1)
792 FATALA("unable to get a draining timer file descriptor:%s\n", strerror(errno
));
794 r
= pthread_mutex_init(&dec_ctx_mutex_l
, 0);
796 FATALA("%d:unable to init the decoder mutex\n", r
);
797 r
= pthread_mutex_init(&dec_sets_p
.mutex
, 0);
799 FATALA("%d:unable to init the mutex for the array of decoder sets\n", r
);
801 STATIC
void init_once_local(void)
806 r
= snd_output_stdio_attach(&pcm_pout_l
, stdout
, 0);
808 FATALA("alsa:unable to attach stdout\n");
809 r
= snd_output_stdio_attach(&pcm_perr_l
, stderr
, 0);
811 FATALA("alsa:unable to attach stderr\n");
812 memset(pcm_silence_bufs_l
, 0, sizeof(pcm_silence_bufs_l
));
814 STATIC
void dec_a_unref_all(void)
820 if (set
== dec_sets_p
.n
)
822 avutil_audio_set_unref(dec_sets_p
.a
[set
]);