sylware / nyanmp (public) (License: AGPLv3) (since 2020-02-12) (hash sha1)
intended to become a collection of media players for gnu/linux based on ffmpeg, alsa, vulkan, x11, wayland, etc.
List of commits:
Subject Hash Author Date (UTC)
npv: dynamic audio filter configuration d8a0ff688ddb2abcde22c01a2ae52ea74e9f0f2f Sylvain BERTRAND 2020-09-19 20:54:04
npv:protection against tantrum of media audio 78589150b7c6f1f3cae49b4b4bc8b572c6d8e6b7 Sylvain BERTRAND 2020-09-18 15:26:17
npv/npa:finish to workaround null channel layout 314788563e01d7ffb364a1775ba68619ee3f6c5c Sylvain BERTRAND 2020-09-15 22:50:57
npv: handle empty channel layout 5b5794fc4d5300b671b684a2f41196f66bd1fc4a Sylvain BERTRAND 2020-09-15 22:11:07
npv: tidy mutex locking 1962092d9675f76604414086200e88f6c857346f Sylvain BERTRAND 2020-09-15 00:51:12
npv: less incorrect reprogramming of blits b319e79f4f1b79670f6eef754142cc65c891ad4b Sylvain BERTRAND 2020-09-12 15:14:27
npv:fix osd restoration 8c64f703eca6b8c54b4cb5c95231dd02aa394135 Sylvain BERTRAND 2020-08-29 20:36:12
npv:osd:solo compilation modulo a few warnings 7805bd8f34f913b1535cc81c5be2a3132bd7e0e5 Sylvain BERTRAND 2020-08-29 14:51:35
npv: cleanup and color component fix 44f294e1de96c7974740f1187ebdbe12204884ae Sylvain BERTRAND 2020-08-28 23:48:18
npv:osd:timer, will add more if pertinent 6d34403c2c49bfa6ccf8e7a72e35a69e6f0527c5 Sylvain BERTRAND 2020-08-28 22:47:18
npv/npa: document properly snd_pcm_drain behavior 510ca39ee6a9ac9fcd646484793b7556eaa5972f Sylvain BERTRAND 2020-08-26 17:36:29
npv:remove locale layout dependent key binds f69bbbe529045b4243ece8957c838cb1465352da Sylvain BERTRAND 2020-08-24 21:27:08
npv: global seek based on audio timeline only 3c8fd60fa0a67143fa16ac90565bfcc35a193b6b Sylvain BERTRAND 2020-08-24 18:41:16
npv:_reasonable_ "pedanticage" of the code c5f2644d6eba84bcbcc9b0599c41e1f6733ea95c Sylvain BERTRAND 2020-08-20 16:25:50
npa:some amount of pedanticage 554bd5b07b1a82eabb2622cbf565031bf7af5c6d Sylvain BERTRAND 2020-08-18 19:33:47
hacking again on it after a rather long time cc09df4f340c9f906e0de9520d2c803ea6936769 Sylvain BERTRAND 2020-08-16 18:14:14
npv:fix initial volume not being stored ef66775061157e5af7d6938d06f38e6e7d06a873 Sylvain BERTRAND 2020-08-15 16:59:23
npv:fixing the fix 2043d3ae57ff8b4c26acfd1ee2ff8958cb887ab8 Sylvain BERTRAND 2020-07-17 19:11:14
npv:fixing minor annoyances 2b1895f92933d41a7eb6b7638a94f526e1b5e7cd Sylvain BERTRAND 2020-07-17 19:03:47
npv:spurious namespace tag 65b5c4970e0c0b651ff8d9d61ce2ab0654a039fd Sylvain BERTRAND 2020-06-06 23:22:19
Commit d8a0ff688ddb2abcde22c01a2ae52ea74e9f0f2f - npv: dynamic audio filter configuration
Author: Sylvain BERTRAND
Author date (UTC): 2020-09-19 20:54
Committer name: Sylvain BERTRAND
Committer date (UTC): 2020-09-19 20:54
Parent(s): 78589150b7c6f1f3cae49b4b4bc8b572c6d8e6b7
Signer:
Signing key:
Signing status: N
Tree: 787f9f98914eefa200fc0c3438c13f346db8cee0
File Lines added Lines deleted
npa/TODO 1 0
npv/TODO 1 1
npv/audio/filt/local/code.frag.c 23 19
npv/audio/filt/local/state.frag.c 19 10
npv/audio/filt/namespace/main.c 13 2
npv/audio/filt/namespace/public.h 4 4
npv/audio/filt/public.h 7 6
npv/audio/filt/public/code.frag.c 46 30
npv/audio/local/code.frag.c 187 203
npv/audio/namespace/main.c 17 10
npv/audio/namespace/public.h 32 28
npv/audio/public.h 9 5
npv/audio/public/code.frag.c 166 50
npv/local/code.frag.c 10 71
File npa/TODO changed (mode: 100644) (index 5e78ecd..35ff3e5)
1 1 not ordered: not ordered:
2 - port npv dynamic audio reconfiguration
2 3 - port npv initial ffmpeg audio parameter override code - port npv initial ffmpeg audio parameter override code
3 4 - we were lied to: presentation/decoding timestamps from a demuxer can be - we were lied to: presentation/decoding timestamps from a demuxer can be
4 5 discontinuous without any warning. discontinuous without any warning.
File npv/TODO changed (mode: 100644) (index e96b931..8d590d7)
1 1 not ordered: not ordered:
2 2 - we were lied to: presentation/decoding timestamps from a demuxer can be - we were lied to: presentation/decoding timestamps from a demuxer can be
3 3 discontinuous without any warning. discontinuous without any warning.
4 - "buffering" indicator, subtitles and osd (On Screen Display)
4 - "buffering" indicatorr? subtitles?
5 5 - forced monotonic video frame selection? may be, probably, more robust in - forced monotonic video frame selection? may be, probably, more robust in
6 6 regard to latency spikes. regard to latency spikes.
7 7 - use vulkan shaders (no glsl or hlsl), compute or not, in order to perform - use vulkan shaders (no glsl or hlsl), compute or not, in order to perform
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/local/state.frag.c changed (mode: 100644) (index 8f462fb..a2b7830)
1 avfilter_filt_graph_t *graph_l;
2 avfilter_filt_ctx_t *abufsrc_ctx_l;
3 const avfilter_filt_t *abufsrc_l;
4 avfilter_filt_ctx_t *vol_ctx_l;
5 const avfilter_filt_t *vol_l;
6 u8 double_zero_l10n_str_l[sizeof("xxx.xx")];
7 avfilter_filt_ctx_t *afmt_ctx_l;
8 const avfilter_filt_t *afmt_l;
9 avfilter_filt_ctx_t *abufsink_ctx_l;
10 const avfilter_filt_t *abufsink_l;
1 STATIC avfilter_filt_graph_t *graph_l;
2 STATIC struct {
3 const avfilter_filt_t *this;
4 avfilter_filt_ctx_t *ctx;
5 /* key to detect required recfg */
6 struct {
7 int rate;
8 int chans_n;
9 uint64_t chans_layout;
10 enum avutil_audio_fr_fmt_t fmt;
11 } key;
12 } abufsrc_l;
13 STATIC avfilter_filt_ctx_t *vol_ctx_l;
14 STATIC const avfilter_filt_t *vol_l;
15 STATIC u8 double_zero_l10n_str_l[sizeof("xxx.xx")];
16 STATIC avfilter_filt_ctx_t *afmt_ctx_l;
17 STATIC const avfilter_filt_t *afmt_l;
18 STATIC avfilter_filt_ctx_t *abufsink_ctx_l;
19 STATIC const avfilter_filt_t *abufsink_l;
File npv/audio/filt/namespace/main.c changed (mode: 100644) (index 6b543d4..83e3c2d)
3 3 #define abufsink_ctx_l npv_audio_filt_abufsink_ctx_l #define abufsink_ctx_l npv_audio_filt_abufsink_ctx_l
4 4 #define abufsink_l npv_audio_filt_abufsink_l #define abufsink_l npv_audio_filt_abufsink_l
5 5 #define abufsrc_cfg npv_audio_filt_abufsrc_cfg #define abufsrc_cfg npv_audio_filt_abufsrc_cfg
6 #define abufsrc_ctx_l npv_audio_filt_abufsrc_ctx_l
7 6 #define abufsrc_l npv_audio_filt_abufsrc_l #define abufsrc_l npv_audio_filt_abufsrc_l
8 7 #define afmt_cfg npv_audio_filt_afm_cfg #define afmt_cfg npv_audio_filt_afm_cfg
9 8 #define afmt_ctx_l npv_audio_filt_afmt_ctx_l #define afmt_ctx_l npv_audio_filt_afmt_ctx_l
 
