npv: media pipeline
[nyanmp.git] / npv / clk / public / code.frag.c
blob1795d99290ad9a29e94f79b2a293b5d8ac23ce21
1 static void clk_init_once(void)
3 int r;
5 r = snd_pcm_status_malloc(&clk_l.ref.status);
6 if (r != 0)
7 FATALCLK("alsa:unable to allocate an alsa status structure\n");
8 r = snd_pcm_status_malloc(&clk_l.now.status);
9 if (r != 0)
10 FATALCLK("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(&clk_pcm_hw_params_l);
13 if (r < 0)
14 FATALCLK("alsa:unable to allocate hardware parameters context\n");
16 #define NO_REF_TIME_POINT 1
17 static u8 clk_get_audio_st_ts(s64 *ts)
19 int r;
20 snd_pcm_audio_tstamp_config_t ac;
21 snd_htimestamp_t hts;
22 f64 now_ns;
23 f64 ref_ns;
24 f64 ref_status_ns;
25 f64 ref_delay_frs_n;
26 f64 ref_audio_ts;
27 f64 audio_tb_num;
28 f64 audio_tb_den;
29 f64 audio_rate_num;
30 unsigned int audio_rate_num_ui;
31 f64 audio_rate_den;
32 unsigned int audio_rate_den_ui;
33 f64 written_frs_n;
34 f64 now_audio_ts;
35 f64 now_video_ts;
37 if (!clk_l.ref_valid)
38 return NO_REF_TIME_POINT;
39 memset(clk_l.now.status, 0, snd_pcm_status_sizeof());
40 ac.report_delay = 0;
41 ac.type_requested = (unsigned int)audio_selected_ts_type_p;
42 snd_pcm_status_set_audio_htstamp_config(clk_l.now.status, &ac);
43 r = snd_pcm_status(audio_pcm_p, clk_l.now.status);
44 if (r < 0)
45 FATALCLK("alsa:unable to sample timing information for 'now' time point\n");
46 snd_pcm_status_get_audio_htstamp(clk_l.now.status, &hts);
47 now_ns = (f64)hts.tv_sec * 1e9 + (f64)hts.tv_nsec;
49 snd_pcm_status_get_audio_htstamp(clk_l.ref.status, &hts);
50 ref_status_ns = (f64)hts.tv_sec * 1e9 + (f64)hts.tv_nsec;
52 ref_audio_ts = (f64)clk_l.ref.audio_st_ts;
53 ref_delay_frs_n = (f64)snd_pcm_status_get_delay(clk_l.ref.status);
54 audio_tb_num = (f64)audio_st_p.tb.num;
55 audio_tb_den = (f64)audio_st_p.tb.den;
56 /*--------------------------------------------------------------------*/
57 r = snd_pcm_hw_params_current(audio_pcm_p, clk_pcm_hw_params_l);
58 if (r != 0)
59 FATALCLK("alsa:unable to get current hardware parameters\n");
60 r = snd_pcm_hw_params_get_rate_numden(clk_pcm_hw_params_l,
61 &audio_rate_num_ui, &audio_rate_den_ui);
62 if (r < 0)
63 FATALCLK("alsa:unable to get exact rate\n");
64 audio_rate_num = (f64)audio_rate_num_ui;
65 audio_rate_den = (f64)audio_rate_den_ui;
66 /*--------------------------------------------------------------------*/
67 written_frs_n = (f64)clk_l.ref.written_ufrs_n;
69 /* time translation */
70 ref_ns = ref_status_ns + (ref_delay_frs_n - written_frs_n)
71 * audio_rate_den * 1e9 / audio_rate_num;
72 /* basic linear interpolation */
73 now_audio_ts = audio_tb_den * 1e-9 * (now_ns - ref_ns) / audio_tb_num
74 + ref_audio_ts;
75 *ts = (s64)lrint(now_audio_ts);
76 return TS_RETURNED;
78 #undef NO_REF_TIME_POINT
79 static u8 clk_get_video_st_ts(s64 *ts)
81 f64 audio_tb_num;
82 f64 audio_tb_den;
83 f64 video_tb_num;
84 f64 video_tb_den;
85 f64 now_audio_ts;
86 s64 now_audio_ts_s64;
87 f64 now_video_ts;
88 u8 r;
90 audio_tb_num = (f64)audio_st_p.tb.num;
91 audio_tb_den = (f64)audio_st_p.tb.den;
92 video_tb_num = (f64)video_st_p.tb.num;
93 video_tb_den = (f64)video_st_p.tb.den;
95 r = clk_get_audio_st_ts(&now_audio_ts_s64);
96 if (r != TS_RETURNED)
97 return r;
98 now_audio_ts = (f64)now_audio_ts_s64;
99 /* basic conversion */
100 now_video_ts = audio_tb_num * video_tb_den * now_audio_ts
101 / (audio_tb_den * video_tb_num);
102 *ts = (s64)lrint(now_video_ts);
103 return TS_RETURNED;
105 static void clk_ref_time_point_update(s64 audio_ts,
106 snd_pcm_ufrs_t written_ufrs_n)
108 int r;
109 snd_pcm_audio_tstamp_config_t ac;
111 memset(clk_l.ref.status, 0, snd_pcm_status_sizeof());
112 ac.report_delay = 0;
113 ac.type_requested = (unsigned int)audio_selected_ts_type_p;
114 snd_pcm_status_set_audio_htstamp_config(clk_l.ref.status, &ac);
115 r = snd_pcm_status(audio_pcm_p, clk_l.ref.status);
116 if (r < 0)
117 FATALCLK("unable to sample timing information for reference time point\n");
118 clk_l.ref.audio_st_ts = audio_ts;
119 clk_l.ref.written_ufrs_n = written_ufrs_n;
120 clk_l.ref_valid = true;
122 static void clk_invalidate(void)
124 clk_l.ref_valid = false;