1 /* 2 * Copyright (C) 2000-2019 the xine project 3 * 4 * This file is part of xine, a free video player. 5 * 6 * xine is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * xine is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 19 * 20 * metronom: general pts => virtual calculation/assoc 21 * 22 * virtual pts: unit 1/90000 sec, always increasing 23 * can be used for synchronization 24 * video/audio frame with same pts also have same vpts 25 * but pts is likely to differ from vpts 26 * 27 * the basic idea is: 28 * video_pts + video_wrap_offset = video_vpts 29 * audio_pts + audio_wrap_offset = audio_vpts 30 * 31 * - video_wrap_offset should be equal to audio_wrap_offset as to have 32 * perfect audio and video sync. They will differ on brief periods due 33 * discontinuity correction. 34 * - metronom should also interpolate vpts values most of the time as 35 * video_pts and audio_vpts are not given for every frame. 36 * - corrections to the frame rate may be needed to cope with bad 37 * encoded streams. 38 */ 39 40 #ifndef HAVE_METRONOM_H 41 #define HAVE_METRONOM_H 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 #include <pthread.h> 48 49 #include <xine/video_out.h> 50 #include <xine.h> 51 52 typedef struct metronom_s metronom_t ; 53 typedef struct metronom_clock_s metronom_clock_t; 54 typedef struct scr_plugin_s scr_plugin_t; 55 56 /* metronom prebuffer can be adjusted with XINE_PARAM_METRONOM_PREBUFFER. 57 * it sets how much the first video/audio frame should be delayed to 58 * have some prebuffering at the output layers. reducing this value (about 59 * 1/8 sec) may result in faster seeking (good to simulate play backwards, 60 * for example). 61 */ 62 #define PREBUFFER_PTS_OFFSET 12000 63 64 /* see below */ 65 #define DISC_STREAMSTART 0 66 #define DISC_RELATIVE 1 67 #define DISC_ABSOLUTE 2 68 #define DISC_STREAMSEEK 3 69 #define DISC_GAPLESS 4 70 71 struct metronom_s { 72 73 /* 74 * called by audio output driver to inform metronom about current audio 75 * samplerate 76 * 77 * parameter pts_per_smpls : 1/90000 sec per 65536 samples 78 */ 79 void (*set_audio_rate) (metronom_t *self, int64_t pts_per_smpls); 80 81 /* 82 * called by video output driver for *every* frame 83 * 84 * parameter frame containing pts, scr, ... information 85 * 86 * will set vpts field in frame 87 * 88 * this function will also update video_wrap_offset if a discontinuity 89 * is detected (read the comentaries below about discontinuities). 90 * 91 */ 92 93 void (*got_video_frame) (metronom_t *self, vo_frame_t *frame); 94 95 /* 96 * called by audio output driver whenever audio samples are delivered to it 97 * 98 * parameter pts : pts for audio data if known, 0 otherwise 99 * nsamples : number of samples delivered 100 * 101 * return value: virtual pts for audio data 102 * 103 * this function will also update audio_wrap_offset if a discontinuity 104 * is detected (read the comentaries below about discontinuities). 105 * 106 */ 107 108 int64_t (*got_audio_samples) (metronom_t *self, int64_t pts, 109 int nsamples); 110 111 /* 112 * called by SPU decoder whenever a packet is delivered to it 113 * 114 * parameter pts : pts for SPU packet if known, 0 otherwise 115 * 116 * return value: virtual pts for SPU packet 117 * (this is the only pts to vpts function that cannot update the wrap_offset 118 * due to the lack of regularity on spu packets) 119 */ 120 121 int64_t (*got_spu_packet) (metronom_t *self, int64_t pts); 122 123 /* 124 * tell metronom about discontinuities. 125 * 126 * these functions are called due to a discontinuity detected at 127 * demux stage. 128 * 129 * there are different types of discontinuities: 130 * 131 * DISC_STREAMSTART : new stream starts, expect pts values to start 132 * from zero immediately 133 * DISC_RELATIVE : typically a wrap-around, expect pts with 134 * a specified offset from the former ones soon 135 * DISC_ABSOLUTE : typically a new menu stream (nav packets) 136 * pts will start from given value soon. 137 * this will try a seamless transition even if decoder 138 * reorders frames around it. 139 * DISC_STREAMSEEK : used by video and audio decoder loop, 140 * when a buffer with BUF_FLAG_SEEK set is encountered; 141 * applies the necessary vpts offset for the seek in 142 * metronom, but keeps the vpts difference between 143 * audio and video, so that metronom doesn't cough 144 * DISC_GAPLESS : wait until it is safe to start next gapless stream. 145 * used internally by xine_play (). 146 */ 147 void (*handle_audio_discontinuity) (metronom_t *self, int type, int64_t disc_off); 148 void (*handle_video_discontinuity) (metronom_t *self, int type, int64_t disc_off); 149 150 /* 151 * set/get options for metronom, constants see below 152 */ 153 void (*set_option) (metronom_t *self, int option, int64_t value); 154 int64_t (*get_option) (metronom_t *self, int option); 155 156 /* 157 * set a master metronom 158 * this is currently useful to sync independently generated streams 159 * (e.g. by post plugins) to the discontinuity domain of another 160 * metronom 161 */ 162 void (*set_master) (metronom_t *self, metronom_t *master); 163 164 void (*exit) (metronom_t *self); 165 166 }; 167 168 /* 169 * metronom options 170 */ 171 172 #define METRONOM_AV_OFFSET 2 173 #define METRONOM_ADJ_VPTS_OFFSET 3 174 #define METRONOM_FRAME_DURATION 4 175 #define METRONOM_SPU_OFFSET 5 176 #define METRONOM_VPTS_OFFSET 6 177 #define METRONOM_PREBUFFER 7 178 #define METRONOM_VPTS 8 179 /* METRONOM_LOCK can be used to lock metronom when multiple options needs to be fetched atomically (ex. VPTS_OFFSET and AV_OFFSET). 180 * example: 181 * metronom->set_option(metronom, METRONOM_LOCK, 1); 182 * vpts_offset = metronom->get_option(metronom, METRONOM_VPTS_OFFSET|METRONOM_NO_LOCK); 183 * av_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET|METRONOM_NO_LOCK); 184 * metronom->set_option(metronom, METRONOM_LOCK, 0); 185 */ 186 #define METRONOM_LOCK 9 187 /* Returns 0 (not waiting), 1 (waiting for audio discontinuity), 2 (waiting for video discontinuity). */ 188 #define METRONOM_WAITING 10 189 /* Nasty input_vdr helper. Inserts an immediate absolute discontinuity, 190 * old style without pts reorder fix. */ 191 #define METRONOM_VDR_TRICK_PTS 11 192 #define METRONOM_NO_LOCK 0x8000 193 194 typedef void xine_speed_change_cb_t (void *user_data, int new_speed); 195 196 metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine) XINE_MALLOC XINE_PROTECTED; 197 198 /* FIXME: reorder this structure on the next cleanup to remove the dummies */ 199 struct metronom_clock_s { 200 201 /* 202 * set/get options for clock, constants see below 203 */ 204 void (*set_option) (metronom_clock_t *self, int option, int64_t value); 205 int64_t (*get_option) (metronom_clock_t *self, int option); 206 207 /* 208 * system clock reference (SCR) functions 209 */ 210 211 #ifdef METRONOM_CLOCK_INTERNAL 212 /* 213 * start clock (no clock reset) 214 * at given pts 215 */ 216 void (*start_clock) (metronom_clock_t *self, int64_t pts); 217 218 219 /* 220 * stop metronom clock 221 */ 222 void (*stop_clock) (metronom_clock_t *self); 223 224 225 /* 226 * resume clock from where it was stopped 227 */ 228 void (*resume_clock) (metronom_clock_t *self); 229 #else 230 void *dummy1; 231 void *dummy2; 232 void *dummy3; 233 #endif 234 235 236 /* 237 * get current clock value in vpts 238 */ 239 int64_t (*get_current_time) (metronom_clock_t *self); 240 241 242 /* 243 * adjust master clock to external timer (e.g. audio hardware) 244 */ 245 void (*adjust_clock) (metronom_clock_t *self, int64_t desired_pts); 246 247 #ifdef METRONOM_CLOCK_INTERNAL 248 /* 249 * set clock speed 250 * for constants see xine_internal.h 251 */ 252 253 int (*set_fine_speed) (metronom_clock_t *self, int speed); 254 #else 255 void *dummy4; 256 #endif 257 258 /* 259 * (un)register a System Clock Reference provider at the metronom 260 */ 261 int (*register_scr) (metronom_clock_t *self, scr_plugin_t *scr); 262 void (*unregister_scr) (metronom_clock_t *self, scr_plugin_t *scr); 263 264 #ifdef METRONOM_CLOCK_INTERNAL 265 void (*exit) (metronom_clock_t *self); 266 267 xine_t *xine; 268 269 scr_plugin_t *scr_master; 270 scr_plugin_t **scr_list; 271 pthread_t sync_thread; 272 int thread_running; 273 int scr_adjustable; 274 #else 275 void *dummy5; 276 void *dummy6; 277 void *dummy7; 278 void *dummy8; 279 pthread_t dummy9; 280 int dummy10; 281 int dummy11; 282 #endif 283 284 int speed; 285 286 void (*register_speed_change_callback) 287 (metronom_clock_t *self, xine_speed_change_cb_t *callback, void *user_data); 288 void (*unregister_speed_change_callback) 289 (metronom_clock_t *self, xine_speed_change_cb_t *callback, void *user_data); 290 291 #ifdef METRONOM_CLOCK_INTERNAL 292 pthread_mutex_t lock; 293 pthread_cond_t cancel; 294 #endif 295 }; 296 297 metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_MALLOC XINE_PROTECTED; 298 299 /* 300 * clock options 301 */ 302 303 #define CLOCK_SCR_ADJUSTABLE 1 304 305 /* 306 * SCR (system clock reference) plugins 307 */ 308 309 struct scr_plugin_s 310 { 311 int (*get_priority) (scr_plugin_t *self); 312 313 /* 314 * set/get clock speed 315 * 316 * for speed constants see xine_internal.h 317 * returns actual speed 318 */ 319 320 int (*set_fine_speed) (scr_plugin_t *self, int speed); 321 322 void (*adjust) (scr_plugin_t *self, int64_t vpts); 323 324 void (*start) (scr_plugin_t *self, int64_t start_vpts); 325 326 int64_t (*get_current) (scr_plugin_t *self); 327 328 void (*exit) (scr_plugin_t *self); 329 330 metronom_clock_t *clock; 331 332 int interface_version; 333 }; 334 335 #ifdef __cplusplus 336 } 337 #endif 338 339 #endif 340