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: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
npv:namespace cleanup, don't need that many short identifiers 86d95bbd53a6c9264a44ae98038db9bf4d195e29 Sylvain BERTRAND 2020-06-06 22:44:11
Commit 78589150b7c6f1f3cae49b4b4bc8b572c6d8e6b7 - npv:protection against tantrum of media audio
Author: Sylvain BERTRAND
Author date (UTC): 2020-09-18 15:26
Committer name: Sylvain BERTRAND
Committer date (UTC): 2020-09-18 15:26
Parent(s): 314788563e01d7ffb364a1775ba68619ee3f6c5c
Signer:
Signing key:
Signing status: N
Tree: 3f3d832e7db292635e83dd9c3a94c28828559336
File Lines added Lines deleted
npa/TODO 4 0
npv/TODO 2 0
npv/audio/local/code.frag.c 17 16
npv/audio/namespace/ffmpeg.h 0 22
npv/audio_device_sharing 31 0
npv/local/code.frag.c 201 31
npv/main.c 2 0
npv/namespace/alsa.h 2 0
npv/namespace/ffmpeg.h 26 0
File npa/TODO changed (mode: 100644) (index ff2db79..5e78ecd)
1 not ordered:
2 - port npv initial ffmpeg audio parameter override code
3 - we were lied to: presentation/decoding timestamps from a demuxer can be
4 discontinuous without any warning.
1 5 - support dynamic re-configuration based on decoder output? - support dynamic re-configuration based on decoder output?
2 6 (the plumbing should be roughly in place for that) (the plumbing should be roughly in place for that)
File npv/TODO changed (mode: 100644) (index 516eb95..e96b931)
1 1 not ordered: not ordered:
2 - we were lied to: presentation/decoding timestamps from a demuxer can be
3 discontinuous without any warning.
2 4 - "buffering" indicator, subtitles and osd (On Screen Display) - "buffering" indicator, subtitles and osd (On Screen Display)
3 5 - forced monotonic video frame selection? may be, probably, more robust in - forced monotonic video frame selection? may be, probably, more robust in
4 6 regard to latency spikes. regard to latency spikes.
File npv/audio/local/code.frag.c changed (mode: 100644) (index f54949d..20611b9)
... ... STATIC bool pcm_hw_fmt_decide_x(snd_pcm_t *pcm,
187 187 r = snd_pcm_hw_params_set_fmt(pcm, pcm_hw_params, fmt); r = snd_pcm_hw_params_set_fmt(pcm, pcm_hw_params, fmt);
188 188 if (r != 0) if (r != 0)
189 189 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_fmt_desc(fmt)); fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_fmt_desc(fmt));
190 pout("alsa:using \"%s\" format\n", snd_pcm_fmt_desc(fmt));
190 pout("alsa:using last resort \"%s\" format\n", snd_pcm_fmt_desc(fmt));
191 191 return true; return true;
192 192 } }
193 193 #define PCM_HW_FMT_DECIDE_X(fmt) pcm_hw_fmt_decide_x(pcm, pcm_hw_params, fmt) #define PCM_HW_FMT_DECIDE_X(fmt) pcm_hw_fmt_decide_x(pcm, pcm_hw_params, fmt)
194 194 STATIC void pcm_hw_fmt_decide(snd_pcm_t *pcm, STATIC void pcm_hw_fmt_decide(snd_pcm_t *pcm,
195 snd_pcm_hw_params_t *pcm_hw_params, bool force,
196 snd_pcm_fmt_t forced_fmt)
195 snd_pcm_hw_params_t *pcm_hw_params, bool best_effort,
196 snd_pcm_fmt_t best_effort_fmt)
197 197 { {
198 198 int r; int r;
199 199 snd_pcm_fmt_t *fmt; snd_pcm_fmt_t *fmt;
200 200
201 if (force) {
202 r = snd_pcm_hw_params_test_fmt(pcm, pcm_hw_params, forced_fmt);
201 if (best_effort) {
202 r = snd_pcm_hw_params_test_fmt(pcm, pcm_hw_params,
203 best_effort_fmt);
203 204 if (r == 0) { if (r == 0) {
204 205 r = snd_pcm_hw_params_set_fmt(pcm, pcm_hw_params, r = snd_pcm_hw_params_set_fmt(pcm, pcm_hw_params,
205 forced_fmt);
206 best_effort_fmt);
206 207 if (r != 0) if (r != 0)
207 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_fmt_desc(forced_fmt));
208 pout("alsa:using forced \"%s\" format\n", snd_pcm_fmt_desc(forced_fmt));
208 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_fmt_desc(best_effort_fmt));
209 pout("alsa:using best effort \"%s\" format\n", snd_pcm_fmt_desc(best_effort_fmt));
209 210 return; return;
210 211 } }
211 212 } }
 