13 12 #define graph_l npv_audio_filt_graph_l #define graph_l npv_audio_filt_graph_l
14 13 #define init_once_local npv_audio_filt_init_once_local #define init_once_local npv_audio_filt_init_once_local
15 14 #define init_once_public npv_audio_filt_init_once_public #define init_once_public npv_audio_filt_init_once_public
15 #define is_recfg_required npv_audio_filt_is_recfg_required
16 16 #define pout npv_audio_filt_pout #define pout npv_audio_filt_pout
17 17 #define vol_cfg npv_audio_filt_vol_cfg #define vol_cfg npv_audio_filt_vol_cfg
18 18 #define vol_ctx_l npv_audio_filt_vol_ctx_l #define vol_ctx_l npv_audio_filt_vol_ctx_l
19 19 #define vol_l npv_audio_filt_vol_l #define vol_l npv_audio_filt_vol_l
20 20 #define warning npv_audio_filt_warning #define warning npv_audio_filt_warning
21 /*----------------------------------------------------------------------------*/
22 /* some member names */
23 #define chans_layout channel_layout
24 #define chans_n channels
25 #define fmt format
26 #define rate sample_rate
21 27 /*============================================================================*/ /*============================================================================*/
22 28 #else #else
23 29 #undef abufsink_cfg #undef abufsink_cfg
24 30 #undef abufsink_ctx_l #undef abufsink_ctx_l
25 31 #undef abufsink_l #undef abufsink_l
26 32 #undef abufsrc_cfg #undef abufsrc_cfg
27 #undef abufsrc_ctx_l
28 33 #undef abufsrc_l #undef abufsrc_l
29 34 #undef afmt_cfg #undef afmt_cfg
30 35 #undef afmt_ctx_l #undef afmt_ctx_l
 
