File npv/audio/filt/local/code.frag.c changed (mode: 100644) (index d361d3e..432cf92) |
... |
... |
STATIC void pout(u8 *fmt, ...) |
25 |
25 |
npv_vpout(fmt, ap); |
npv_vpout(fmt, ap); |
26 |
26 |
va_end(ap); |
va_end(ap); |
27 |
27 |
} |
} |
28 |
|
STATIC void abufsrc_cfg(enum avutil_audio_fr_fmt_t fmt, int rate, int chans_n, |
|
29 |
|
uint64_t chans_layout, bool print_info) |
|
|
28 |
|
STATIC bool is_recfg_required(avutil_audio_set_ref_t *src_set) |
|
29 |
|
{ |
|
30 |
|
if ( src_set->chans_n != abufsrc_l.key.chans_n |
|
31 |
|
|| src_set->chans_layout != abufsrc_l.key.chans_layout |
|
32 |
|
|| src_set->rate != abufsrc_l.key.rate |
|
33 |
|
|| src_set->fmt != abufsrc_l.key.fmt) |
|
34 |
|
return true; |
|
35 |
|
return false; |
|
36 |
|
} |
|
37 |
|
STATIC void abufsrc_cfg(int chans_n, uint64_t chans_layout, int rate, |
|
38 |
|
enum avutil_audio_fr_fmt_t fmt, bool print_info) |
30 |
39 |
{ |
{ |
31 |
40 |
int r; |
int r; |
32 |
41 |
avutil_rational_t time_base; |
avutil_rational_t time_base; |
33 |
42 |
u8 chans_layout_str[STR_SZ]; /* should be overkill */ |
u8 chans_layout_str[STR_SZ]; /* should be overkill */ |
34 |
43 |
|
|
35 |
|
abufsrc_l = avfilter_get_by_name("abuffer"); |
|
36 |
|
if (abufsrc_l == 0) |
|
|
44 |
|
abufsrc_l.this = avfilter_get_by_name("abuffer"); |
|
45 |
|
if (abufsrc_l.this == 0) |
37 |
46 |
fatal("audio buffer source:could not find the filter\n"); |
fatal("audio buffer source:could not find the filter\n"); |
38 |
|
abufsrc_ctx_l = avfilter_graph_alloc_filt(graph_l, abufsrc_l, |
|
|
47 |
|
abufsrc_l.ctx = avfilter_graph_alloc_filt(graph_l, abufsrc_l.this, |
39 |
48 |
"src_abuf"); |
"src_abuf"); |
40 |
|
if (abufsrc_ctx_l == 0) |
|
|
49 |
|
if (abufsrc_l.ctx == 0) |
41 |
50 |
fatal("audio buffer source context:could not allocate the instance in the filter graph\n"); |
fatal("audio buffer source context:could not allocate the instance in the filter graph\n"); |
42 |
|
r = avutil_opt_set(abufsrc_ctx_l, "sample_fmt", |
|
|
51 |
|
r = avutil_opt_set(abufsrc_l.ctx, "sample_fmt", |
43 |
52 |
avutil_get_audio_fr_fmt_name(fmt), |
avutil_get_audio_fr_fmt_name(fmt), |
44 |
53 |
AVUTIL_OPT_SEARCH_CHILDREN); |
AVUTIL_OPT_SEARCH_CHILDREN); |
45 |
54 |
if (r < 0) |
if (r < 0) |
46 |
55 |
fatal("audio buffer source context:unable to set the decoder frame format option\n"); |
fatal("audio buffer source context:unable to set the decoder frame format option\n"); |
47 |
|
r = avutil_opt_set_int(abufsrc_ctx_l, "sample_rate", |
|
|
56 |
|
r = avutil_opt_set_int(abufsrc_l.ctx, "sample_rate", |
48 |
57 |
rate, AVUTIL_OPT_SEARCH_CHILDREN); |
rate, AVUTIL_OPT_SEARCH_CHILDREN); |
49 |
58 |
if (r < 0) |
if (r < 0) |
50 |
59 |
fatal("audio buffer source context:unable to set the decoder rate option\n"); |
fatal("audio buffer source context:unable to set the decoder rate option\n"); |
51 |
|
/* |
|
52 |
|
* XXX: at the time of coding, bug for 1 chans layout... or I did miss |
|
53 |
|
* some valuable information |
|
54 |
|
*/ |
|
55 |
60 |
avutil_get_chans_layout_str(chans_layout_str, sizeof(chans_layout_str), |
avutil_get_chans_layout_str(chans_layout_str, sizeof(chans_layout_str), |
56 |
61 |
chans_n, chans_layout); |
chans_n, chans_layout); |
57 |
62 |
if (print_info) |
if (print_info) |
58 |
63 |
pout("audio buffer source context:using channels layout \"%s\" (%d pcm channels)\n", chans_layout_str, chans_n); |
pout("audio buffer source context:using channels layout \"%s\" (%d pcm channels)\n", chans_layout_str, chans_n); |
59 |
|
r = avutil_opt_set(abufsrc_ctx_l, "channel_layout", chans_layout_str, |
|
|
64 |
|
r = avutil_opt_set(abufsrc_l.ctx, "channel_layout", chans_layout_str, |
60 |
65 |
AVUTIL_OPT_SEARCH_CHILDREN); |
AVUTIL_OPT_SEARCH_CHILDREN); |
61 |
66 |
if (r < 0) |
if (r < 0) |
62 |
67 |
fatal("audio buffer source context:unable to set the decoder channel layout option\n"); |
fatal("audio buffer source context:unable to set the decoder channel layout option\n"); |
63 |
|
r = avfilter_init_str(abufsrc_ctx_l, 0); |
|
|
68 |
|
r = avfilter_init_str(abufsrc_l.ctx, 0); |
64 |
69 |
if (r < 0) |
if (r < 0) |
65 |
70 |
fatal("audio buffer source context:unable to initialize\n"); |
fatal("audio buffer source context:unable to initialize\n"); |
66 |
71 |
} |
} |
|
... |
... |
STATIC void vol_cfg(bool muted, double vol_cfg) |
90 |
95 |
if (r < 0) |
if (r < 0) |
91 |
96 |
fatal("volume buffer context:unable to initialize\n"); |
fatal("volume buffer context:unable to initialize\n"); |
92 |
97 |
} |
} |
93 |
|
STATIC void afmt_cfg(enum avutil_audio_fr_fmt_t fmt, int rate, int chans_n, |
|
94 |
|
uint64_t chans_layout, bool print_info) |
|
|
98 |
|
STATIC void afmt_cfg(int chans_n, uint64_t chans_layout, int rate, |
|
99 |
|
enum avutil_audio_fr_fmt_t fmt, bool print_info) |
95 |
100 |
{ |
{ |
96 |
101 |
int r; |
int r; |
97 |
102 |
u8 rate_str[sizeof("dddddd")]; |
u8 rate_str[sizeof("dddddd")]; |
|
... |
... |
STATIC void abufsink_cfg(void) |
142 |
147 |
STATIC void init_once_local(void) |
STATIC void init_once_local(void) |
143 |
148 |
{ |
{ |
144 |
149 |
graph_l = 0; |
graph_l = 0; |
145 |
|
abufsrc_ctx_l = 0; |
|
146 |
|
abufsrc_l = 0; |
|
|
150 |
|
memset(&abufsrc_l, 0, sizeof(abufsrc_l)); |
147 |
151 |
vol_ctx_l = 0; |
vol_ctx_l = 0; |
148 |
152 |
vol_l = 0; |
vol_l = 0; |
149 |
153 |
afmt_ctx_l = 0; |
afmt_ctx_l = 0; |
150 |
154 |
afmt_l = 0; |
afmt_l = 0; |
151 |
155 |
abufsink_ctx_l = 0; |
abufsink_ctx_l = 0; |
152 |
156 |
abufsink_l = 0; |
abufsink_l = 0; |
153 |
|
/* floating point strs are localized... */ |
|
|
157 |
|
/* floating point strs are localized... erk... */ |
154 |
158 |
snprintf(double_zero_l10n_str_l, sizeof(double_zero_l10n_str_l), |
snprintf(double_zero_l10n_str_l, sizeof(double_zero_l10n_str_l), |
155 |
159 |
"%f", 0.); |
"%f", 0.); |
156 |
160 |
} |
} |
File npv/audio/filt/public/code.frag.c changed (mode: 100644) (index d5e6f50..2fd1fef) |
|
1 |
|
/*NSPC*/ |
1 |
2 |
#define AGAIN 0 |
#define AGAIN 0 |
2 |
3 |
#define PUSHED_ONE_SET 1 |
#define PUSHED_ONE_SET 1 |
3 |
4 |
#define NO_DEC_SET 2 |
#define NO_DEC_SET 2 |
4 |
5 |
#define FILT_SWITCHED_TO_DRAINING 3 |
#define FILT_SWITCHED_TO_DRAINING 3 |
5 |
|
STATIC u8 filt_push_dec_sets(void) |
|
|
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) |
6 |
9 |
{ |
{ |
7 |
10 |
u8 r8; |
u8 r8; |
8 |
11 |
int ri; |
int ri; |
|
... |
... |
STATIC u8 filt_push_dec_sets(void) |
11 |
14 |
npv_audio_dec_sets_lock(); |
npv_audio_dec_sets_lock(); |
12 |
15 |
if (npv_audio_dec_sets_p.n == 0) { |
if (npv_audio_dec_sets_p.n == 0) { |
13 |
16 |
if (npv_audio_dec_sets_p.eof_receive) { |
if (npv_audio_dec_sets_p.eof_receive) { |
14 |
|
ri = avfilter_bufsrc_add_audio_set_flags(abufsrc_ctx_l, |
|
15 |
|
0, AVFILTER_BUFSRC_FLAG_PUSH |
|
16 |
|
| AVFILTER_BUFSRC_FLAG_KEEP_REF); |
|
|
17 |
|
ri = avfilter_bufsrc_add_audio_set_flags(abufsrc_l.ctx, |
|
18 |
|
0, AVFILTER_BUFSRC_FLAG_KEEP_REF); |
17 |
19 |
if (ri < 0) |
if (ri < 0) |
18 |
20 |
fatal("ffmpeg:unable to notify the end of data to the filter source audio buffer context\n"); |
fatal("ffmpeg:unable to notify the end of data to the filter source audio buffer context\n"); |
19 |
21 |
pout("ffmpeg:interactive filter switched to draining\n"); |
pout("ffmpeg:interactive filter switched to draining\n"); |
|
... |
... |
STATIC u8 filt_push_dec_sets(void) |
24 |
26 |
goto unlock; |
goto unlock; |
25 |
27 |
} |
} |
26 |
28 |
a = npv_audio_dec_sets_p.a; |
a = npv_audio_dec_sets_p.a; |
|
29 |
|
/* |
|
30 |
|
* XXX: this is were dynamic audio recfg is triggered and we get out of |
|
31 |
|
* the critical section asap |
|
32 |
|
*/ |
|
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; |
|
38 |
|
*new_fmt = a[0]->fmt; |
|
39 |
|
r8 = FILT_RECFG_REQUIRED; |
|
40 |
|
goto unlock; |
|
41 |
|
} |
27 |
42 |
/* the dec_sets_p bufs will be unref in avcodec_audio_receive_set */ |
/* the dec_sets_p bufs will be unref in avcodec_audio_receive_set */ |
28 |
|
ri = avfilter_bufsrc_add_audio_set_flags(abufsrc_ctx_l, a[0], |
|
29 |
|
AVFILTER_BUFSRC_FLAG_PUSH | AVFILTER_BUFSRC_FLAG_KEEP_REF); |
|
|
43 |
|
ri = avfilter_bufsrc_add_audio_set_flags(abufsrc_l.ctx, a[0], |
|
44 |
|
AVFILTER_BUFSRC_FLAG_KEEP_REF); |
30 |
45 |
if (ri >= 0) { |
if (ri >= 0) { |
31 |
46 |
/* rotate the ptrs if needed */ |
/* rotate the ptrs if needed */ |
32 |
47 |
if (npv_audio_dec_sets_p.n > 1) { |
if (npv_audio_dec_sets_p.n > 1) { |
|
... |
... |
unlock: |
54 |
69 |
#undef NO_DEC_SET |
#undef NO_DEC_SET |
55 |
70 |
#undef PUSHED_NULL_SET |
#undef PUSHED_NULL_SET |
56 |
71 |
#undef FILT_SWITCHED_TO_DRAINING |
#undef FILT_SWITCHED_TO_DRAINING |
57 |
|
#define AGAIN 0 |
|
|
72 |
|
#undef FILT_RECFG_REQUIRED |
58 |
73 |
#define HAVE_FILT_SET 1 |
#define HAVE_FILT_SET 1 |
59 |
74 |
#define EOF_FILT 2 |
#define EOF_FILT 2 |
60 |
|
STATIC u8 filt_set_try_get(void) |
|
|
75 |
|
STATIC u8 filt_set_get(void) |
61 |
76 |
{ |
{ |
62 |
77 |
int r; |
int r; |
63 |
78 |
/* |
/* |
|
... |
... |
STATIC u8 filt_set_try_get(void) |
65 |
80 |
* filt_p.set won't matter. |
* filt_p.set won't matter. |
66 |
81 |
*/ |
*/ |
67 |
82 |
r = avfilter_bufsink_get_audio_set(abufsink_ctx_l, filt_p.set); |
r = avfilter_bufsink_get_audio_set(abufsink_ctx_l, filt_p.set); |
68 |
|
if (r == AVERROR(EAGAIN)) { |
|
69 |
|
return AGAIN; |
|
70 |
|
} else if (r >= 0) { |
|
|
83 |
|
if (r >= 0) { |
71 |
84 |
filt_p.pcm_written_ufrs_n = 0; |
filt_p.pcm_written_ufrs_n = 0; |
72 |
85 |
return HAVE_FILT_SET; |
return HAVE_FILT_SET; |
73 |
86 |
} else if (r == AVUTIL_AVERROR_EOF) { |
} else if (r == AVUTIL_AVERROR_EOF) { |
|
... |
... |
STATIC u8 filt_set_try_get(void) |
75 |
88 |
} |
} |
76 |
89 |
fatal("ffmpeg:error while getting frames from the filter\n"); |
fatal("ffmpeg:error while getting frames from the filter\n"); |
77 |
90 |
} |
} |
78 |
|
#undef AGAIN |
|
79 |
91 |
#undef HAVE_FILT_SET |
#undef HAVE_FILT_SET |
80 |
92 |
#undef EOF_FILT |
#undef EOF_FILT |
81 |
93 |
#define DONT_PRINT_INFO false |
#define DONT_PRINT_INFO false |
82 |
94 |
STATIC void filt_flush(void) |
STATIC void filt_flush(void) |
83 |
95 |
{ |
{ |
84 |
|
enum avutil_audio_fr_fmt_t dst_fmt; |
|
85 |
|
int dst_rate; |
|
86 |
96 |
int dst_chans_n; |
int dst_chans_n; |
|
97 |
|
enum avutil_audio_fr_fmt_t dst_fmt; |
87 |
98 |
uint64_t src_chans_layout; |
uint64_t src_chans_layout; |
88 |
99 |
uint64_t dst_chans_layout; |
uint64_t dst_chans_layout; |
|
100 |
|
int dst_rate; |
89 |
101 |
|
|
90 |
102 |
avutil_audio_set_unref(filt_p.set); |
avutil_audio_set_unref(filt_p.set); |
91 |
103 |
filt_p.pcm_written_ufrs_n = 0; |
filt_p.pcm_written_ufrs_n = 0; |
92 |
104 |
|
|
93 |
|
npv_audio_pcm2ff(npv_audio_pcm_p, &dst_fmt, &dst_rate, &dst_chans_n, |
|
94 |
|
&dst_chans_layout, DONT_PRINT_INFO); |
|
|
105 |
|
npv_audio_pcm2ff_strict(npv_audio_pcm_p, &dst_chans_n, |
|
106 |
|
&dst_chans_layout, &dst_rate, &dst_fmt, DONT_PRINT_INFO); |
95 |
107 |
/* the audio dec ctx may not have a valid chans layout */ |
/* the audio dec ctx may not have a valid chans layout */ |
96 |
|
if (npv_audio_dec_ctx_p->chans_layout == 0) { |
|
|
108 |
|
if (npv_audio_dec_ctx_p->chans_layout == 0) |
97 |
109 |
src_chans_layout = avutil_get_default_chans_layout( |
src_chans_layout = avutil_get_default_chans_layout( |
98 |
110 |
npv_audio_dec_ctx_p->chans_n); |
npv_audio_dec_ctx_p->chans_n); |
99 |
|
} else |
|
|
111 |
|
else |
100 |
112 |
src_chans_layout = npv_audio_dec_ctx_p->chans_layout; |
src_chans_layout = npv_audio_dec_ctx_p->chans_layout; |
101 |
|
npv_audio_filt_cfg( |
|
102 |
|
npv_audio_dec_ctx_p->fr_fmt, npv_audio_dec_ctx_p->fr_rate, |
|
103 |
|
npv_audio_dec_ctx_p->chans_n, src_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, |
104 |
115 |
filt_p.muted, filt_p.vol, |
filt_p.muted, filt_p.vol, |
105 |
|
dst_fmt, dst_rate, dst_chans_n, dst_chans_layout, |
|
|
116 |
|
dst_chans_n, dst_chans_layout, dst_rate, dst_fmt, |
106 |
117 |
DONT_PRINT_INFO); |
DONT_PRINT_INFO); |
107 |
118 |
} |
} |
108 |
119 |
#undef DONT_PRINT_INFO |
#undef DONT_PRINT_INFO |
|
... |
... |
STATIC void init_once(double initial_vol) |
111 |
122 |
init_once_local(); |
init_once_local(); |
112 |
123 |
init_once_public(initial_vol); |
init_once_public(initial_vol); |
113 |
124 |
} |
} |
114 |
|
STATIC void cfg(enum avutil_audio_fr_fmt_t src_fmt, int src_rate, |
|
115 |
|
int src_chans_n, uint64_t src_chans_layout, |
|
|
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, |
116 |
127 |
bool muted, double vol, |
bool muted, double vol, |
117 |
|
enum avutil_audio_fr_fmt_t dst_fmt, int dst_rate, |
|
118 |
|
int dst_chans_n, uint64_t dst_chans_layout, |
|
|
128 |
|
int dst_chans_n, uint64_t dst_chans_layout, int dst_rate, |
|
129 |
|
enum avutil_audio_fr_fmt_t dst_fmt, |
119 |
130 |
bool print_info) |
bool print_info) |
120 |
131 |
{ |
{ |
121 |
132 |
int r; |
int r; |
|
... |
... |
STATIC void cfg(enum avutil_audio_fr_fmt_t src_fmt, int src_rate, |
126 |
137 |
graph_l = avfilter_graph_alloc(); |
graph_l = avfilter_graph_alloc(); |
127 |
138 |
if (graph_l == 0) |
if (graph_l == 0) |
128 |
139 |
fatal("unable to create filter graph\n"); |
fatal("unable to create filter graph\n"); |
129 |
|
abufsrc_cfg(src_fmt, src_rate, src_chans_n, src_chans_layout, |
|
|
140 |
|
abufsrc_cfg(src_chans_n, src_chans_layout, src_rate, src_fmt, |
130 |
141 |
print_info); |
print_info); |
|
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 |
|
/*--------------------------------------------------------------------*/ |
131 |
148 |
vol_cfg(muted, vol); |
vol_cfg(muted, vol); |
132 |
|
afmt_cfg(dst_fmt, dst_rate, dst_chans_n, dst_chans_layout, print_info); |
|
|
149 |
|
afmt_cfg(dst_chans_n, dst_chans_layout, dst_rate, dst_fmt, print_info); |
133 |
150 |
abufsink_cfg(); |
abufsink_cfg(); |
134 |
|
r = avfilter_link(abufsrc_ctx_l, 0, vol_ctx_l, 0); |
|
|
151 |
|
r = avfilter_link(abufsrc_l.ctx, 0, vol_ctx_l, 0); |
135 |
152 |
if (r < 0) |
if (r < 0) |
136 |
153 |
fatal("unable to connect the audio buffer source filter to the volume filter\n"); |
fatal("unable to connect the audio buffer source filter to the volume filter\n"); |
137 |
154 |
r = avfilter_link(vol_ctx_l, 0, afmt_ctx_l, 0); |
r = avfilter_link(vol_ctx_l, 0, afmt_ctx_l, 0); |
|
... |
... |
STATIC void cfg(enum avutil_audio_fr_fmt_t src_fmt, int src_rate, |
143 |
160 |
r = avfilter_graph_config(graph_l, 0); |
r = avfilter_graph_config(graph_l, 0); |
144 |
161 |
if (r < 0) |
if (r < 0) |
145 |
162 |
fatal("unable to configure the filter graph\n"); |
fatal("unable to configure the filter graph\n"); |
146 |
|
/*--------------------------------------------------------------------*/ |
|
147 |
163 |
if (!print_info) |
if (!print_info) |
148 |
164 |
return; |
return; |
149 |
165 |
dump_str = avfilter_graph_dump(graph_l, 0); |
dump_str = avfilter_graph_dump(graph_l, 0); |
File npv/audio/local/code.frag.c changed (mode: 100644) (index 20611b9..48f17da) |
... |
... |
STATIC void pout(u8 *fmt, ...) |
25 |
25 |
npv_vpout(fmt, ap); |
npv_vpout(fmt, ap); |
26 |
26 |
va_end(ap); |
va_end(ap); |
27 |
27 |
} |
} |
|
28 |
|
/* base on kernel api at the time we wrote this code */ |
|
29 |
|
STATIC u8 *kernel_ts_types_str_l[] = { |
|
30 |
|
"compat", |
|
31 |
|
"default", |
|
32 |
|
"link", |
|
33 |
|
"link absolute", |
|
34 |
|
"link estimated", |
|
35 |
|
"link synchonized" |
|
36 |
|
}; |
|
37 |
|
/* |
|
38 |
|
* XXX: if it is ever used significantly, a fine granularity wiring strategy |
|
39 |
|
* will be implemented instead of using the default wiring |
|
40 |
|
*/ |
|
41 |
|
STATIC uint64_t pcm_chmaps2ff_chans_layout(snd_pcm_t *pcm, |
|
42 |
|
unsigned int pcm_chans_n, bool print_info) |
|
43 |
|
{ |
|
44 |
|
int r; |
|
45 |
|
uint64_t ff_chans_layout; |
|
46 |
|
snd_pcm_chmap_t *pcm_chmap; |
|
47 |
|
u8 chans_layout_str[STR_SZ]; /* should be overkill */ |
|
48 |
|
|
|
49 |
|
pcm_chmap = snd_pcm_get_chmap(pcm); |
|
50 |
|
if (pcm_chmap == 0) { |
|
51 |
|
if (print_info) |
|
52 |
|
pout("alsa:no pcm channel map available, wiring to default ffmpeg channel layout\n"); |
|
53 |
|
} else { |
|
54 |
|
if (print_info) |
|
55 |
|
pout("alsa:your pcm device support channel maps, but fine granularity wiring strategy is not implemented, using default ffmpeg layout\n"); |
|
56 |
|
free(pcm_chmap); |
|
57 |
|
} |
|
58 |
|
ff_chans_layout = avutil_get_default_chans_layout((int)pcm_chans_n); |
|
59 |
|
avutil_get_chans_layout_str(chans_layout_str, sizeof(chans_layout_str), |
|
60 |
|
(int)pcm_chans_n, ff_chans_layout); |
|
61 |
|
if (print_info) |
|
62 |
|
pout("alsa channel map wired to ffmpeg channel layout:\"%s\" (%u pcm channels)\n", chans_layout_str, pcm_chans_n); |
|
63 |
|
return ff_chans_layout; |
|
64 |
|
} |
28 |
65 |
STATIC bool ff_fmt2pcm_layout_best_effort(enum avutil_audio_fr_fmt_t ff_fmt, |
STATIC bool ff_fmt2pcm_layout_best_effort(enum avutil_audio_fr_fmt_t ff_fmt, |
29 |
66 |
snd_pcm_fmt_t *alsa_fmt, snd_pcm_access_t *alsa_access) |
snd_pcm_fmt_t *alsa_fmt, snd_pcm_access_t *alsa_access) |
30 |
67 |
{ |
{ |
|
... |
... |
STATIC bool ff_fmt2pcm_layout_best_effort(enum avutil_audio_fr_fmt_t ff_fmt, |
74 |
111 |
return true; |
return true; |
75 |
112 |
} |
} |
76 |
113 |
STATIC void pcm_hw_chans_n_decide(snd_pcm_t *pcm, |
STATIC void pcm_hw_chans_n_decide(snd_pcm_t *pcm, |
77 |
|
snd_pcm_hw_params_t *pcm_hw_params, unsigned int chans_n) |
|
|
114 |
|
snd_pcm_hw_params_t *pcm_hw_params, int chans_n) |
78 |
115 |
{ |
{ |
79 |
116 |
int r; |
int r; |
80 |
117 |
unsigned int chans_n_max; |
unsigned int chans_n_max; |
81 |
118 |
unsigned int chans_n_min; |
unsigned int chans_n_min; |
82 |
119 |
|
|
83 |
|
r = snd_pcm_hw_params_test_chans_n(pcm, pcm_hw_params, chans_n); |
|
|
120 |
|
r = snd_pcm_hw_params_test_chans_n(pcm, pcm_hw_params, |
|
121 |
|
(unsigned int)chans_n); |
84 |
122 |
if (r == 0) { |
if (r == 0) { |
85 |
|
r = snd_pcm_hw_params_set_chans_n(pcm, pcm_hw_params, chans_n); |
|
|
123 |
|
r = snd_pcm_hw_params_set_chans_n(pcm, pcm_hw_params, |
|
124 |
|
(unsigned int)chans_n); |
86 |
125 |
if (r != 0) |
if (r != 0) |
87 |
|
fatal("alsa:unable to restrict pcm device to %u channels, count which was successfully tested\n", chans_n); |
|
88 |
|
pout("alsa:using %u channels\n", chans_n); |
|
|
126 |
|
fatal("alsa:unable to restrict pcm device to %d channels, count which was successfully tested\n", chans_n); |
|
127 |
|
pout("alsa:using %d channels\n", chans_n); |
89 |
128 |
return; |
return; |
90 |
129 |
} |
} |
91 |
|
pout("alsa:unable to use %u channels\n", chans_n); |
|
|
130 |
|
pout("alsa:unable to use %d channels\n", chans_n); |
92 |
131 |
/* try to use the max chans n the pcm can */ |
/* try to use the max chans n the pcm can */ |
93 |
132 |
r = snd_pcm_hw_params_get_chans_n_max(pcm_hw_params, &chans_n_max); |
r = snd_pcm_hw_params_get_chans_n_max(pcm_hw_params, &chans_n_max); |
94 |
133 |
if (r != 0) |
if (r != 0) |
|
... |
... |
STATIC void pcm_hw_chans_n_decide(snd_pcm_t *pcm, |
118 |
157 |
fatal("alsa:unable to find a suitable count of channels\n"); |
fatal("alsa:unable to find a suitable count of channels\n"); |
119 |
158 |
} |
} |
120 |
159 |
STATIC void pcm_hw_rate_decide(snd_pcm_t *pcm, |
STATIC void pcm_hw_rate_decide(snd_pcm_t *pcm, |
121 |
|
snd_pcm_hw_params_t *pcm_hw_params, unsigned int rate) |
|
|
160 |
|
snd_pcm_hw_params_t *pcm_hw_params, int rate) |
122 |
161 |
{ |
{ |
123 |
162 |
int r; |
int r; |
124 |
163 |
unsigned int rate_max; |
unsigned int rate_max; |
125 |
164 |
unsigned int rate_near; |
unsigned int rate_near; |
126 |
165 |
unsigned int rate_min; |
unsigned int rate_min; |
127 |
166 |
|
|
128 |
|
r = snd_pcm_hw_params_test_rate(pcm, pcm_hw_params, rate, |
|
|
167 |
|
r = snd_pcm_hw_params_test_rate(pcm, pcm_hw_params, (unsigned int)rate, |
129 |
168 |
SND_PCM_ST_PLAYBACK); |
SND_PCM_ST_PLAYBACK); |
130 |
169 |
if (r == 0) { |
if (r == 0) { |
131 |
|
r = snd_pcm_hw_params_set_rate(pcm, pcm_hw_params, rate, |
|
132 |
|
SND_PCM_ST_PLAYBACK); |
|
|
170 |
|
r = snd_pcm_hw_params_set_rate(pcm, pcm_hw_params, |
|
171 |
|
(unsigned int)rate, SND_PCM_ST_PLAYBACK); |
133 |
172 |
if (r != 0) |
if (r != 0) |
134 |
|
fatal("alsa:unable to restrict pcm device to %uHz, which was successfully tested\n", rate); |
|
135 |
|
pout("alsa:using %uHz\n", rate); |
|
|
173 |
|
fatal("alsa:unable to restrict pcm device to %dHz, which was successfully tested\n", rate); |
|
174 |
|
pout("alsa:using %dHz\n", rate); |
136 |
175 |
return; |
return; |
137 |
176 |
} |
} |
138 |
|
pout("alsa:unable to use %uHz\n", rate); |
|
|
177 |
|
pout("alsa:unable to use %dHz\n", rate); |
139 |
178 |
/* try to use the max rate the pcm can */ |
/* try to use the max rate the pcm can */ |
140 |
179 |
r = snd_pcm_hw_params_get_rate_max(pcm_hw_params, &rate_max, |
r = snd_pcm_hw_params_get_rate_max(pcm_hw_params, &rate_max, |
141 |
180 |
SND_PCM_ST_PLAYBACK); |
SND_PCM_ST_PLAYBACK); |
|
... |
... |
STATIC void pcm_hw_buf_sz_cfg(snd_pcm_t *pcm, |
325 |
364 |
* |
* |
326 |
365 |
* we try to use a sensible restrict order regarding audio props |
* we try to use a sensible restrict order regarding audio props |
327 |
366 |
*/ |
*/ |
328 |
|
STATIC void pcm_cfg_hw_core(snd_pcm_t *pcm, snd_pcm_hw_params_t *pcm_hw_params, |
|
329 |
|
int chans_n, int rate, enum avutil_audio_fr_fmt_t ff_fmt) |
|
|
367 |
|
STATIC void pcm_cfg_hw_core_best_effort(snd_pcm_t *pcm, |
|
368 |
|
snd_pcm_hw_params_t *pcm_hw_params, int chans_n, uint64_t chans_layout, |
|
369 |
|
int rate, enum avutil_audio_fr_fmt_t ff_fmt) |
330 |
370 |
{ |
{ |
331 |
371 |
int r; |
int r; |
332 |
372 |
bool best_effort_wiring_success; |
bool best_effort_wiring_success; |
|
... |
... |
STATIC void pcm_cfg_hw_core(snd_pcm_t *pcm, snd_pcm_hw_params_t *pcm_hw_params, |
337 |
377 |
r = snd_pcm_hw_params_any(pcm, pcm_hw_params); |
r = snd_pcm_hw_params_any(pcm, pcm_hw_params); |
338 |
378 |
if (r < 0) |
if (r < 0) |
339 |
379 |
fatal("alsa:unable to populate the hardware parameters context\n"); |
fatal("alsa:unable to populate the hardware parameters context\n"); |
340 |
|
pcm_hw_chans_n_decide(pcm, pcm_hw_params, (unsigned int)chans_n); |
|
341 |
|
pcm_hw_rate_decide(pcm, pcm_hw_params, (unsigned int)rate); |
|
342 |
|
/* try our best */ |
|
|
380 |
|
pcm_hw_chans_n_decide(pcm, pcm_hw_params, chans_n); |
|
381 |
|
/* XXX: we ignore chans_layout (remapping done in bridge filt) */ |
|
382 |
|
pcm_hw_rate_decide(pcm, pcm_hw_params, rate); |
|
383 |
|
/* try our best with the fmt */ |
343 |
384 |
best_effort_wiring_success = ff_fmt2pcm_layout_best_effort( |
best_effort_wiring_success = ff_fmt2pcm_layout_best_effort( |
344 |
385 |
ff_fmt, &fmt_from_best_effort, &access_from_best_effort); |
ff_fmt, &fmt_from_best_effort, &access_from_best_effort); |
345 |
386 |
pcm_hw_fmt_decide(pcm, pcm_hw_params, best_effort_wiring_success, |
pcm_hw_fmt_decide(pcm, pcm_hw_params, best_effort_wiring_success, |
|
... |
... |
STATIC void pcm_cfg_hw_core(snd_pcm_t *pcm, snd_pcm_hw_params_t *pcm_hw_params, |
348 |
389 |
access_from_best_effort); |
access_from_best_effort); |
349 |
390 |
pcm_hw_buf_sz_cfg(pcm, pcm_hw_params); |
pcm_hw_buf_sz_cfg(pcm, pcm_hw_params); |
350 |
391 |
} |
} |
351 |
|
/* base on kernel api at the time we wrote this code */ |
|
352 |
|
STATIC u8 *kernel_ts_types_str[] = { |
|
353 |
|
"compat", |
|
354 |
|
"default", |
|
355 |
|
"link", |
|
356 |
|
"link absolute", |
|
357 |
|
"link estimated", |
|
358 |
|
"link synchonized" |
|
359 |
|
}; |
|
360 |
|
STATIC void pcm_cfg_hw(snd_pcm_t *pcm, unsigned int chans_n, unsigned int rate, |
|
361 |
|
enum avutil_audio_fr_fmt_t ff_fmt) |
|
362 |
|
{ |
|
363 |
|
int r; |
|
364 |
|
s8 i; |
|
365 |
|
snd_pcm_access_t access; |
|
366 |
|
snd_pcm_hw_params_t *hw_params; |
|
367 |
|
|
|
368 |
|
pout("ALSA:HW_PARAMS START------------------------------------------------------------\n"); |
|
369 |
|
r = snd_pcm_hw_params_malloc(&hw_params); |
|
370 |
|
if (r < 0) |
|
371 |
|
fatal("alsa:unable to allocate hardware parameters context\n"); |
|
372 |
|
|
|
373 |
|
pcm_cfg_hw_core(pcm, hw_params, chans_n, rate, ff_fmt); |
|
374 |
|
|
|
375 |
|
r = snd_pcm_hw_params(pcm, hw_params); |
|
376 |
|
if (r != 0) |
|
377 |
|
fatal("alsa:unable to install the hardware parameters\n"); |
|
378 |
|
r = snd_pcm_hw_params_current(pcm, hw_params); |
|
379 |
|
if (r != 0) |
|
380 |
|
fatal("alsa:unable to get current hardware parameters\n"); |
|
381 |
|
snd_pcm_hw_params_dump(hw_params, pcm_pout_l); |
|
382 |
|
|
|
383 |
|
i = 0; |
|
384 |
|
selected_ts_type_p = -1; |
|
385 |
|
loop { |
|
386 |
|
if (i == ARRAY_N(kernel_ts_types_str)) |
|
387 |
|
break; |
|
388 |
|
r = snd_pcm_hw_params_supports_audio_ts_type(hw_params, i); |
|
389 |
|
if (r == 1) { |
|
390 |
|
selected_ts_type_p = i; |
|
391 |
|
pout("kernel audio timestamp type \"%s\" is supported for the current configuration\n", kernel_ts_types_str[i]); |
|
392 |
|
} |
|
393 |
|
++i; |
|
394 |
|
} |
|
395 |
|
/* |
|
396 |
|
* we selected the most accurate, namely with the highest idx, audio ts |
|
397 |
|
* type |
|
398 |
|
*/ |
|
399 |
|
pout("%s will be used for the audio based clock\n", kernel_ts_types_str[selected_ts_type_p]); |
|
400 |
|
snd_pcm_hw_params_free(hw_params); |
|
401 |
|
pout("ALSA:HW_PARAMS END--------------------------------------------------------------\n"); |
|
402 |
|
} |
|
403 |
|
STATIC void pcm_cfg_sw(snd_pcm_t *pcm) |
|
404 |
|
{ |
|
405 |
|
int r; |
|
406 |
|
snd_pcm_sw_params_t *sw_params; |
|
407 |
|
|
|
408 |
|
pout("ALSA:SW_PARAMS START------------------------------------------------------------\n"); |
|
409 |
|
r = snd_pcm_sw_params_malloc(&sw_params); |
|
410 |
|
if (r != 0) |
|
411 |
|
fatal("alsa:unable to allocate software parameters structure\n"); |
|
412 |
|
r = snd_pcm_sw_params_current(pcm, sw_params); |
|
413 |
|
if (r != 0) |
|
414 |
|
fatal("alsa:unable to get current software parameters\n"); |
|
415 |
|
r = snd_pcm_sw_params_set_period_evt(pcm, sw_params, 1); |
|
416 |
|
if (r != 0) |
|
417 |
|
fatal("alsa:unable to enable period event\n"); |
|
418 |
|
/* enable ts to be sure */ |
|
419 |
|
r = snd_pcm_sw_params_set_tstamp_mode(pcm, sw_params, |
|
420 |
|
SND_PCM_TSTAMP_ENABLE); |
|
421 |
|
if (r < 0) |
|
422 |
|
fatal("unable to set timestamp mode:%s\n", snd_strerror(r)); |
|
423 |
|
r = snd_pcm_sw_params(pcm, sw_params); |
|
424 |
|
if (r != 0) |
|
425 |
|
fatal("alsa:unable to install sotfware parameters\n"); |
|
426 |
|
snd_pcm_sw_params_dump(sw_params, pcm_pout_l); |
|
427 |
|
snd_pcm_sw_params_free(sw_params); |
|
428 |
|
pout("ALSA:SW_PARAMS END--------------------------------------------------------------\n"); |
|
429 |
|
} |
|
430 |
392 |
STATIC void dec_a_grow(void) |
STATIC void dec_a_grow(void) |
431 |
393 |
{ |
{ |
432 |
394 |
u32 new_idx; |
u32 new_idx; |
|
... |
... |
STATIC void draining_state_switch(void) |
606 |
568 |
if (r == -1) |
if (r == -1) |
607 |
569 |
fatal("unable to arm the draining timer\n"); |
fatal("unable to arm the draining timer\n"); |
608 |
570 |
} |
} |
609 |
|
#define NO 0 |
|
610 |
|
#define AGAIN 0 |
|
611 |
|
#define RECOVERED 1 |
|
612 |
|
#define CONTINUE 2 |
|
613 |
|
#define HAVE_FILT_SET 1 |
|
614 |
|
#define EOF_FILT 2 |
|
615 |
|
#define NO_DEC_SET 2 |
|
616 |
|
STATIC void pcm_filt_frs_write(snd_pcm_ufrs_t ufrs_n) { loop |
|
|
571 |
|
#define NO_DEC_SET 2 |
|
572 |
|
#define FILT_RECFG_REQUIRED 4 |
|
573 |
|
#define EOF_FILT 2 |
|
574 |
|
#define DRAINING 3 |
|
575 |
|
#define HAVE_FILT_SET 1 |
|
576 |
|
#define PRINT_INFO true |
|
577 |
|
/* synchronous filt or will end up asynchronous in the pipeline one day */ |
|
578 |
|
STATIC u8 dec_set_filter(void) |
|
579 |
|
{ |
|
580 |
|
u8 r; |
|
581 |
|
|
|
582 |
|
loop { |
|
583 |
|
int new_chans_n; |
|
584 |
|
uint64_t new_chans_layout; |
|
585 |
|
int new_rate; |
|
586 |
|
enum avutil_audio_fr_fmt_t new_fmt; |
|
587 |
|
int dst_chans_n; |
|
588 |
|
uint64_t dst_chans_layout; |
|
589 |
|
int dst_rate; |
|
590 |
|
enum avutil_audio_fr_fmt_t dst_fmt; |
|
591 |
|
|
|
592 |
|
r = filt_push_dec_set(&new_chans_n, &new_chans_layout, |
|
593 |
|
&new_rate, &new_fmt); |
|
594 |
|
if (r == NO_DEC_SET) /* pipeline not fast enough */ |
|
595 |
|
return NO_DEC_SET; |
|
596 |
|
else if (r != FILT_RECFG_REQUIRED) { |
|
597 |
|
/* FILT_SWITCHED_TO_DRAINING | PUSHED_ONE_SET | AGAIN */ |
|
598 |
|
break; |
|
599 |
|
} |
|
600 |
|
/* FILT_RECFG_REQUIRED */ |
|
601 |
|
pcm2ff_strict(npv_audio_pcm_p, &dst_chans_n, &dst_chans_layout, |
|
602 |
|
&dst_rate, &dst_fmt, PRINT_INFO); |
|
603 |
|
/* may not have a valid src chans layout, "fix it" */ |
|
604 |
|
if (new_chans_layout == 0) |
|
605 |
|
new_chans_layout = avutil_get_default_chans_layout( |
|
606 |
|
new_chans_n); |
|
607 |
|
filt_cfg(new_chans_n, new_chans_layout, new_rate, new_fmt, |
|
608 |
|
filt_p.muted, filt_p.vol, |
|
609 |
|
dst_chans_n, dst_chans_layout, dst_rate, dst_fmt, |
|
610 |
|
PRINT_INFO); |
|
611 |
|
} |
|
612 |
|
r = npv_audio_filt_set_get(); |
|
613 |
|
if (r == EOF_FILT) { |
|
614 |
|
draining_state_switch(); |
|
615 |
|
return DRAINING; |
|
616 |
|
} |
|
617 |
|
return HAVE_FILT_SET; |
|
618 |
|
} |
|
619 |
|
#undef NO_DEC_SET |
|
620 |
|
#undef FILT_RECFG_REQUIRED |
|
621 |
|
#undef EOF_FILT |
|
622 |
|
#undef DRAINING |
|
623 |
|
#undef HAVE_FILT_SET |
|
624 |
|
#undef PRINT_INFO |
|
625 |
|
#define NO 0 |
|
626 |
|
#define AGAIN 0 |
|
627 |
|
#define RECOVERED 1 |
|
628 |
|
#define CONTINUE 2 |
|
629 |
|
#define NO_DEC_SET 2 |
|
630 |
|
#define ALL_FRS_WRITTEN 0 |
|
631 |
|
/* #define RECOVERED 1 */ |
|
632 |
|
#define INCOMPLETE_WRITE 2 |
|
633 |
|
#define DRAINING 3 |
|
634 |
|
#define PRINT_INFO true |
|
635 |
|
STATIC u8 pcm_filt_frs_write(snd_pcm_ufrs_t *ufrs_n) { loop |
617 |
636 |
{ |
{ |
618 |
637 |
u8 chan_buf; |
u8 chan_buf; |
619 |
638 |
u8 *chans_buf[AVUTIL_DATA_PTRS_N]; |
u8 *chans_buf[AVUTIL_DATA_PTRS_N]; |
|
... |
... |
STATIC void pcm_filt_frs_write(snd_pcm_ufrs_t ufrs_n) { loop |
622 |
641 |
int is_planar_fmt; |
int is_planar_fmt; |
623 |
642 |
snd_pcm_ufrs_t written_ufrs_n; /* for clarity */ |
snd_pcm_ufrs_t written_ufrs_n; /* for clarity */ |
624 |
643 |
|
|
625 |
|
if (ufrs_n == 0) |
|
626 |
|
break; |
|
627 |
|
/* |
|
628 |
|
* in this loop we try to get some filt frs from what we got from the |
|
629 |
|
* dec |
|
630 |
|
*/ |
|
631 |
|
if (npv_audio_filt_p.set->frs_n == 0) loop { |
|
|
644 |
|
if (*ufrs_n == 0) |
|
645 |
|
return ALL_FRS_WRITTEN; |
|
646 |
|
/* synchronous filtering */ |
|
647 |
|
if (npv_audio_filt_p.set->frs_n == 0) { |
632 |
648 |
u8 r; |
u8 r; |
633 |
649 |
|
|
634 |
|
/* we _really_ want audio data */ |
|
635 |
|
(void)filt_push_dec_sets(); |
|
636 |
|
r = npv_audio_filt_set_try_get(); |
|
637 |
|
if (r == EOF_FILT) { |
|
638 |
|
draining_state_switch(); |
|
639 |
|
return; |
|
640 |
|
} else if (r == HAVE_FILT_SET) { |
|
641 |
|
npv_audio_filt_p.pcm_written_ufrs_n = 0; |
|
642 |
|
break; |
|
643 |
|
} |
|
644 |
|
/* r == AGAIN */ |
|
|
650 |
|
r = dec_set_filter(); |
|
651 |
|
if (r == NO_DEC_SET || r == DRAINING) |
|
652 |
|
return r; |
|
653 |
|
/* HAVE_FILT_SET */ |
|
654 |
|
npv_audio_filt_p.pcm_written_ufrs_n = 0; |
645 |
655 |
} |
} |
646 |
656 |
chans_buf_init(chans_buf, (int)npv_audio_filt_p.pcm_written_ufrs_n); |
chans_buf_init(chans_buf, (int)npv_audio_filt_p.pcm_written_ufrs_n); |
647 |
657 |
filt_set_remaining_ufrs_n = (snd_pcm_ufrs_t)npv_audio_filt_p.set->frs_n |
filt_set_remaining_ufrs_n = (snd_pcm_ufrs_t)npv_audio_filt_p.set->frs_n |
648 |
658 |
- npv_audio_filt_p.pcm_written_ufrs_n; |
- npv_audio_filt_p.pcm_written_ufrs_n; |
649 |
|
if (filt_set_remaining_ufrs_n > ufrs_n) |
|
650 |
|
ufrs_to_write_n = ufrs_n; |
|
|
659 |
|
if (filt_set_remaining_ufrs_n > *ufrs_n) |
|
660 |
|
ufrs_to_write_n = *ufrs_n; |
651 |
661 |
else |
else |
652 |
662 |
ufrs_to_write_n = filt_set_remaining_ufrs_n; |
ufrs_to_write_n = filt_set_remaining_ufrs_n; |
653 |
663 |
is_planar_fmt = avutil_audio_fr_fmt_is_planar( |
is_planar_fmt = avutil_audio_fr_fmt_is_planar( |
|
... |
... |
STATIC void pcm_filt_frs_write(snd_pcm_ufrs_t ufrs_n) { loop |
677 |
687 |
npv_audio_filt_p.set->frs_n) |
npv_audio_filt_p.set->frs_n) |
678 |
688 |
/* set audio_filt_p.set->frs_n = 0 */ |
/* set audio_filt_p.set->frs_n = 0 */ |
679 |
689 |
avutil_audio_set_unref(npv_audio_filt_p.set); |
avutil_audio_set_unref(npv_audio_filt_p.set); |
680 |
|
return; |
|
|
690 |
|
return RECOVERED; |
681 |
691 |
} |
} |
682 |
692 |
/* r_recover == CONTINUE */ |
/* r_recover == CONTINUE */ |
683 |
693 |
written_ufrs_n += (snd_pcm_ufrs_t)alsa_r; |
written_ufrs_n += (snd_pcm_ufrs_t)alsa_r; |
|
... |
... |
STATIC void pcm_filt_frs_write(snd_pcm_ufrs_t ufrs_n) { loop |
689 |
699 |
* this is here we update our ref time point for the audio clk |
* this is here we update our ref time point for the audio clk |
690 |
700 |
* because with a new filt set of frs, we get a new ts |
* because with a new filt set of frs, we get a new ts |
691 |
701 |
* |
* |
692 |
|
* XXX: getting the "right" ts from ff is convoluted |
|
|
702 |
|
* XXX: getting the "right" ts from ff is shady/convoluted? |
693 |
703 |
*/ |
*/ |
694 |
704 |
if (npv_audio_filt_p.pcm_written_ufrs_n == 0) |
if (npv_audio_filt_p.pcm_written_ufrs_n == 0) |
695 |
705 |
npv_clk_ref_time_point_update(npv_audio_filt_p.set->pts, |
npv_clk_ref_time_point_update(npv_audio_filt_p.set->pts, |
696 |
706 |
written_ufrs_n); |
written_ufrs_n); |
697 |
707 |
npv_audio_filt_p.pcm_written_ufrs_n += written_ufrs_n; |
npv_audio_filt_p.pcm_written_ufrs_n += written_ufrs_n; |
698 |
|
ufrs_n -= written_ufrs_n; |
|
|
708 |
|
*ufrs_n -= written_ufrs_n; |
699 |
709 |
|
|
700 |
710 |
if ((int)npv_audio_filt_p.pcm_written_ufrs_n |
if ((int)npv_audio_filt_p.pcm_written_ufrs_n |
701 |
711 |
== npv_audio_filt_p.set->frs_n) |
== npv_audio_filt_p.set->frs_n) |
|
... |
... |
STATIC void pcm_filt_frs_write(snd_pcm_ufrs_t ufrs_n) { loop |
706 |
716 |
#undef AGAIN |
#undef AGAIN |
707 |
717 |
#undef RECOVERED |
#undef RECOVERED |
708 |
718 |
#undef CONTINUE |
#undef CONTINUE |
709 |
|
#undef HAVE_FILT_SET |
|
710 |
|
#undef EOF_FILT |
|
711 |
719 |
#undef NO_DEC_SET |
#undef NO_DEC_SET |
712 |
|
/* fatal if the wiring cannot be done */ |
|
713 |
|
STATIC void pcm_layout2ff_fmt_strict(snd_pcm_fmt_t alsa_fmt, |
|
714 |
|
snd_pcm_access_t alsa_access, enum avutil_audio_fr_fmt_t *ff_fmt, |
|
715 |
|
bool print_info) |
|
716 |
|
{ |
|
717 |
|
/* |
|
718 |
|
* ff fmt byte order is always native. |
|
719 |
|
* here we handle little endian only |
|
720 |
|
*/ |
|
721 |
|
switch (alsa_fmt) { |
|
722 |
|
case SND_PCM_FMT_FLOAT: |
|
723 |
|
if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) |
|
724 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_FLT; |
|
725 |
|
else |
|
726 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_FLTP; |
|
727 |
|
break; |
|
728 |
|
case SND_PCM_FMT_S32: |
|
729 |
|
if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) |
|
730 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_S32; |
|
731 |
|
else |
|
732 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_S32P; |
|
733 |
|
break; |
|
734 |
|
case SND_PCM_FMT_S16: |
|
735 |
|
if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) |
|
736 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_S16; |
|
737 |
|
else |
|
738 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_S16P; |
|
739 |
|
break; |
|
740 |
|
case SND_PCM_FMT_U8: |
|
741 |
|
if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) |
|
742 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_U8; |
|
743 |
|
else |
|
744 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_U8P; |
|
745 |
|
break; |
|
746 |
|
default: |
|
747 |
|
fatal("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)); |
|
748 |
|
} |
|
749 |
|
if (print_info) { |
|
750 |
|
u8 ff_fmt_str[STR_SZ]; |
|
751 |
|
|
|
752 |
|
avutil_get_audio_fr_fmt_str(ff_fmt_str, sizeof(ff_fmt_str), |
|
753 |
|
*ff_fmt); |
|
754 |
|
pout("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); |
|
755 |
|
} |
|
756 |
|
} |
|
757 |
|
/* |
|
758 |
|
* XXX: if it is ever used significantly, a fine granularity wiring strategy |
|
759 |
|
* will be implemented instead of using the default wiring |
|
760 |
|
*/ |
|
761 |
|
STATIC uint64_t pcm_chmaps2ff_chans_layout(snd_pcm_t *pcm, |
|
762 |
|
unsigned int pcm_chans_n, bool print_info) |
|
763 |
|
{ |
|
764 |
|
int r; |
|
765 |
|
uint64_t ff_chans_layout; |
|
766 |
|
snd_pcm_chmap_t *pcm_chmap; |
|
767 |
|
u8 chans_layout_str[STR_SZ]; /* should be overkill */ |
|
768 |
|
|
|
769 |
|
pcm_chmap = snd_pcm_get_chmap(pcm); |
|
770 |
|
if (pcm_chmap == 0) { |
|
771 |
|
if (print_info) |
|
772 |
|
pout("alsa:no pcm channel map available, wiring to default ffmpeg channel layout\n"); |
|
773 |
|
} else { |
|
774 |
|
if (print_info) |
|
775 |
|
pout("alsa:your pcm device support channel maps, but fine granularity wiring strategy is not implemented\n"); |
|
776 |
|
free(pcm_chmap); |
|
777 |
|
} |
|
778 |
|
ff_chans_layout = avutil_get_default_chans_layout((int)pcm_chans_n); |
|
779 |
|
avutil_get_chans_layout_str(chans_layout_str, sizeof(chans_layout_str), |
|
780 |
|
(int)pcm_chans_n, ff_chans_layout); |
|
781 |
|
if (print_info) |
|
782 |
|
pout("alsa channel map wired to ffmpeg channel layout:\"%s\" (%u pcm channels)\n", chans_layout_str, pcm_chans_n); |
|
783 |
|
return ff_chans_layout; |
|
784 |
|
} |
|
|
720 |
|
#undef ALL_FRS_WRITTEN |
|
721 |
|
#undef INCOMPLETE_WRITE |
|
722 |
|
#undef DRAINING |
|
723 |
|
#undef PRINT_INFO |
785 |
724 |
STATIC void init_pcm_once_public(u8 *pcm_str) |
STATIC void init_pcm_once_public(u8 *pcm_str) |
786 |
725 |
{ |
{ |
787 |
726 |
int r; |
int r; |
|
... |
... |
STATIC void dec_a_unref_all(void) |
855 |
794 |
} |
} |
856 |
795 |
dec_sets_p.n = 0; |
dec_sets_p.n = 0; |
857 |
796 |
} |
} |
|
797 |
|
/* fatal if the wiring cannot be done */ |
|
798 |
|
STATIC void pcm_layout2ff_fmt_strict(snd_pcm_fmt_t alsa_fmt, |
|
799 |
|
snd_pcm_access_t alsa_access, enum avutil_audio_fr_fmt_t *ff_fmt, |
|
800 |
|
bool print_info) |
|
801 |
|
{ |
|
802 |
|
/* |
|
803 |
|
* ff fmt byte order is always native. |
|
804 |
|
* here we handle little endian only |
|
805 |
|
*/ |
|
806 |
|
switch (alsa_fmt) { |
|
807 |
|
case SND_PCM_FMT_FLOAT: |
|
808 |
|
if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) |
|
809 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_FLT; |
|
810 |
|
else |
|
811 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_FLTP; |
|
812 |
|
break; |
|
813 |
|
case SND_PCM_FMT_S32: |
|
814 |
|
if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) |
|
815 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_S32; |
|
816 |
|
else |
|
817 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_S32P; |
|
818 |
|
break; |
|
819 |
|
case SND_PCM_FMT_S16: |
|
820 |
|
if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) |
|
821 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_S16; |
|
822 |
|
else |
|
823 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_S16P; |
|
824 |
|
break; |
|
825 |
|
case SND_PCM_FMT_U8: |
|
826 |
|
if (alsa_access == SND_PCM_ACCESS_RW_INTERLEAVED) |
|
827 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_U8; |
|
828 |
|
else |
|
829 |
|
*ff_fmt = AVUTIL_AUDIO_FR_FMT_U8P; |
|
830 |
|
break; |
|
831 |
|
default: |
|
832 |
|
fatal("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)); |
|
833 |
|
} |
|
834 |
|
if (print_info) { |
|
835 |
|
u8 ff_fmt_str[STR_SZ]; |
|
836 |
|
|
|
837 |
|
avutil_get_audio_fr_fmt_str(ff_fmt_str, sizeof(ff_fmt_str), |
|
838 |
|
*ff_fmt); |
|
839 |
|
pout("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); |
|
840 |
|
} |
|
841 |
|
} |
File npv/audio/namespace/main.c changed (mode: 100644) (index a374f68..6601cff) |
7 |
7 |
#define dec_ctx_mutex_l npv_audio_dec_ctx_mutex_l |
#define dec_ctx_mutex_l npv_audio_dec_ctx_mutex_l |
8 |
8 |
#define dec_flush npv_audio_dec_flush |
#define dec_flush npv_audio_dec_flush |
9 |
9 |
#define dec_l npv_audio_dec_l |
#define dec_l npv_audio_dec_l |
|
10 |
|
#define dec_set_filter npv_audio_dec_set_filter |
10 |
11 |
#define draining_state_handle npv_audio_draining_state_handle |
#define draining_state_handle npv_audio_draining_state_handle |
11 |
12 |
#define draining_state_switch npv_audio_draining_state_switch |
#define draining_state_switch npv_audio_draining_state_switch |
12 |
13 |
#define fatal npv_audio_fatal |
#define fatal npv_audio_fatal |
13 |
14 |
#define ff_fmt2pcm_layout_best_effort npv_audio_ff_fmt2pcm_layout_best_effort |
#define ff_fmt2pcm_layout_best_effort npv_audio_ff_fmt2pcm_layout_best_effort |
14 |
|
#define filt_push_dec_sets npv_audio_filt_push_dec_sets |
|
|
15 |
|
/*----------------------------------------------------------------------------*/ |
|
16 |
|
/* from audio/filt */ |
|
17 |
|
#define filt_cfg npv_audio_filt_cfg |
|
18 |
|
#define filt_p npv_audio_filt_p |
|
19 |
|
#define filt_push_dec_set npv_audio_filt_push_dec_set |
|
20 |
|
/*----------------------------------------------------------------------------*/ |
15 |
21 |
#define init_once_local npv_audio_init_once_local |
#define init_once_local npv_audio_init_once_local |
16 |
22 |
#define init_once_public npv_audio_init_once_public |
#define init_once_public npv_audio_init_once_public |
17 |
23 |
#define init_pcm_once_public npv_audio_init_pcm_once_public |
#define init_pcm_once_public npv_audio_init_pcm_once_public |
18 |
|
#define kernel_ts_types_str npv_audio_kernel_ts_types_str |
|
|
24 |
|
#define kernel_ts_types_str_l npv_audio_kernel_ts_types_str_l |
19 |
25 |
#define pcm_chmaps2ff_chans_layout npv_audio_pcm_chmaps2ff_chans_layout |
#define pcm_chmaps2ff_chans_layout npv_audio_pcm_chmaps2ff_chans_layout |
20 |
|
#define pcm_cfg_hw npv_audio_pcm_cfg_hw |
|
21 |
|
#define pcm_cfg_hw_core npv_audio_pcm_cfg_hw_core |
|
22 |
|
#define pcm_cfg_sw npv_audio_pcm_cfg_sw |
|
|
26 |
|
#define pcm_cfg_hw_core_best_effort npv_audio_pcm_cfg_hw_core_best_effort |
23 |
27 |
#define pcm_filt_frs_write npv_audio_pcm_filt_frs_write |
#define pcm_filt_frs_write npv_audio_pcm_filt_frs_write |
24 |
28 |
#define pcm_hw_access_decide npv_audio_pcm_hw_access_decide |
#define pcm_hw_access_decide npv_audio_pcm_hw_access_decide |
25 |
29 |
#define pcm_hw_access_decide_x npv_audio_pcm_hw_access_decide_x |
#define pcm_hw_access_decide_x npv_audio_pcm_hw_access_decide_x |
|
34 |
38 |
#define pcm_perr_l npv_audio_pcm_perr_l |
#define pcm_perr_l npv_audio_pcm_perr_l |
35 |
39 |
#define pcm_silence_bufs_l npv_audio_pcm_silence_bufs_l |
#define pcm_silence_bufs_l npv_audio_pcm_silence_bufs_l |
36 |
40 |
#define pcm_silence_frs_write npv_audio_pcm_silence_frs_write |
#define pcm_silence_frs_write npv_audio_pcm_silence_frs_write |
|
41 |
|
#define pcm2ff npv_audio_pcm2ff |
37 |
42 |
#define pout npv_audio_pout |
#define pout npv_audio_pout |
38 |
43 |
#define warning npv_audio_warning |
#define warning npv_audio_warning |
39 |
44 |
/*============================================================================*/ |
/*============================================================================*/ |
|
45 |
50 |
#undef dec_a_unref_all |
#undef dec_a_unref_all |
46 |
51 |
#undef dec_ctx_mutex_l |
#undef dec_ctx_mutex_l |
47 |
52 |
#undef dec_l |
#undef dec_l |
|
53 |
|
#undef dec_set_filter |
48 |
54 |
#undef dec_flush |
#undef dec_flush |
49 |
55 |
#undef draining_state_handle |
#undef draining_state_handle |
50 |
56 |
#undef draining_state_switch |
#undef draining_state_switch |
51 |
57 |
#undef fatal |
#undef fatal |
52 |
58 |
#undef ff_fmt2pcm_layout_best_effort |
#undef ff_fmt2pcm_layout_best_effort |
53 |
|
#undef filt_push_dec_sets |
|
|
59 |
|
#undef filt_cfg |
|
60 |
|
#undef filt_p |
|
61 |
|
#undef filt_push_dec_set |
54 |
62 |
#undef init_once_local |
#undef init_once_local |
55 |
63 |
#undef init_once_public |
#undef init_once_public |
56 |
64 |
#undef init_pcm_once_public |
#undef init_pcm_once_public |
57 |
|
#undef kernel_ts_types_str |
|
|
65 |
|
#undef kernel_ts_types_str_l |
58 |
66 |
#undef pcm_chmaps2ff_chans_layout |
#undef pcm_chmaps2ff_chans_layout |
59 |
|
#undef pcm_cfg_hw |
|
60 |
|
#undef pcm_cfg_hw_core |
|
61 |
|
#undef pcm_cfg_sw |
|
|
67 |
|
#undef pcm_cfg_hw_core_best_effort |
62 |
68 |
#undef pcm_filt_frs_write |
#undef pcm_filt_frs_write |
63 |
69 |
#undef pcm_hw_access_decide |
#undef pcm_hw_access_decide |
64 |
70 |
#undef pcm_hw_access_decide_x |
#undef pcm_hw_access_decide_x |
|
73 |
79 |
#undef pcm_perr_l |
#undef pcm_perr_l |
74 |
80 |
#undef pcm_silence_bufs_l |
#undef pcm_silence_bufs_l |
75 |
81 |
#undef pcm_silence_frs_write |
#undef pcm_silence_frs_write |
|
82 |
|
#undef pcm2ff |
76 |
83 |
#undef pout |
#undef pout |
77 |
84 |
#undef warning |
#undef warning |
78 |
85 |
#endif |
#endif |
File npv/audio/public/code.frag.c changed (mode: 100644) (index bbd0bc9..9ac9f70) |
... |
... |
STATIC void draining_state_evt(void) |
83 |
83 |
fatal("unable to read the number of draining state timer expirations\n"); |
fatal("unable to read the number of draining state timer expirations\n"); |
84 |
84 |
draining_state_handle(); |
draining_state_handle(); |
85 |
85 |
} |
} |
86 |
|
#define AGAIN 0 |
|
87 |
|
#define RECOVERED 1 |
|
|
86 |
|
#define AGAIN 0 |
|
87 |
|
#define RECOVERED 1 |
|
88 |
|
#define INCOMPLETE_WRITE 1 |
88 |
89 |
STATIC void evt_pcm_write(void) |
STATIC void evt_pcm_write(void) |
89 |
90 |
{ |
{ |
90 |
91 |
snd_pcm_sfrs_t alsa_r; |
snd_pcm_sfrs_t alsa_r; |
91 |
92 |
snd_pcm_ufrs_t ufrs_n; |
snd_pcm_ufrs_t ufrs_n; |
92 |
|
u8 r_recover; |
|
|
93 |
|
u8 r; |
93 |
94 |
|
|
94 |
95 |
alsa_r = snd_pcm_avail(pcm_p); |
alsa_r = snd_pcm_avail(pcm_p); |
95 |
|
r_recover = alsa_recover(alsa_r); |
|
96 |
|
if (r_recover == AGAIN || r_recover == RECOVERED) |
|
|
96 |
|
r = alsa_recover(alsa_r); |
|
97 |
|
if (r == AGAIN || r == RECOVERED) |
97 |
98 |
return; |
return; |
98 |
|
/* r_recover == CONTINUE */ |
|
|
99 |
|
/* r == CONTINUE */ |
99 |
100 |
ufrs_n = (snd_pcm_ufrs_t)alsa_r; |
ufrs_n = (snd_pcm_ufrs_t)alsa_r; |
100 |
|
if (npv_paused_p) |
|
|
101 |
|
if (npv_paused_p) { |
101 |
102 |
pcm_silence_frs_write(ufrs_n); |
pcm_silence_frs_write(ufrs_n); |
102 |
|
else |
|
103 |
|
pcm_filt_frs_write(ufrs_n); |
|
|
103 |
|
return; |
|
104 |
|
} |
|
105 |
|
r = pcm_filt_frs_write(&ufrs_n); |
|
106 |
|
if (r == INCOMPLETE_WRITE) |
|
107 |
|
pcm_silence_frs_write(ufrs_n); |
|
108 |
|
/* DRAINING | ALL_FRS_WRITTEN | RECOVERED */ |
104 |
109 |
} |
} |
105 |
110 |
#undef AGAIN |
#undef AGAIN |
106 |
111 |
#undef RECOVERED |
#undef RECOVERED |
|
112 |
|
#undef INCOMPLETE_WRITE |
107 |
113 |
STATIC void pcm_silence_bufs_cfg(snd_pcm_t *pcm, bool print_info) |
STATIC void pcm_silence_bufs_cfg(snd_pcm_t *pcm, bool print_info) |
108 |
114 |
{ |
{ |
109 |
115 |
int r; |
int r; |
|
... |
... |
STATIC void dec_sets_unlock(void) |
237 |
243 |
if (r != 0) |
if (r != 0) |
238 |
244 |
fatal("%d:unable to unlock the array of decoder sets\n", r); |
fatal("%d:unable to unlock the array of decoder sets\n", r); |
239 |
245 |
} |
} |
240 |
|
STATIC void pcm_cfg(snd_pcm_t *pcm, unsigned int chans_n, unsigned int rate, |
|
241 |
|
enum avutil_audio_fr_fmt_t ff_fmt) |
|
242 |
|
{ |
|
243 |
|
pcm_cfg_hw(pcm, chans_n, rate, ff_fmt); |
|
244 |
|
pcm_cfg_sw(pcm); |
|
245 |
|
pout("ALSA PCM DUMP START-------------------------------------------------------------\n"); |
|
246 |
|
snd_pcm_dump(pcm, pcm_pout_l); |
|
247 |
|
pout("ALSA PCM DUMP END---------------------------------------------------------------\n"); |
|
248 |
|
} |
|
249 |
|
STATIC void pcm2ff(snd_pcm_t *pcm, enum avutil_audio_fr_fmt_t *ff_fmt, |
|
250 |
|
int *ff_rate, int *ff_chans_n, uint64_t *ff_chans_layout, |
|
251 |
|
bool print_info) |
|
|
246 |
|
STATIC void pcm_cfg_hw_best_effort(snd_pcm_t *pcm, int chans_n, |
|
247 |
|
uint64_t ff_chans_layout, int rate, enum avutil_audio_fr_fmt_t ff_fmt) |
252 |
248 |
{ |
{ |
253 |
249 |
int r; |
int r; |
|
250 |
|
s8 i; |
|
251 |
|
snd_pcm_access_t access; |
254 |
252 |
snd_pcm_hw_params_t *hw_params; |
snd_pcm_hw_params_t *hw_params; |
255 |
|
snd_pcm_access_t pcm_access; |
|
256 |
|
snd_pcm_fmt_t pcm_fmt; |
|
257 |
|
unsigned int pcm_rate; |
|
258 |
|
unsigned int pcm_chans_n; |
|
259 |
|
|
|
|
253 |
|
|
|
254 |
|
pout("ALSA:HW_PARAMS START------------------------------------------------------------\n"); |
260 |
255 |
r = snd_pcm_hw_params_malloc(&hw_params); |
r = snd_pcm_hw_params_malloc(&hw_params); |
261 |
256 |
if (r < 0) |
if (r < 0) |
262 |
|
fatal("alsa:unable to allocate hardware parameters context for ffmpeg filter wiring\n"); |
|
|
257 |
|
fatal("alsa:unable to allocate hardware parameters context\n"); |
|
258 |
|
pcm_cfg_hw_core_best_effort(pcm, hw_params, chans_n, ff_chans_layout, |
|
259 |
|
rate, ff_fmt); |
|
260 |
|
r = snd_pcm_hw_params(pcm, hw_params); |
|
261 |
|
if (r != 0) |
|
262 |
|
fatal("alsa:unable to install the hardware parameters\n"); |
263 |
263 |
r = snd_pcm_hw_params_current(pcm, hw_params); |
r = snd_pcm_hw_params_current(pcm, hw_params); |
264 |
264 |
if (r != 0) |
if (r != 0) |
265 |
|
fatal("alsa:unable to get current hardware parameters for ffmpeg filter wiring\n"); |
|
266 |
|
r = snd_pcm_hw_params_get_access(hw_params, &pcm_access); |
|
267 |
|
if (r < 0) |
|
268 |
|
fatal("alsa:unable to get the pcm access for ffmpeg filter wiring\n"); |
|
269 |
|
r = snd_pcm_hw_params_get_fmt(hw_params, &pcm_fmt); |
|
270 |
|
if (r < 0) |
|
271 |
|
fatal("alsa:unable to get the pcm format for ffmpeg filter wiring\n"); |
|
272 |
|
/*--------------------------------------------------------------------*/ |
|
273 |
|
pcm_layout2ff_fmt_strict(pcm_fmt, pcm_access, ff_fmt, print_info); |
|
274 |
|
/*--------------------------------------------------------------------*/ |
|
275 |
|
r = snd_pcm_hw_params_get_rate(hw_params, &pcm_rate, |
|
276 |
|
SND_PCM_ST_PLAYBACK); |
|
277 |
|
if (r < 0) |
|
278 |
|
fatal("alsa:unable to get the pcm rate for ffmpeg filter wiring\n"); |
|
279 |
|
*ff_rate = (int)pcm_rate; |
|
280 |
|
r = snd_pcm_hw_params_get_chans_n(hw_params, &pcm_chans_n); |
|
281 |
|
if (r < 0) |
|
282 |
|
fatal("alsa:unable to get the pcm count of channels for ffmpeg filter wiring\n"); |
|
283 |
|
*ff_chans_n = (int)pcm_chans_n; |
|
284 |
|
/*--------------------------------------------------------------------*/ |
|
285 |
|
*ff_chans_layout = pcm_chmaps2ff_chans_layout(pcm, pcm_chans_n, |
|
286 |
|
print_info); |
|
287 |
|
/*--------------------------------------------------------------------*/ |
|
|
265 |
|
fatal("alsa:unable to get current hardware parameters\n"); |
|
266 |
|
snd_pcm_hw_params_dump(hw_params, pcm_pout_l); |
|
267 |
|
i = 0; |
|
268 |
|
selected_ts_type_p = -1; |
|
269 |
|
loop { |
|
270 |
|
if (i == ARRAY_N(kernel_ts_types_str_l)) |
|
271 |
|
break; |
|
272 |
|
r = snd_pcm_hw_params_supports_audio_ts_type(hw_params, i); |
|
273 |
|
if (r == 1) { |
|
274 |
|
selected_ts_type_p = i; |
|
275 |
|
pout("kernel audio timestamp type \"%s\" is supported for the current configuration\n", kernel_ts_types_str_l[i]); |
|
276 |
|
} |
|
277 |
|
++i; |
|
278 |
|
} |
|
279 |
|
/* |
|
280 |
|
* we selected the most accurate, namely with the highest idx, audio ts |
|
281 |
|
* type |
|
282 |
|
*/ |
|
283 |
|
pout("%s will be used for the audio based clock\n", kernel_ts_types_str_l[selected_ts_type_p]); |
288 |
284 |
snd_pcm_hw_params_free(hw_params); |
snd_pcm_hw_params_free(hw_params); |
|
285 |
|
pout("ALSA:HW_PARAMS END--------------------------------------------------------------\n"); |
|
286 |
|
} |
|
287 |
|
STATIC void pcm_cfg_sw(snd_pcm_t *pcm) |
|
288 |
|
{ |
|
289 |
|
int r; |
|
290 |
|
snd_pcm_sw_params_t *sw_params; |
|
291 |
|
|
|
292 |
|
pout("ALSA:SW_PARAMS START------------------------------------------------------------\n"); |
|
293 |
|
r = snd_pcm_sw_params_malloc(&sw_params); |
|
294 |
|
if (r != 0) |
|
295 |
|
fatal("alsa:unable to allocate software parameters structure\n"); |
|
296 |
|
r = snd_pcm_sw_params_current(pcm, sw_params); |
|
297 |
|
if (r != 0) |
|
298 |
|
fatal("alsa:unable to get current software parameters\n"); |
|
299 |
|
r = snd_pcm_sw_params_set_period_evt(pcm, sw_params, 1); |
|
300 |
|
if (r != 0) |
|
301 |
|
fatal("alsa:unable to enable period event\n"); |
|
302 |
|
/* enable ts to be sure */ |
|
303 |
|
r = snd_pcm_sw_params_set_tstamp_mode(pcm, sw_params, |
|
304 |
|
SND_PCM_TSTAMP_ENABLE); |
|
305 |
|
if (r < 0) |
|
306 |
|
fatal("unable to set timestamp mode:%s\n", snd_strerror(r)); |
|
307 |
|
r = snd_pcm_sw_params(pcm, sw_params); |
|
308 |
|
if (r != 0) |
|
309 |
|
fatal("alsa:unable to install sotfware parameters\n"); |
|
310 |
|
snd_pcm_sw_params_dump(sw_params, pcm_pout_l); |
|
311 |
|
snd_pcm_sw_params_free(sw_params); |
|
312 |
|
pout("ALSA:SW_PARAMS END--------------------------------------------------------------\n"); |
289 |
313 |
} |
} |
290 |
314 |
/* we do per-loop fine-grained locking */ |
/* we do per-loop fine-grained locking */ |
291 |
315 |
#define sz size |
#define sz size |
|
... |
... |
unlock_and_return: |
322 |
346 |
return; |
return; |
323 |
347 |
}} |
}} |
324 |
348 |
#undef sz |
#undef sz |
|
349 |
|
#define CHANS_N_NOT_OVERRIDDEN 0 |
|
350 |
|
#define RATE_NOT_OVERRIDDEN 0 |
|
351 |
|
#define AUDIO_FR_FMT_NOT_OVERRIDDEN AVUTIL_AUDIO_FR_FMT_NONE |
|
352 |
|
#define PRINT_INFO true |
|
353 |
|
STATIC void npv_audio_prepare(int override_initial_ff_chans_n, |
|
354 |
|
int override_initial_ff_rate, |
|
355 |
|
enum avutil_audio_fr_fmt_t override_initial_ff_fmt) |
|
356 |
|
{ |
|
357 |
|
int dst_chans_n; |
|
358 |
|
uint64_t dst_chans_layout; |
|
359 |
|
int dst_rate; |
|
360 |
|
enum avutil_audio_fr_fmt_t dst_fmt; |
|
361 |
|
int initial_ff_chans_n; |
|
362 |
|
uint64_t src_chans_layout; |
|
363 |
|
int initial_ff_rate; |
|
364 |
|
enum avutil_audio_fr_fmt_t initial_ff_fmt; |
|
365 |
|
/* |
|
366 |
|
* do our best to match the pcm cfg to audio ff dec output OR the user |
|
367 |
|
* overrides, BUT we don't expect to match it "exactly": a ff filt |
|
368 |
|
* will bridge the difference |
|
369 |
|
*/ |
|
370 |
|
if (override_initial_ff_chans_n == CHANS_N_NOT_OVERRIDDEN) |
|
371 |
|
initial_ff_chans_n = dec_ctx_p->chans_n; |
|
372 |
|
else |
|
373 |
|
initial_ff_chans_n = override_initial_ff_chans_n; |
|
374 |
|
/* the audio dec ctx may not have a valid chans layout */ |
|
375 |
|
if (dec_ctx_p->chans_layout == 0) { |
|
376 |
|
src_chans_layout = avutil_get_default_chans_layout( |
|
377 |
|
dec_ctx_p->chans_n); |
|
378 |
|
} else |
|
379 |
|
src_chans_layout = dec_ctx_p->chans_layout; |
|
380 |
|
if (override_initial_ff_rate == RATE_NOT_OVERRIDDEN) |
|
381 |
|
initial_ff_rate = dec_ctx_p->fr_rate; |
|
382 |
|
else |
|
383 |
|
initial_ff_rate = override_initial_ff_rate; |
|
384 |
|
if (override_initial_ff_fmt == AUDIO_FR_FMT_NOT_OVERRIDDEN) |
|
385 |
|
initial_ff_fmt = dec_ctx_p->fr_fmt; |
|
386 |
|
else |
|
387 |
|
initial_ff_fmt = override_initial_ff_fmt; |
|
388 |
|
npv_audio_pcm_cfg_hw_best_effort(pcm_p, initial_ff_chans_n, |
|
389 |
|
src_chans_layout, initial_ff_rate, initial_ff_fmt); |
|
390 |
|
npv_audio_pcm_silence_bufs_cfg(pcm_p, PRINT_INFO); |
|
391 |
|
npv_audio_pcm_cfg_sw(pcm_p); |
|
392 |
|
pout("ALSA PCM DUMP START-------------------------------------------------------------\n"); |
|
393 |
|
snd_pcm_dump(pcm_p, pcm_pout_l); |
|
394 |
|
pout("ALSA PCM DUMP END---------------------------------------------------------------\n"); |
|
395 |
|
} |
|
396 |
|
#undef CHANS_N_NOT_OVERRIDDEN |
|
397 |
|
#undef RATE_NOT_OVERRIDDEN |
|
398 |
|
#undef AUDIO_FR_FMT_NOT_OVERRIDDEN |
|
399 |
|
#undef PRINT_INFO |
|
400 |
|
STATIC void pcm2ff_strict(snd_pcm_t *pcm, int *ff_chans_n, |
|
401 |
|
uint64_t *ff_chans_layout, int *ff_rate, |
|
402 |
|
enum avutil_audio_fr_fmt_t *ff_fmt, bool print_info) |
|
403 |
|
{ |
|
404 |
|
int r; |
|
405 |
|
snd_pcm_hw_params_t *hw_params; |
|
406 |
|
unsigned int pcm_chans_n; |
|
407 |
|
unsigned int pcm_rate; |
|
408 |
|
snd_pcm_fmt_t pcm_fmt; |
|
409 |
|
snd_pcm_access_t pcm_access; |
|
410 |
|
|
|
411 |
|
r = snd_pcm_hw_params_malloc(&hw_params); |
|
412 |
|
if (r < 0) |
|
413 |
|
fatal("alsa:unable to allocate hardware parameters context for ffmpeg filter wiring\n"); |
|
414 |
|
r = snd_pcm_hw_params_current(pcm, hw_params); |
|
415 |
|
if (r != 0) |
|
416 |
|
fatal("alsa:unable to get current hardware parameters for ffmpeg filter wiring\n"); |
|
417 |
|
r = snd_pcm_hw_params_get_access(hw_params, &pcm_access); |
|
418 |
|
if (r < 0) |
|
419 |
|
fatal("alsa:unable to get the pcm access for ffmpeg filter wiring\n"); |
|
420 |
|
r = snd_pcm_hw_params_get_fmt(hw_params, &pcm_fmt); |
|
421 |
|
if (r < 0) |
|
422 |
|
fatal("alsa:unable to get the pcm format for ffmpeg filter wiring\n"); |
|
423 |
|
/*--------------------------------------------------------------------*/ |
|
424 |
|
pcm_layout2ff_fmt_strict(pcm_fmt, pcm_access, ff_fmt, print_info); |
|
425 |
|
/*--------------------------------------------------------------------*/ |
|
426 |
|
r = snd_pcm_hw_params_get_rate(hw_params, &pcm_rate, |
|
427 |
|
SND_PCM_ST_PLAYBACK); |
|
428 |
|
if (r < 0) |
|
429 |
|
fatal("alsa:unable to get the pcm rate for ffmpeg filter wiring\n"); |
|
430 |
|
*ff_rate = (int)pcm_rate; |
|
431 |
|
r = snd_pcm_hw_params_get_chans_n(hw_params, &pcm_chans_n); |
|
432 |
|
if (r < 0) |
|
433 |
|
fatal("alsa:unable to get the pcm count of channels for ffmpeg filter wiring\n"); |
|
434 |
|
*ff_chans_n = (int)pcm_chans_n; |
|
435 |
|
/*--------------------------------------------------------------------*/ |
|
436 |
|
*ff_chans_layout = pcm_chmaps2ff_chans_layout(pcm, pcm_chans_n, |
|
437 |
|
print_info); |
|
438 |
|
/*--------------------------------------------------------------------*/ |
|
439 |
|
snd_pcm_hw_params_free(hw_params); |
|
440 |
|
} |
File npv/local/code.frag.c changed (mode: 100644) (index e6de726..6ad6944) |
... |
... |
the ffmpeg audio frame formats which intersect alsa pcm audio formats are:\n" |
399 |
399 |
} |
} |
400 |
400 |
} |
} |
401 |
401 |
STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen, |
STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen, |
402 |
|
u16 *w, u16 *h, u8 **pcm_str, |
|
403 |
|
unsigned int *override_initial_ff_chans_n, |
|
404 |
|
unsigned int *override_initial_ff_rate, |
|
|
402 |
|
u16 *w, u16 *h, u8 **pcm_str, int *override_initial_ff_chans_n, |
|
403 |
|
int *override_initial_ff_rate, |
405 |
404 |
enum avutil_audio_fr_fmt_t *override_initial_ff_audio_fr_fmt, |
enum avutil_audio_fr_fmt_t *override_initial_ff_audio_fr_fmt, |
406 |
405 |
double *vol, u8 *pkts_prefill_percent) |
double *vol, u8 *pkts_prefill_percent) |
407 |
406 |
{ |
{ |
|
... |
... |
STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen, |
479 |
478 |
usage(); |
usage(); |
480 |
479 |
exit(1); |
exit(1); |
481 |
480 |
} |
} |
482 |
|
*override_initial_ff_rate = (unsigned int)strtoul( |
|
|
481 |
|
*override_initial_ff_rate = (unsigned int)strtol( |
483 |
482 |
args[i + 1], 0, 10); |
args[i + 1], 0, 10); |
484 |
483 |
pout("-fr:override initial ffmpeg audio rate to %uHz used for alsa pcm configuration\n", *override_initial_ff_rate); |
pout("-fr:override initial ffmpeg audio rate to %uHz used for alsa pcm configuration\n", *override_initial_ff_rate); |
485 |
484 |
i += 2; |
i += 2; |
|
... |
... |
STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen, |
489 |
488 |
usage(); |
usage(); |
490 |
489 |
exit(1); |
exit(1); |
491 |
490 |
} |
} |
492 |
|
*override_initial_ff_chans_n = (unsigned int)strtoul( |
|
|
491 |
|
*override_initial_ff_chans_n = (unsigned int)strtol( |
493 |
492 |
args[i + 1], 0, 10); |
args[i + 1], 0, 10); |
494 |
493 |
pout("-fc:override initial ffmpeg count of channels to %u used for alsa pcm configuration\n", *override_initial_ff_chans_n); |
pout("-fc:override initial ffmpeg count of channels to %u used for alsa pcm configuration\n", *override_initial_ff_chans_n); |
495 |
494 |
i += 2; |
i += 2; |
|
... |
... |
STATIC void init_once(u8 *url, bool start_fullscreen, double initial_vol, |
575 |
574 |
} |
} |
576 |
575 |
#undef WIDTH_NOT_DEFINED |
#undef WIDTH_NOT_DEFINED |
577 |
576 |
#undef HEIGHT_NOT_DEFINED |
#undef HEIGHT_NOT_DEFINED |
578 |
|
#define PRINT_INFO true |
|
579 |
|
#define CHANS_N_NOT_OVERRIDDEN 0 |
|
580 |
|
#define RATE_NOT_OVERRIDDEN 0 |
|
581 |
|
#define AUDIO_FR_FMT_NOT_OVERRIDDEN AVUTIL_AUDIO_FR_FMT_NONE |
|
582 |
|
STATIC void prepare(double initial_vol, |
|
583 |
|
unsigned int override_initial_ff_chans_n, |
|
584 |
|
unsigned int override_initial_ff_rate, |
|
|
577 |
|
STATIC void prepare(double initial_vol, int override_initial_ff_chans_n, |
|
578 |
|
int override_initial_ff_rate, |
585 |
579 |
enum avutil_audio_fr_fmt_t override_initial_ff_fmt, |
enum avutil_audio_fr_fmt_t override_initial_ff_fmt, |
586 |
580 |
u8 pkts_prefill_percent, avcodec_params_t *audio_codec_params, |
u8 pkts_prefill_percent, avcodec_params_t *audio_codec_params, |
587 |
581 |
avcodec_params_t *video_codec_params) |
avcodec_params_t *video_codec_params) |
588 |
582 |
{ |
{ |
589 |
|
enum avutil_audio_fr_fmt_t dst_fmt; |
|
590 |
|
int dst_rate; |
|
591 |
|
int dst_chans_n; |
|
592 |
|
uint64_t src_chans_layout; |
|
593 |
|
uint64_t dst_chans_layout; |
|
594 |
|
unsigned int initial_ff_chans_n; |
|
595 |
|
unsigned int initial_ff_rate; |
|
596 |
|
enum avutil_audio_fr_fmt_t initial_ff_fmt; |
|
597 |
|
|
|
598 |
583 |
npv_pipeline_limits_reset(); |
npv_pipeline_limits_reset(); |
599 |
584 |
npv_pipeline_prefill_reset(pkts_prefill_percent); |
npv_pipeline_prefill_reset(pkts_prefill_percent); |
600 |
|
|
|
601 |
585 |
npv_audio_dec_ctx_cfg(audio_codec_params); |
npv_audio_dec_ctx_cfg(audio_codec_params); |
602 |
586 |
npv_video_dec_ctx_cfg(video_codec_params); |
npv_video_dec_ctx_cfg(video_codec_params); |
603 |
|
/*--------------------------------------------------------------------*/ |
|
604 |
|
/* |
|
605 |
|
* do our best to match the pcm cfg to audio ff dec output OR the user |
|
606 |
|
* overrides, BUT we don't expect to match it "exactly": see right below |
|
607 |
|
* why. |
|
608 |
|
*/ |
|
609 |
|
if (override_initial_ff_chans_n == CHANS_N_NOT_OVERRIDDEN) |
|
610 |
|
initial_ff_chans_n = npv_audio_dec_ctx_p->chans_n; |
|
611 |
|
else |
|
612 |
|
initial_ff_chans_n = (unsigned int)override_initial_ff_chans_n; |
|
613 |
|
if (override_initial_ff_rate == RATE_NOT_OVERRIDDEN) |
|
614 |
|
initial_ff_rate = npv_audio_dec_ctx_p->fr_rate; |
|
615 |
|
else |
|
616 |
|
initial_ff_rate = (unsigned int)override_initial_ff_rate; |
|
617 |
|
if (override_initial_ff_fmt == AUDIO_FR_FMT_NOT_OVERRIDDEN) |
|
618 |
|
initial_ff_fmt = npv_audio_dec_ctx_p->fr_fmt; |
|
619 |
|
else |
|
620 |
|
initial_ff_fmt = override_initial_ff_fmt; |
|
621 |
|
/* |
|
622 |
|
* XXX: the ff chan layout is not used here, only the n of chans is |
|
623 |
|
* used. we consider that the pcm map of chans cannot be reasonably |
|
624 |
|
* configured (because "hardware"). then it would be "wired" properly in |
|
625 |
|
* the ff filter below (because "software") |
|
626 |
|
*/ |
|
627 |
|
npv_audio_pcm_cfg(npv_audio_pcm_p, initial_ff_chans_n, initial_ff_rate, |
|
628 |
|
initial_ff_fmt); |
|
629 |
|
/*--------------------------------------------------------------------*/ |
|
630 |
|
/* use a ff filt to fill in the gap between the pcm and audio ff dec */ |
|
631 |
|
npv_audio_pcm2ff(npv_audio_pcm_p, &dst_fmt, &dst_rate, &dst_chans_n, |
|
632 |
|
&dst_chans_layout, PRINT_INFO); |
|
633 |
|
/* the audio dec ctx may not have a valid chans layout */ |
|
634 |
|
if (npv_audio_dec_ctx_p->chans_layout == 0) { |
|
635 |
|
src_chans_layout = avutil_get_default_chans_layout( |
|
636 |
|
npv_audio_dec_ctx_p->chans_n); |
|
637 |
|
} else |
|
638 |
|
src_chans_layout = npv_audio_dec_ctx_p->chans_layout; |
|
639 |
|
npv_audio_filt_cfg( |
|
640 |
|
npv_audio_dec_ctx_p->fr_fmt, npv_audio_dec_ctx_p->fr_rate, |
|
641 |
|
npv_audio_dec_ctx_p->chans_n, src_chans_layout, false, |
|
642 |
|
initial_vol, dst_fmt, dst_rate, dst_chans_n, dst_chans_layout, |
|
643 |
|
PRINT_INFO); |
|
644 |
|
npv_audio_pcm_silence_bufs_cfg(npv_audio_pcm_p, PRINT_INFO); |
|
645 |
|
|
|
|
587 |
|
npv_audio_prepare(override_initial_ff_chans_n, override_initial_ff_rate, |
|
588 |
|
override_initial_ff_fmt); |
646 |
589 |
evt_add_all_fds(); |
evt_add_all_fds(); |
647 |
590 |
} |
} |
648 |
|
#undef PRINT_INFO |
|
649 |
|
#undef CHANS_N_NOT_OVERRIDDEN |
|
650 |
|
#undef RATE_NOT_OVERRIDDEN |
|
651 |
|
#undef AUDIO_FR_FMT_NOT_OVERRIDDEN |
|
652 |
591 |
STATIC void npv_cmd_quit(void) |
STATIC void npv_cmd_quit(void) |
653 |
592 |
{ |
{ |
654 |
593 |
exit_ok("quit command received\n"); |
exit_ok("quit command received\n"); |
|
... |
... |
int main(int argc, u8 **args) |
833 |
772 |
* missing ones with the initial codec params, which is the default |
* missing ones with the initial codec params, which is the default |
834 |
773 |
* behavior. |
* behavior. |
835 |
774 |
*/ |
*/ |
836 |
|
unsigned int override_initial_ff_chans_n; |
|
837 |
|
unsigned int override_initial_ff_rate; |
|
|
775 |
|
int override_initial_ff_chans_n; |
|
776 |
|
int override_initial_ff_rate; |
838 |
777 |
enum avutil_audio_fr_fmt_t override_initial_ff_audio_fr_fmt; |
enum avutil_audio_fr_fmt_t override_initial_ff_audio_fr_fmt; |
839 |
778 |
/* audio override -- end */ |
/* audio override -- end */ |
840 |
779 |
u8 *url; |
u8 *url; |