... ... STATIC bool pcm_hw_access_decide_x(snd_pcm_t *pcm,
247 248 r = snd_pcm_hw_params_set_access(pcm, pcm_hw_params, access); r = snd_pcm_hw_params_set_access(pcm, pcm_hw_params, access);
248 249 if (r != 0) if (r != 0)
249 250 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_access_name(access)); fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_access_name(access));
250 pout("alsa:using \"%s\" access\n", snd_pcm_access_name(access));
251 pout("alsa:using last resort \"%s\" access\n", snd_pcm_access_name(access));
251 252 return true; return true;
252 253 } }
253 254 #define PCM_HW_ACCESS_DECIDE_X(access) \ #define PCM_HW_ACCESS_DECIDE_X(access) \
254 255 pcm_hw_access_decide_x(pcm, pcm_hw_params, access) pcm_hw_access_decide_x(pcm, pcm_hw_params, access)
255 256 /* XXX: only classic non-mmap ones */ /* XXX: only classic non-mmap ones */
256 257 STATIC void pcm_hw_access_decide(snd_pcm_t *pcm, STATIC void pcm_hw_access_decide(snd_pcm_t *pcm,
257 snd_pcm_hw_params_t *pcm_hw_params, bool force,
258 snd_pcm_access_t forced_access)
258 snd_pcm_hw_params_t *pcm_hw_params, bool best_effort,
259 snd_pcm_access_t best_effort_access)
259 260 { {
260 261 int r; int r;
261 262 snd_pcm_access_t access; snd_pcm_access_t access;
262 263
263 if (force) {
264 if (best_effort) {
264 265 r = snd_pcm_hw_params_test_access(pcm, pcm_hw_params, r = snd_pcm_hw_params_test_access(pcm, pcm_hw_params,
265 forced_access);
266 best_effort_access);
266 267 if (r == 0) { if (r == 0) {
267 268 r = snd_pcm_hw_params_set_access(pcm, pcm_hw_params, r = snd_pcm_hw_params_set_access(pcm, pcm_hw_params,
268 forced_access);
269 best_effort_access);
269 270 if (r != 0) if (r != 0)
270 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_access_name(forced_access));
271 pout("alsa:using forced \"%s\" access\n", snd_pcm_access_name(forced_access));
271 fatal("alsa:unable to restrict pcm device to \"%s\", which was successfully tested\n", snd_pcm_access_name(best_effort_access));
272 pout("alsa:using best effort \"%s\" access\n", snd_pcm_access_name(best_effort_access));
272 273 return; return;
273 274 } }
274 275 } }
File npv/audio/namespace/ffmpeg.h changed (mode: 100644) (index 393c8a6..13c90dc)
1 1 #ifndef CLEANUP #ifndef CLEANUP
2 #define AVUTIL_AUDIO_FR_FMT_U8 AV_SAMPLE_FMT_U8
3 #define AVUTIL_AUDIO_FR_FMT_S16 AV_SAMPLE_FMT_S16
4 #define AVUTIL_AUDIO_FR_FMT_S32 AV_SAMPLE_FMT_S32
5 #define AVUTIL_AUDIO_FR_FMT_FLT AV_SAMPLE_FMT_FLT
6 #define AVUTIL_AUDIO_FR_FMT_U8P AV_SAMPLE_FMT_U8P
7 #define AVUTIL_AUDIO_FR_FMT_S16P AV_SAMPLE_FMT_S16P
8 #define AVUTIL_AUDIO_FR_FMT_S32P AV_SAMPLE_FMT_S32P
9 #define AVUTIL_AUDIO_FR_FMT_FLTP AV_SAMPLE_FMT_FLTP
10 #define AVUTIL_OPT_SEARCH_CHILDREN AV_OPT_SEARCH_CHILDREN
11 /*----------------------------------------------------------------------------*/
12 2 #define avcodec_receive_audio_set avcodec_receive_frame #define avcodec_receive_audio_set avcodec_receive_frame
13 3 #define avfilter_bufsink_get_audio_set av_buffersink_get_frame #define avfilter_bufsink_get_audio_set av_buffersink_get_frame
14 4 #define avfilter_bufsink_get_audio_fmt av_buffersink_get_format #define avfilter_bufsink_get_audio_fmt av_buffersink_get_format
 
19 9 #define avutil_audio_fr_fmt_t AVSampleFormat #define avutil_audio_fr_fmt_t AVSampleFormat
20 10 #define avutil_audio_set_ref_t AVFrame #define avutil_audio_set_ref_t AVFrame
21 11 #define avutil_audio_set_unref av_frame_unref #define avutil_audio_set_unref av_frame_unref
22 #define avutil_get_audio_fr_fmt_name av_get_sample_fmt_name
23 12 #define avutil_get_audio_fr_fmt_str av_get_sample_fmt_string #define avutil_get_audio_fr_fmt_str av_get_sample_fmt_string
24 13 #define avutil_get_bytes_per_sample av_get_bytes_per_sample #define avutil_get_bytes_per_sample av_get_bytes_per_sample
25 14 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
 
31 20 #define chans_layout channel_layout #define chans_layout channel_layout
32 21 /*============================================================================*/ /*============================================================================*/
33 22 #else #else
34 #undef AVUTIL_AUDIO_FR_FMT_U8
35 #undef AVUTIL_AUDIO_FR_FMT_S16
36 #undef AVUTIL_AUDIO_FR_FMT_S32
37 #undef AVUTIL_AUDIO_FR_FMT_FLT
38 #undef AVUTIL_AUDIO_FR_FMT_U8P
39 #undef AVUTIL_AUDIO_FR_FMT_S16P
40 #undef AVUTIL_AUDIO_FR_FMT_S32P
41 #undef AVUTIL_AUDIO_FR_FMT_FLTP
42 #undef AVUTIL_OPT_SEARCH_CHILDREN
43 /*----------------------------------------------------------------------------*/
44 23 #undef avcodec_receive_audio_set #undef avcodec_receive_audio_set
45 24 #undef avfilter_bufsink_get_audio_set #undef avfilter_bufsink_get_audio_set
46 25 #undef avfilter_bufsink_get_audio_fmt #undef avfilter_bufsink_get_audio_fmt
 
51 30 #undef avutil_audio_fr_fmt_t #undef avutil_audio_fr_fmt_t
52 31 #undef avutil_audio_set_ref_t #undef avutil_audio_set_ref_t
53 32 #undef avutil_audio_set_unref #undef avutil_audio_set_unref
54 #undef avutil_get_audio_fr_fmt_name
55 33 #undef avutil_get_audio_fr_fmt_str #undef avutil_get_audio_fr_fmt_str
56 34 #undef avutil_get_bytes_per_sample #undef avutil_get_bytes_per_sample
57 35 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
File npv/audio_device_sharing added (mode: 100644) (index 0000000..ac9c444)
1 Sharing an audio device is not like sharing a display/gpu device. It is easy
2 to resize a window if the user does not like it, but for audio, there is sort of
3 no way to change the "configuration" easily like for a window.
4 --------
5 The main level of audio device sharing is the process level: on gnu/linux, this
6 task is handled with the alsa library with some IPCs. There are some
7 alternatives, but with a very high/unreasonable software cost: c++, massive
8 runtime/sdk dependencies, etc. There is some trade-off due to sharing: a choice
9 must be made for the audio device hardware configuration.
10 Because if the first process using the audio device is configuring it with very
11 low quality settings, the sub-sequent processes which will want to use the
12 audio device at the same time will be stuck with this low quality settings!
13 THEN, TO AVOID A PROCESS THROWING SOME TANTRUM OVER AN AUDIO DEVICE
14 CONFIGURATION, THE ALSA LIBRARY DEFAULT CHOICE IS "48000Hz STEREO" (you can
15 override it very easily at the global or user level with a configuration text
16 file).
17 That said, the alsa library has tons of conversion/re-sampling plugins which
18 will make the audio configuration space way broader that the shared hardware
19 default. Then from the process perspective, audio device configuration remains
20 quite flexible.
21 --------
22 The second level in the case of npv is that a media content can change on the
23 fly some of its audio properties. Due to buffering, once the change was
24 detected, the already submitted audio data to the alsa pcm would have to be
25 drained (aka wait until all the samples are played) before being reconfigured,
26 and that must be instant to avoid "clicking". To put that in perspective, at
27 48000Hz, to get a perfect audio transition, the time window is 20µs.
28 We should be better off configuring once the alsa pcm, based on the properties
29 of the first audio samples or some reasonable and configurable defaults, like
30 alsa dmix, and re-sample the output of the audio decoder to fit this very alsa
31 pcm configuration.
File npv/local/code.frag.c changed (mode: 100644) (index db42bae..e6de726)
... ... STATIC void ff_log_stdout(void *a, int b, const char *fmt, va_list ap)
348 348 { {
349 349 vprintf(fmt, ap); vprintf(fmt, ap);
350 350 } }
351 /*NPSC*/
352 struct ff_supported_audio_fr_fmt_t {
353 u8 *str;
354 enum avutil_audio_fr_fmt_t audio_fr_fmt;
355 };
356 /* this is the intersection of ff audio fr fmt and alsa pcm fmt */
357 /*NPSC*/
358 STATIC struct ff_supported_audio_fr_fmt_t ff_supported_audio_fr_fmts[] = {
359 {"u8", AVUTIL_AUDIO_FR_FMT_U8},
360 {"u8planar", AVUTIL_AUDIO_FR_FMT_U8P},
361 {"s16", AVUTIL_AUDIO_FR_FMT_S16},
362 {"s16planar", AVUTIL_AUDIO_FR_FMT_S16P},
363 {"s32", AVUTIL_AUDIO_FR_FMT_S32},
364 {"s32planar", AVUTIL_AUDIO_FR_FMT_S32P},
365 {"float32", AVUTIL_AUDIO_FR_FMT_FLT},
366 {"float32planar", AVUTIL_AUDIO_FR_FMT_FLTP},
367 {"float64", AVUTIL_AUDIO_FR_FMT_DBL},
368 {"float64planar", AVUTIL_AUDIO_FR_FMT_DBLP},
369 {0,0}
370 };
351 371 STATIC void usage(void) STATIC void usage(void)
352 372 { {
373 struct ff_supported_audio_fr_fmt_t *fmt;
374
353 375 pout("\ pout("\
354 npv [-f send a fullscreen message to the window manager at start] [-p alsa pcm]\n\
355 [-v volume(0..100)] [-h window height in pixels] [-w window width in pixels]\n\
356 [-b packet buffer prefill wait(0..100)] [-help] url\n");
376 npv [-f send a fullscreen message to the window manager at start]\n\
377 [-p alsa pcm]\n\
378 [-fc override initial ffmpeg count of channels used to approximate the alsa\n\
379 pcm configuration]\n\
380 [-fr override initial ffmpeg rate(hz) used to approximate the alsa pcm\n\
381 configuration]\n\
382 [-ff override initial ffmpeg audio frame format used to approximate the alsa\n\
383 pcm configuration, see below for a list]\n\
384 [-v volume(0..100)]\n\
385 [-h window height in pixels]\n\
386 [-w window width in pixels]\n\
387 [-b packet buffer prefill wait(0..100)]\n\
388 [-help]\n\
389 url\n\
390 \n\
391 the ffmpeg audio frame formats which intersect alsa pcm audio formats are:\n"
392 );
393 fmt = ff_supported_audio_fr_fmts;
394 loop {
395 if (fmt->str == 0)
396 break;
397 pout("\t%s\n", fmt->str);
398 ++fmt;
399 }
357 400 } }
358 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,
359 u16 *w, u16 *h, u8 **pcm_str, double *vol, u8 *pkts_prefill_percent)
402 u16 *w, u16 *h, u8 **pcm_str,
403 unsigned int *override_initial_ff_chans_n,
404 unsigned int *override_initial_ff_rate,
405 enum avutil_audio_fr_fmt_t *override_initial_ff_audio_fr_fmt,
406 double *vol, u8 *pkts_prefill_percent)
360 407 { {
361 408 int i; int i;
362 409 int url_idx; int url_idx;
 
... ... STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen,
369 416 if (strcmp("-f", args[i]) == 0) { if (strcmp("-f", args[i]) == 0) {
370 417 *start_fullscreen = true; *start_fullscreen = true;
371 418 ++i; ++i;
372 } else if (strcmp("-p", args[i]) == 0) {
373 *pcm_str = args[i + 1];
374 pout("-p:alsa pcm \"%s\"\n", *pcm_str);
375 i += 2;
376 419 } else if (strcmp("-v", args[i]) == 0) { } else if (strcmp("-v", args[i]) == 0) {
377 420 unsigned long vol_ul; unsigned long vol_ul;
378 421
379 if ((i + 1) == argc)
380 fatal("-v:initial volume is missing\n");
422 if ((i + 1) == argc) {
423 perr("-v:initial volume is missing\n");
424 usage();
425 exit(1);
426 }
381 427 vol_ul = strtoul(args[i + 1], 0, 10); vol_ul = strtoul(args[i + 1], 0, 10);
382 428 if (vol_ul < 0 || 100 < vol_ul) if (vol_ul < 0 || 100 < vol_ul)
383 429 fatal("-v:invalid volume value %lu (0..100)\n", vol_ul); fatal("-v:invalid volume value %lu (0..100)\n", vol_ul);
 
... ... STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen,
387 433 } else if (strcmp("-h", args[i]) == 0) { } else if (strcmp("-h", args[i]) == 0) {
388 434 unsigned long h_ul; unsigned long h_ul;
389 435
390 if ((i + 1) == argc)
391 fatal("-h:initial window pixel height is missing\n");
436 if ((i + 1) == argc) {
437 perr("-h:initial window pixel height is missing\n");
438 usage();
439 exit(1);
440 }
392 441 h_ul = strtoul(args[i + 1], 0, 10); h_ul = strtoul(args[i + 1], 0, 10);
393 442 if (h_ul == 0 || h_ul > U16_MAX) if (h_ul == 0 || h_ul > U16_MAX)
394 443 fatal("-h:invalid window pixel height %lu (1..%lu)\n", h_ul, U16_MAX); fatal("-h:invalid window pixel height %lu (1..%lu)\n", h_ul, U16_MAX);
 
... ... STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen,
398 447 } else if (strcmp("-w", args[i]) == 0) { } else if (strcmp("-w", args[i]) == 0) {
399 448 unsigned long w_ul; unsigned long w_ul;
400 449
401 if ((i + 1) == argc)
402 fatal("-h:initial window pixel width is missing\n");
450 if ((i + 1) == argc) {
451 perr("-h:initial window pixel width is missing\n");
452 usage();
453 exit(1);
454 }
403 455 w_ul = strtoul(args[i + 1], 0, 10); w_ul = strtoul(args[i + 1], 0, 10);
404 456 if (w_ul == 0 || w_ul > U16_MAX) if (w_ul == 0 || w_ul > U16_MAX)
405 457 fatal("-w:invalid window pixel width %lu (1..%lu)\n", w_ul, U16_MAX); fatal("-w:invalid window pixel width %lu (1..%lu)\n", w_ul, U16_MAX);
 
... ... STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen,
407 459 pout("-w:using initial window width %lu pixels\n", w_ul); pout("-w:using initial window width %lu pixels\n", w_ul);
408 460 i += 2; i += 2;
409 461 } else if (strcmp("-b", args[i]) == 0) { } else if (strcmp("-b", args[i]) == 0) {
410 if ((i + 1) == argc)
411 fatal("-b:percent value for prefill of buffer of packet queues is missing\n");
462 if ((i + 1) == argc) {
463 perr("-b:percent value for prefill of buffer of packet queues is missing\n");
464 usage();
465 exit(1);
466 }
412 467 *pkts_prefill_percent = (u8)strtoul(args[i + 1], 0, 10); *pkts_prefill_percent = (u8)strtoul(args[i + 1], 0, 10);
413 468 pout("-v:using a %u prefilled buffer of packet queues\n", *pkts_prefill_percent); pout("-v:using a %u prefilled buffer of packet queues\n", *pkts_prefill_percent);
414 469 i += 2; i += 2;
470 } else if (strcmp("-p", args[i]) == 0) {
471 *pcm_str = args[i + 1];
472 pout("-p:alsa pcm \"%s\"\n", *pcm_str);
473 i += 2;
474 /*------------------------------------------------------------*/
475 /* ff initial override for alsa pcm cfg -- start */
476 } else if (strcmp("-fr", args[i]) == 0) {
477 if ((i + 1) == argc) {
478 perr("-fr:override initial ffmpeg rate(hz) is missing\n");
479 usage();
480 exit(1);
481 }
482 *override_initial_ff_rate = (unsigned int)strtoul(
483 args[i + 1], 0, 10);
484 pout("-fr:override initial ffmpeg audio rate to %uHz used for alsa pcm configuration\n", *override_initial_ff_rate);
485 i += 2;
486 } else if (strcmp("-fc", args[i]) == 0) {
487 if ((i + 1) == argc) {
488 perr("-fc:override initial ffmpeg channel count is missing\n");
489 usage();
490 exit(1);
491 }
492 *override_initial_ff_chans_n = (unsigned int)strtoul(
493 args[i + 1], 0, 10);
494 pout("-fc:override initial ffmpeg count of channels to %u used for alsa pcm configuration\n", *override_initial_ff_chans_n);
495 i += 2;
496 } else if (strcmp("-ff", args[i]) == 0) {
497 struct ff_supported_audio_fr_fmt_t *fmt;
498
499 if ((i + 1) == argc) {
500 perr("-fc:override initial ffmpeg audio frame format is missing\n");
501 usage();
502 exit(1);
503 }
504 fmt = ff_supported_audio_fr_fmts;
505 loop {
506 if (fmt->str == 0) {
507 perr("-ff:unknown ffmpeg audio frame format\n");
508 usage();
509 exit(1);
510 }
511 if (strcmp(fmt->str, args[i + 1]) == 0) {
512 *override_initial_ff_audio_fr_fmt =
513 fmt->audio_fr_fmt;
514 break;
515 }
516 ++fmt;
517 }
518 pout("-ff:override initial ffmpeg audio frame format is %s\n", avutil_get_audio_fr_fmt_name(fmt->audio_fr_fmt));
519 i += 2;
520 /* ff initial override for alsa pcm cfg -- end */
521 /*------------------------------------------------------------*/
415 522 } else if (strcmp("-help", args[i]) == 0) { } else if (strcmp("-help", args[i]) == 0) {
416 523 usage(); usage();
417 524 exit(0); exit(0);
 
... ... STATIC void opts_parse(int argc, u8 **args, u8 **url, bool* start_fullscreen,
420 527 ++i; ++i;
421 528 } }
422 529 } }
423 if (url_idx == -1)
424 fatal("missing url\n");
530 if (url_idx == -1) {
531 perr("missing url\n");
532 usage();
533 exit(1);
534 }
425 535 *url = args[url_idx]; *url = args[url_idx];
426 536 pout("url-->####%s####\n", *url); pout("url-->####%s####\n", *url);
427 537 } }
 