34 39 #undef graph_l #undef graph_l
35 40 #undef init_once_local #undef init_once_local
36 41 #undef init_once_public #undef init_once_public
42 #undef is_recfg_required
37 43 #undef pout #undef pout
38 44 #undef vol_cfg #undef vol_cfg
39 45 #undef vol_ctx_l #undef vol_ctx_l
40 46 #undef vol_l #undef vol_l
41 47 #undef warning #undef warning
48 /*----------------------------------------------------------------------------*/
49 #undef chans_layout
50 #undef chans_n
51 #undef rate
52 #undef fmt
42 53 #endif #endif
File npv/audio/filt/namespace/public.h changed (mode: 100644) (index 7387274..73a69a9)
2 2 #define cfg npv_audio_filt_cfg #define cfg npv_audio_filt_cfg
3 3 #define filt_flush npv_audio_filt_flush #define filt_flush npv_audio_filt_flush
4 4 #define filt_p npv_audio_filt_p #define filt_p npv_audio_filt_p
5 #define filt_push_dec_sets npv_audio_filt_push_dec_sets
6 #define filt_set_try_get npv_audio_filt_set_try_get
5 #define filt_push_dec_set npv_audio_filt_push_dec_set
6 #define filt_set_get npv_audio_filt_set_get
7 7 #define init_once npv_audio_filt_init_once #define init_once npv_audio_filt_init_once
8 8 /*============================================================================*/ /*============================================================================*/
9 9 #else #else
10 10 #undef cfg #undef cfg
11 11 #undef filt_flush #undef filt_flush
12 12 #undef filt_p #undef filt_p
13 #undef filt_push_dec_sets
14 #undef filt_set_try_get
13 #undef filt_push_dec_set
14 #undef filt_set_get
15 15 #undef init_once #undef init_once
16 16 #endif #endif
File npv/audio/filt/public.h changed (mode: 100644) (index 9416e08..9ff44ce)
19 19 #include "npv/audio/filt/public/state.frag.h" #include "npv/audio/filt/public/state.frag.h"
20 20 /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
21 21 STATIC void init_once(double initial_vol); STATIC void init_once(double initial_vol);
22 STATIC void cfg(enum avutil_audio_fr_fmt_t src_fmt, int src_rate,
23 int src_chans_n, uint64_t src_chans_layout,
22 STATIC void cfg(int src_chans_n, uint64_t src_chans_layout, int src_rate,
23 enum avutil_audio_fr_fmt_t src_fmt,
24 24 bool muted, double vol, bool muted, double vol,
25 enum avutil_audio_fr_fmt_t dst_fmt, int dst_rate,
26 int dst_chans_n, uint64_t dst_chans_layout,
25 int dst_chans_n, uint64_t dst_chans_layout, int dst_rate,
26 enum avutil_audio_fr_fmt_t dst_fmt,
27 27 bool print_info); bool print_info);
28 STATIC u8 filt_push_dec_sets(void);
29 STATIC u8 filt_set_try_get(void);
28 STATIC u8 filt_push_dec_set(int *new_chans_n, uint64_t *new_chans_layout,
29 int *new_rate, enum avutil_audio_fr_fmt_t *new_fmt);
30 STATIC u8 filt_set_get(void);
30 31 STATIC void filt_flush(void); STATIC void filt_flush(void);
31 32 /* out of audio filt namespace to avoid collision with npv_cmd_* prefix */ /* out of audio filt namespace to avoid collision with npv_cmd_* prefix */
32 33 STATIC void npv_audio_filt_cmd_mute(void); STATIC void npv_audio_filt_cmd_mute(void);
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/namespace/public.h changed (mode: 100644) (index 180ba4d..4ee24f8)
1 1 #ifndef CLEANUP #ifndef CLEANUP
2 #define dec_ctx_cfg npv_audio_dec_ctx_cfg
3 #define dec_ctx_lock npv_audio_dec_ctx_lock
4 #define dec_ctx_p npv_audio_dec_ctx_p
5 #define dec_ctx_unlock npv_audio_dec_ctx_unlock
6 #define dec_flush npv_audio_dec_flush
7 #define dec_sets_lock npv_audio_dec_sets_lock
8 #define dec_sets_p npv_audio_dec_sets_p
9 #define dec_sets_unlock npv_audio_dec_sets_unlock
10 #define dec_sets_receive_avail npv_audio_dec_sets_receive_avail
11 #define dec_set_try_receive npv_audio_dec_set_try_receive
12 #define draining_p npv_audio_draining_p
13 #define draining_state_evt npv_audio_draining_state_evt
14 #define draining_timer_fd_p npv_audio_draining_timer_fd_p
15 #define evt_pcm_write npv_audio_evt_pcm_write
16 #define init_once npv_audio_init_once
17 #define pcm2ff npv_audio_pcm2ff
18 #define pcm_cfg npv_audio_pcm_cfg
19 #define pcm_p npv_audio_pcm_p
20 #define pcm_pollfds_p npv_audio_pcm_pollfds_p
21 #define pcm_pollfds_n_p npv_audio_pcm_pollfds_n_p
22 #define pcm_pollfds_n_max npv_audio_pcm_pollfds_n_max
23 #define pcm_silence_bufs_cfg npv_audio_pcm_silence_bufs_cfg
24 #define pkt_q_p npv_audio_pkt_q_p
25 #define pkts_send npv_audio_pkts_send
26 #define selected_ts_type_p npv_audio_selected_ts_type_p
27 #define st_p npv_audio_st_p
2 #define dec_ctx_cfg npv_audio_dec_ctx_cfg
3 #define dec_ctx_lock npv_audio_dec_ctx_lock
4 #define dec_ctx_p npv_audio_dec_ctx_p
5 #define dec_ctx_unlock npv_audio_dec_ctx_unlock
6 #define dec_flush npv_audio_dec_flush
7 #define dec_sets_lock npv_audio_dec_sets_lock
8 #define dec_sets_p npv_audio_dec_sets_p
9 #define dec_sets_unlock npv_audio_dec_sets_unlock
10 #define dec_sets_receive_avail npv_audio_dec_sets_receive_avail
11 #define dec_set_try_receive npv_audio_dec_set_try_receive
12 #define draining_p npv_audio_draining_p
13 #define draining_state_evt npv_audio_draining_state_evt
14 #define draining_timer_fd_p npv_audio_draining_timer_fd_p
15 #define evt_pcm_write npv_audio_evt_pcm_write
16 #define init_once npv_audio_init_once
17 #define pcm_cfg_hw_best_effort npv_audio_pcm_cfg_hw_best_effort
18 #define pcm_cfg_sw npv_audio_pcm_cfg_sw
19 #define pcm_p npv_audio_pcm_p
20 #define pcm_pollfds_p npv_audio_pcm_pollfds_p
21 #define pcm_pollfds_n_p npv_audio_pcm_pollfds_n_p
22 #define pcm_pollfds_n_max npv_audio_pcm_pollfds_n_max
23 #define pcm_silence_bufs_cfg npv_audio_pcm_silence_bufs_cfg
24 #define pcm2ff_strict npv_audio_pcm2ff_strict
25 #define pkt_q_p npv_audio_pkt_q_p
26 #define pkts_send npv_audio_pkts_send
27 #define prepare npv_audio_prepare
28 #define selected_ts_type_p npv_audio_selected_ts_type_p
29 #define st_p npv_audio_st_p
28 30 /*============================================================================*/ /*============================================================================*/
29 31 #else #else
30 32 #undef dec_ctx_cfg #undef dec_ctx_cfg
 
