1 STATIC
void npv_clk_init_once(void)
5 r
= snd_pcm_status_malloc(&npv_clk_l
.ref
.status
);
7 npv_clk_fatal("alsa:unable to allocate an alsa status structure\n");
8 r
= snd_pcm_status_malloc(&npv_clk_l
.now
.status
);
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
);
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
)
21 snd_pcm_audio_tstamp_config_t ac
;
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
;
32 unsigned int audio_rate_num_ui
;
34 unsigned int audio_rate_den_ui
;
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());
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
,
47 r
= snd_pcm_status(npv_audio_pcm_p
, npv_clk_l
.now
.status
);
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
);
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
);
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
);
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
;
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
);
96 *ts
= avutil_rescale_q(now_audio_filt_ts
, audio_filt_tb
,
100 STATIC
void npv_clk_ref_time_point_update(s64 audio_filt_ts
,
101 snd_pcm_ufrs_t written_ufrs_n
)
104 snd_pcm_audio_tstamp_config_t ac
;
106 memset(npv_clk_l
.ref
.status
, 0, snd_pcm_status_sizeof());
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
);
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)
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());
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
);
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();