... ... STATIC void init_once(u8 *url, bool start_fullscreen, double initial_vol,
466 576 #undef WIDTH_NOT_DEFINED #undef WIDTH_NOT_DEFINED
467 577 #undef HEIGHT_NOT_DEFINED #undef HEIGHT_NOT_DEFINED
468 578 #define PRINT_INFO true #define PRINT_INFO true
469 STATIC void prepare(double initial_vol, u8 pkts_prefill_percent,
470 avcodec_params_t *audio_codec_params,
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,
585 enum avutil_audio_fr_fmt_t override_initial_ff_fmt,
586 u8 pkts_prefill_percent, avcodec_params_t *audio_codec_params,
471 587 avcodec_params_t *video_codec_params) avcodec_params_t *video_codec_params)
472 588 { {
473 589 enum avutil_audio_fr_fmt_t dst_fmt; enum avutil_audio_fr_fmt_t dst_fmt;
 
... ... STATIC void prepare(double initial_vol, u8 pkts_prefill_percent,
475 591 int dst_chans_n; int dst_chans_n;
476 592 uint64_t src_chans_layout; uint64_t src_chans_layout;
477 593 uint64_t dst_chans_layout; 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;
478 597
479 598 npv_pipeline_limits_reset(); npv_pipeline_limits_reset();
480 599 npv_pipeline_prefill_reset(pkts_prefill_percent); npv_pipeline_prefill_reset(pkts_prefill_percent);
481 600
482 601 npv_audio_dec_ctx_cfg(audio_codec_params); npv_audio_dec_ctx_cfg(audio_codec_params);
483 602 npv_video_dec_ctx_cfg(video_codec_params); npv_video_dec_ctx_cfg(video_codec_params);
603 /*--------------------------------------------------------------------*/
484 604 /* /*
485 * do our best to match the pcm cfg to audio ff dec output, BUT we don't
486 * expect to match it "exactly": see right below why
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.
487 608 */ */
488 npv_audio_pcm_cfg(npv_audio_pcm_p, npv_audio_dec_ctx_p->chans_n,
489 npv_audio_dec_ctx_p->fr_rate, npv_audio_dec_ctx_p->fr_fmt);
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 /*--------------------------------------------------------------------*/
490 630 /* use a ff filt to fill in the gap between the pcm and audio ff dec */ /* use a ff filt to fill in the gap between the pcm and audio ff dec */
491 631 npv_audio_pcm2ff(npv_audio_pcm_p, &dst_fmt, &dst_rate, &dst_chans_n, npv_audio_pcm2ff(npv_audio_pcm_p, &dst_fmt, &dst_rate, &dst_chans_n,
492 632 &dst_chans_layout, PRINT_INFO); &dst_chans_layout, PRINT_INFO);
 
... ... STATIC void prepare(double initial_vol, u8 pkts_prefill_percent,
498 638 src_chans_layout = npv_audio_dec_ctx_p->chans_layout; src_chans_layout = npv_audio_dec_ctx_p->chans_layout;
499 639 npv_audio_filt_cfg( npv_audio_filt_cfg(
500 640 npv_audio_dec_ctx_p->fr_fmt, npv_audio_dec_ctx_p->fr_rate, npv_audio_dec_ctx_p->fr_fmt, npv_audio_dec_ctx_p->fr_rate,
501 npv_audio_dec_ctx_p->chans_n, src_chans_layout,
502 false, initial_vol,
503 dst_fmt, dst_rate, dst_chans_n, dst_chans_layout,
504 PRINT_INFO);
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);
505 644 npv_audio_pcm_silence_bufs_cfg(npv_audio_pcm_p, PRINT_INFO); npv_audio_pcm_silence_bufs_cfg(npv_audio_pcm_p, PRINT_INFO);
506 645
507 646 evt_add_all_fds(); evt_add_all_fds();
508 647 } }
648 #undef PRINT_INFO
649 #undef CHANS_N_NOT_OVERRIDDEN
650 #undef RATE_NOT_OVERRIDDEN
651 #undef AUDIO_FR_FMT_NOT_OVERRIDDEN
509 652 STATIC void npv_cmd_quit(void) STATIC void npv_cmd_quit(void)
510 653 { {
511 654 exit_ok("quit command received\n"); exit_ok("quit command received\n");
 
... ... STATIC void npv_cmd_mute(void)
672 815 } }
673 816 #define WIDTH_NOT_DEFINED 0 #define WIDTH_NOT_DEFINED 0
674 817 #define HEIGHT_NOT_DEFINED 0 #define HEIGHT_NOT_DEFINED 0
818 #define CHANS_N_NOT_OVERRIDDEN 0
819 #define RATE_NOT_OVERRIDDEN 0
820 #define AUDIO_FR_FMT_NOT_OVERRIDDEN AVUTIL_AUDIO_FR_FMT_NONE
675 821 int main(int argc, u8 **args) int main(int argc, u8 **args)
676 822 { {
677 823 bool start_fullscreen; bool start_fullscreen;
678 824 u16 win_width; u16 win_width;
679 825 u16 win_height; u16 win_height;
680 826 u8 *pcm_str; u8 *pcm_str;
827 /* audio override -- start */
828 /*
829 * we could have got direct parameters for alsa, but doing only an
830 * override triggers an autoconfiguration of any missing parameters
831 * based on initial codec params. In other words, the user is not
832 * required to provide all audio params, the code will try to fit the
833 * missing ones with the initial codec params, which is the default
834 * behavior.
835 */
836 unsigned int override_initial_ff_chans_n;
837 unsigned int override_initial_ff_rate;
838 enum avutil_audio_fr_fmt_t override_initial_ff_audio_fr_fmt;
839 /* audio override -- end */
681 840 u8 *url; u8 *url;
682 841 double initial_vol; double initial_vol;
683 842 avcodec_params_t *audio_codec_params; avcodec_params_t *audio_codec_params;
 
... ... int main(int argc, u8 **args)
691 850 win_height = HEIGHT_NOT_DEFINED; win_height = HEIGHT_NOT_DEFINED;
692 851 url = 0; url = 0;
693 852 pcm_str = "default"; pcm_str = "default";
853 override_initial_ff_chans_n = CHANS_N_NOT_OVERRIDDEN;
854 override_initial_ff_rate = RATE_NOT_OVERRIDDEN;
855 override_initial_ff_audio_fr_fmt = AUDIO_FR_FMT_NOT_OVERRIDDEN;
694 856 url = 0; url = 0;
695 857 initial_vol = 1.; initial_vol = 1.;
696 858 npv_pipeline_limits_p.pkts.prefill.percent = 0; npv_pipeline_limits_p.pkts.prefill.percent = 0;
697 859 opts_parse(argc, args, &url, &start_fullscreen, &win_width, &win_height, opts_parse(argc, args, &url, &start_fullscreen, &win_width, &win_height,
698 &pcm_str, &initial_vol,
860 &pcm_str, &override_initial_ff_chans_n,
861 &override_initial_ff_rate,
862 &override_initial_ff_audio_fr_fmt,
863 &initial_vol,
699 864 &npv_pipeline_limits_p.pkts.prefill.percent); &npv_pipeline_limits_p.pkts.prefill.percent);
700 865 init_once(url, start_fullscreen, initial_vol, win_width, win_height, init_once(url, start_fullscreen, initial_vol, win_width, win_height,
701 866 pcm_str, &audio_codec_params, &video_codec_params, npv_faces); pcm_str, &audio_codec_params, &video_codec_params, npv_faces);
702 prepare(initial_vol, npv_pipeline_limits_p.pkts.prefill.percent,
703 audio_codec_params, video_codec_params);
867 prepare(initial_vol, override_initial_ff_chans_n,
868 override_initial_ff_rate, override_initial_ff_audio_fr_fmt,
869 npv_pipeline_limits_p.pkts.prefill.percent, audio_codec_params,
870 video_codec_params);
704 871
705 872 /* switch the ffmpeg log to stdout for metadata/etc dump */ /* switch the ffmpeg log to stdout for metadata/etc dump */
706 873 avutil_log_set_callback(ff_log_stdout); avutil_log_set_callback(ff_log_stdout);
 
... ... int main(int argc, u8 **args)
724 891 } }
725 892 #undef WIDTH_NOT_DEFINED #undef WIDTH_NOT_DEFINED
726 893 #undef HEIGHT_NOT_DEFINED #undef HEIGHT_NOT_DEFINED
894 #undef CHANS_N_NOT_OVERRIDDEN
895 #undef RATE_NOT_OVERRIDDEN
896 #undef AUDIO_FR_FMT_NOT_OVERRIDDEN
File npv/main.c changed (mode: 100644) (index 2089b02..1bb6e6e)
45 45 /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
46 46 #include "npv/namespace/public.h" #include "npv/namespace/public.h"
47 47 #include "npv/namespace/ffmpeg.h" #include "npv/namespace/ffmpeg.h"
48 #include "npv/namespace/alsa.h"
48 49 #include "npv/audio/namespace/ffmpeg.h" #include "npv/audio/namespace/ffmpeg.h"
49 50 #include "npv/namespace/public.h" #include "npv/namespace/public.h"
50 51 #include "npv/namespace/main.c" #include "npv/namespace/main.c"
 
58 59 #define CLEANUP #define CLEANUP
59 60 #include "npv/namespace/public.h" #include "npv/namespace/public.h"
60 61 #include "npv/namespace/ffmpeg.h" #include "npv/namespace/ffmpeg.h"
62 #include "npv/namespace/alsa.h"
61 63 #include "npv/audio/namespace/ffmpeg.h" #include "npv/audio/namespace/ffmpeg.h"
62 64 #include "npv/namespace/public.h" #include "npv/namespace/public.h"
63 65 #include "npv/namespace/main.c" #include "npv/namespace/main.c"
File npv/namespace/alsa.h changed (mode: 100644) (index ebab9f5..f257225)
1 1 #ifndef CLEANUP #ifndef CLEANUP
2 2 #define chans_n channels #define chans_n channels
3 3 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
4 #define SND_PCM_FMT_UNKNOWN SND_PCM_FORMAT_UNKNOWN
5 #define SND_PCM_FMT_FLOAT64 SND_PCM_FORMAT_FLOAT64
4 6 #define SND_PCM_FMT_FLOAT SND_PCM_FORMAT_FLOAT #define SND_PCM_FMT_FLOAT SND_PCM_FORMAT_FLOAT
5 7 #define SND_PCM_FMT_S32 SND_PCM_FORMAT_S32 #define SND_PCM_FMT_S32 SND_PCM_FORMAT_S32
6 8 #define SND_PCM_FMT_U32 SND_PCM_FORMAT_U32 #define SND_PCM_FMT_U32 SND_PCM_FORMAT_U32
File npv/namespace/ffmpeg.h changed (mode: 100644) (index 6c2e055..44451b6)
1 1 #ifndef CLEANUP #ifndef CLEANUP
2 #define AVUTIL_AUDIO_FR_FMT_NONE AV_SAMPLE_FMT_NONE
3 #define AVUTIL_AUDIO_FR_FMT_U8 AV_SAMPLE_FMT_U8
4 #define AVUTIL_AUDIO_FR_FMT_U8P AV_SAMPLE_FMT_U8P
5 #define AVUTIL_AUDIO_FR_FMT_S16 AV_SAMPLE_FMT_S16
6 #define AVUTIL_AUDIO_FR_FMT_S32 AV_SAMPLE_FMT_S32
7 #define AVUTIL_AUDIO_FR_FMT_FLT AV_SAMPLE_FMT_FLT
8 #define AVUTIL_AUDIO_FR_FMT_DBL AV_SAMPLE_FMT_DBL
9 #define AVUTIL_AUDIO_FR_FMT_U8P AV_SAMPLE_FMT_U8P
10 #define AVUTIL_AUDIO_FR_FMT_S16P AV_SAMPLE_FMT_S16P
11 #define AVUTIL_AUDIO_FR_FMT_S32P AV_SAMPLE_FMT_S32P
12 #define AVUTIL_AUDIO_FR_FMT_FLTP AV_SAMPLE_FMT_FLTP
13 #define AVUTIL_AUDIO_FR_FMT_DBLP AV_SAMPLE_FMT_DBLP
14 #define AVUTIL_OPT_SEARCH_CHILDREN AV_OPT_SEARCH_CHILDREN
2 15 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
3 16 #define AVFILTER_BUFSRC_FLAG_PUSH AV_BUFFERSRC_FLAG_PUSH #define AVFILTER_BUFSRC_FLAG_PUSH AV_BUFFERSRC_FLAG_PUSH
4 17 #define AVFILTER_BUFSRC_FLAG_KEEP_REF AV_BUFFERSRC_FLAG_KEEP_REF #define AVFILTER_BUFSRC_FLAG_KEEP_REF AV_BUFFERSRC_FLAG_KEEP_REF
 
41 54 #define avformat_st_t AVStream #define avformat_st_t AVStream
42 55 #define avutil_cpus_n av_cpu_count #define avutil_cpus_n av_cpu_count
43 56 #define avutil_free av_free #define avutil_free av_free
57 #define avutil_get_audio_fr_fmt_name av_get_sample_fmt_name
44 58 #define avutil_get_chans_layout_chans_n av_get_channel_layout_nb_channels #define avutil_get_chans_layout_chans_n av_get_channel_layout_nb_channels
45 59 #define avutil_get_chans_layout_str av_get_channel_layout_string #define avutil_get_chans_layout_str av_get_channel_layout_string
46 60 #define avutil_get_default_chans_layout av_get_default_channel_layout #define avutil_get_default_chans_layout av_get_default_channel_layout
 
65 79 #define sws_get_cached_ctx sws_getCachedContext #define sws_get_cached_ctx sws_getCachedContext
66 80 /*============================================================================*/ /*============================================================================*/
67 81 #else #else
82 #undef AVUTIL_AUDIO_FR_FMT_NONE
83 #undef AVUTIL_AUDIO_FR_FMT_U8
84 #undef AVUTIL_AUDIO_FR_FMT_S16
85 #undef AVUTIL_AUDIO_FR_FMT_S32
86 #undef AVUTIL_AUDIO_FR_FMT_FLT
87 #undef AVUTIL_AUDIO_FR_FMT_U8P
88 #undef AVUTIL_AUDIO_FR_FMT_S16P
89 #undef AVUTIL_AUDIO_FR_FMT_S32P
90 #undef AVUTIL_AUDIO_FR_FMT_FLTP
91 #undef AVUTIL_OPT_SEARCH_CHILDREN
92 /*----------------------------------------------------------------------------*/
68 93 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
69 94 #undef AVFILTER_BUFSRC_FLAG_PUSH #undef AVFILTER_BUFSRC_FLAG_PUSH
70 95 #undef AVFILTER_BUFSRC_FLAG_KEEP_REF #undef AVFILTER_BUFSRC_FLAG_KEEP_REF
 
108 133 #undef avformat_st_t #undef avformat_st_t
109 134 #undef avutil_cpus_n #undef avutil_cpus_n
110 135 #undef avutil_free #undef avutil_free
136 #undef avutil_get_audio_fr_fmt_name
111 137 #undef avutil_get_chans_layout_chans_n #undef avutil_get_chans_layout_chans_n
112 138 #undef avutil_get_chans_layout_str #undef avutil_get_chans_layout_str
113 139 #undef avutil_get_default_chans_layout #undef avutil_get_default_chans_layout
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