42 44 #undef draining_timer_fd_p #undef draining_timer_fd_p
43 45 #undef evt_pcm_write #undef evt_pcm_write
44 46 #undef init_once #undef init_once
45 #undef pcm2ff
46 #undef pcm_cfg
47 #undef pcm_cfg_hw_best_effort
48 #undef pcm_cfg_sw
47 49 #undef pcm_p #undef pcm_p
48 50 #undef pcm_pollfds_p #undef pcm_pollfds_p
49 51 #undef pcm_pollfds_n_p #undef pcm_pollfds_n_p
50 52 #undef pcm_pollfds_n_max #undef pcm_pollfds_n_max
51 53 #undef pcm_silence_bufs_cfg #undef pcm_silence_bufs_cfg
54 #undef pcm2ff_strict
52 55 #undef pkt_q_p #undef pkt_q_p
53 56 #undef pkts_send #undef pkts_send
57 #undef prepare
54 58 #undef selected_ts_type #undef selected_ts_type
55 59 #undef st_p #undef st_p
56 60 #endif #endif
File npv/audio/public.h changed (mode: 100644) (index cdeed9c..651616e)
... ... STATIC u8 dec_set_try_receive(void);
32 32 STATIC void dec_sets_receive_avail(void); STATIC void dec_sets_receive_avail(void);
33 33 STATIC void draining_state_evt(void); STATIC void draining_state_evt(void);
34 34 STATIC void evt_pcm_write(void); STATIC void evt_pcm_write(void);
35 STATIC void pcm_cfg_hw_best_effort(snd_pcm_t *pcm, int chans_n,
36 uint64_t ff_chans_layout, int rate, enum avutil_audio_fr_fmt_t ff_fmt);
35 37 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);
38 STATIC void pcm_cfg_sw(snd_pcm_t *pcm);
36 39 STATIC void init_once(u8 *pcm_str); STATIC void init_once(u8 *pcm_str);
37 STATIC void pcm_cfg(snd_pcm_t *pcm, unsigned int chans_n, unsigned int rate,
38 enum avutil_audio_fr_fmt_t ff_fmt);
39 STATIC void pcm2ff(snd_pcm_t *pcm, enum avutil_audio_fr_fmt_t *ff_fmt,
40 int *ff_rate, int *ff_chans_n, uint64_t *ff_chans_layout,
41 bool print_info);
42 40 STATIC void pkts_send(void); STATIC void pkts_send(void);
41 STATIC void prepare(int override_initial_ff_chans_n,
42 int override_initial_ff_rate,
43 enum avutil_audio_fr_fmt_t override_initial_ff_fmt);
44 STATIC void pcm2ff_strict(snd_pcm_t *pcm, int *ff_chans_n,
45 uint64_t *ff_chans_layout, int *ff_rate,
46 enum avutil_audio_fr_fmt_t *ff_fmt, bool print_info);
43 47 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
44 48 #define CLEANUP #define CLEANUP
45 49 #include "npv/namespace/ffmpeg.h" #include "npv/namespace/ffmpeg.h"
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;
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/nyanmp

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/nyanmp

Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/nyanmp

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main