npv:vulkan synchronization less wrong
[nyanmp.git] / npv / clk / public / code.frag.c
blob84aafbaf4eb4c854cca50238fb45a859f0ad117a
1 STATIC void npv_clk_init_once(void)
3 int r;
5 r = snd_pcm_status_malloc(&npv_clk_l.ref.status);
6 if (r != 0)
7 npv_clk_fatal("alsa:unable to allocate an alsa status structure\n");
8 r = snd_pcm_status_malloc(&npv_clk_l.now.status);
9 if (r != 0)
10 npv_clk_fatal("alsa:unable to allocate an alsa status structure\n");
11 /* we pre-allocate alsa pcm hw_params container */
12 r = snd_pcm_hw_params_malloc(&npv_clk_pcm_hw_params_l);
13 if (r < 0)
14 npv_clk_fatal("alsa:unable to allocate hardware parameters context\n");
15 npv_clk_l.paused = false;
17 #define NO_REF_TIME_POINT 1
18 STATIC u8 npv_clk_get_audio_filt_ts(s64 *ts)
20 int r;
21 snd_pcm_audio_tstamp_config_t ac;
22 snd_htimestamp_t hts;
23 f64 now_ns;
24 f64 ref_ns;
25 f64 ref_status_ns;
26 f64 ref_delay_frs_n;
27 f64 ref_audio_filt_ts;
28 avutil_rational_t audio_filt_tb;
29 f64 audio_filt_tb_num;
30 f64 audio_filt_tb_den;
31 f64 audio_rate_num;
32 unsigned int audio_rate_num_ui;
33 f64 audio_rate_den;
34 unsigned int audio_rate_den_ui;
35 f64 written_frs_n;
36 f64 now_audio_ts;
37 f64 now_video_ts;
39 if (!npv_clk_l.ref_valid)
40 return NO_REF_TIME_POINT;
41 if (!npv_clk_l.paused) {
42 memset(npv_clk_l.now.status, 0, snd_pcm_status_sizeof());
43 ac.report_delay = 0;
44 ac.type_requested = (unsigned int)npv_audio_selected_ts_type_p;
45 snd_pcm_status_set_audio_htstamp_config(npv_clk_l.now.status,
46 &ac);
47 r = snd_pcm_status(npv_audio_pcm_p, npv_clk_l.now.status);
48 if (r < 0)
49 npv_clk_fatal("alsa:unable to sample timing information for 'now' time point\n");
51 snd_pcm_status_get_audio_htstamp(npv_clk_l.now.status, &hts);
52 now_ns = (f64)hts.tv_sec * 1e9 + (f64)hts.tv_nsec;
54 snd_pcm_status_get_audio_htstamp(npv_clk_l.ref.status, &hts);
55 ref_status_ns = (f64)hts.tv_sec * 1e9 + (f64)hts.tv_nsec;
57 ref_audio_filt_ts = (f64)npv_clk_l.ref.audio_filt_ts;
58 ref_delay_frs_n = (f64)snd_pcm_status_get_delay(npv_clk_l.ref.status);
59 /* we are writting the output of the filt to the audio pcm */
60 audio_filt_tb = avfilter_bufsink_tb_get(npv_audio_filt_p.abufsink_ctx);
61 audio_filt_tb_num = (f64)audio_filt_tb.num;
62 audio_filt_tb_den = (f64)audio_filt_tb.den;
63 /*--------------------------------------------------------------------*/
64 r = snd_pcm_hw_params_current(npv_audio_pcm_p, npv_clk_pcm_hw_params_l);
65 if (r != 0)
66 npv_clk_fatal("alsa:unable to get current hardware parameters\n");
67 r = snd_pcm_hw_params_get_rate_numden(npv_clk_pcm_hw_params_l,
68 &audio_rate_num_ui, &audio_rate_den_ui);
69 if (r < 0)
70 npv_clk_fatal("alsa:unable to get exact rate\n");
71 audio_rate_num = (f64)audio_rate_num_ui;
72 audio_rate_den = (f64)audio_rate_den_ui;
73 /*--------------------------------------------------------------------*/
74 written_frs_n = (f64)npv_clk_l.ref.written_ufrs_n;
76 /* time translation */
77 ref_ns = ref_status_ns + (ref_delay_frs_n - written_frs_n)
78 * audio_rate_den * 1e9 / audio_rate_num;
79 /* basic linear interpolation */
80 now_audio_ts = audio_filt_tb_den * 1e-9 * (now_ns - ref_ns)
81 / audio_filt_tb_num + ref_audio_filt_ts;
82 *ts = (s64)lrint(now_audio_ts);
83 return TS_RETURNED;
85 #undef NO_REF_TIME_POINT
86 STATIC u8 npv_clk_get_video_st_ts(s64 *ts)
88 avutil_rational_t audio_filt_tb;
89 s64 now_audio_filt_ts;
90 u8 r;
92 audio_filt_tb = avfilter_bufsink_tb_get(npv_audio_filt_p.abufsink_ctx);
93 r = npv_clk_get_audio_filt_ts(&now_audio_filt_ts);
94 if (r != TS_RETURNED)
95 return r;
96 *ts = avutil_rescale_q(now_audio_filt_ts, audio_filt_tb,
97 npv_video_st_p.tb);
98 return TS_RETURNED;
100 STATIC void npv_clk_ref_time_point_update(s64 audio_filt_ts,
101 snd_pcm_ufrs_t written_ufrs_n)
103 int r;
104 snd_pcm_audio_tstamp_config_t ac;
106 memset(npv_clk_l.ref.status, 0, snd_pcm_status_sizeof());
107 ac.report_delay = 0;
108 ac.type_requested = (unsigned int)npv_audio_selected_ts_type_p;
109 snd_pcm_status_set_audio_htstamp_config(npv_clk_l.ref.status, &ac);
110 r = snd_pcm_status(npv_audio_pcm_p, npv_clk_l.ref.status);
111 if (r < 0)
112 npv_clk_fatal("unable to sample timing information for reference time point\n");
113 npv_clk_l.ref.audio_filt_ts = audio_filt_ts;
114 npv_clk_l.ref.written_ufrs_n = written_ufrs_n;
115 npv_clk_l.ref_valid = true;
117 STATIC void npv_clk_invalidate(void)
119 npv_clk_l.ref_valid = false;
121 STATIC void npv_clk_pause(void)
123 int r;
124 snd_pcm_audio_tstamp_config_t ac;
126 npv_clk_l.paused = true;
127 memset(npv_clk_l.now.status, 0, snd_pcm_status_sizeof());
128 ac.report_delay = 0;
129 ac.type_requested = (unsigned int)npv_audio_selected_ts_type_p;
130 snd_pcm_status_set_audio_htstamp_config(npv_clk_l.now.status, &ac);
131 r = snd_pcm_status(npv_audio_pcm_p, npv_clk_l.now.status);
132 if (r < 0)
133 npv_clk_fatal("alsa:unable to sample timing information for 'paused' time point\n");
135 STATIC void npv_clk_unpause(void)
137 npv_clk_l.paused = false;
138 npv_clk_invalidate();