You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	Timefilter code by Olivier Guilyardi o list O samalyse o com
Originally committed as revision 17838 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
							
								
								
									
										77
									
								
								libavformat/timefilter.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								libavformat/timefilter.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | /* | ||||||
|  |  * Delay Locked Loop based time filter | ||||||
|  |  * Copyright (c) 2009 Samalyse | ||||||
|  |  * Author: Olivier Guilyardi <olivier samalyse com> | ||||||
|  |  * | ||||||
|  |  * This file is part of FFmpeg. | ||||||
|  |  * | ||||||
|  |  * FFmpeg is free software; you can redistribute it and/or | ||||||
|  |  * modify it under the terms of the GNU Lesser General Public | ||||||
|  |  * License as published by the Free Software Foundation; either | ||||||
|  |  * version 2.1 of the License, or (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * FFmpeg is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||||
|  |  * Lesser General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU Lesser General Public | ||||||
|  |  * License along with FFmpeg; if not, write to the Free Software | ||||||
|  |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "config.h" | ||||||
|  | #include "avformat.h" | ||||||
|  | #include "timefilter.h" | ||||||
|  |  | ||||||
|  | struct TimeFilter { | ||||||
|  |     /// Delay Locked Loop data. These variables refer to mathematical | ||||||
|  |     /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf | ||||||
|  |     double cycle_time; | ||||||
|  |     double next_cycle_time; | ||||||
|  |     double feedback2_factor; | ||||||
|  |     double feedback3_factor; | ||||||
|  |     double integrator2_state; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | TimeFilter * ff_timefilter_new(double period, double feedback2_factor, double feedback3_factor) | ||||||
|  | { | ||||||
|  |     TimeFilter *self        = av_mallocz(sizeof(TimeFilter)); | ||||||
|  |     self->integrator2_state = period; | ||||||
|  |     self->feedback2_factor  = feedback2_factor; | ||||||
|  |     self->feedback3_factor  = feedback3_factor; | ||||||
|  |     return self; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ff_timefilter_destroy(TimeFilter *self) | ||||||
|  | { | ||||||
|  |     av_freep(&self); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ff_timefilter_reset(TimeFilter *self) | ||||||
|  | { | ||||||
|  |     self->cycle_time = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ff_timefilter_update(TimeFilter *self, double system_time) | ||||||
|  | { | ||||||
|  |     if (!self->cycle_time) { | ||||||
|  |         /// init loop | ||||||
|  |         self->cycle_time        = system_time; | ||||||
|  |         self->next_cycle_time   = self->cycle_time + self->integrator2_state; | ||||||
|  |     } else { | ||||||
|  |         /// calculate loop error | ||||||
|  |         double loop_error = system_time - self->next_cycle_time; | ||||||
|  |  | ||||||
|  |         /// update loop | ||||||
|  |         self->cycle_time         = self->next_cycle_time; | ||||||
|  |         self->next_cycle_time   += self->feedback2_factor * loop_error + self->integrator2_state; | ||||||
|  |         self->integrator2_state += self->feedback3_factor * loop_error; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | double ff_timefilter_read(TimeFilter *self) | ||||||
|  | { | ||||||
|  |     return self->cycle_time; | ||||||
|  | } | ||||||
							
								
								
									
										104
									
								
								libavformat/timefilter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								libavformat/timefilter.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | /* | ||||||
|  |  * Delay Locked Loop based time filter prototypes and declarations | ||||||
|  |  * Copyright (c) 2009 Samalyse | ||||||
|  |  * Author: Olivier Guilyardi <olivier samalyse com> | ||||||
|  |  * | ||||||
|  |  * This file is part of FFmpeg. | ||||||
|  |  * | ||||||
|  |  * FFmpeg is free software; you can redistribute it and/or | ||||||
|  |  * modify it under the terms of the GNU Lesser General Public | ||||||
|  |  * License as published by the Free Software Foundation; either | ||||||
|  |  * version 2.1 of the License, or (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * FFmpeg is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||||
|  |  * Lesser General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU Lesser General Public | ||||||
|  |  * License along with FFmpeg; if not, write to the Free Software | ||||||
|  |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef AVFORMAT_TIMEFILTER_H | ||||||
|  | #define AVFORMAT_TIMEFILTER_H | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Opaque type representing a time filter state | ||||||
|  |  * | ||||||
|  |  * The purpose of this filter is to provide a way to compute accurate time | ||||||
|  |  * stamps that can be compared to wall clock time, especially when dealing | ||||||
|  |  * with two clocks: the system clock and a hardware device clock, such as | ||||||
|  |  * a soundcard. | ||||||
|  |  */ | ||||||
|  | typedef struct TimeFilter TimeFilter; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Create a new Delay Locked Loop time filter | ||||||
|  |  * | ||||||
|  |  * period is the device cycle duration in seconds. For example, at | ||||||
|  |  * 44.1Hz and a buffer size of 512 frames, period = 512 / 44100. The filter | ||||||
|  |  * only works if the cycle duration is fixed. | ||||||
|  |  * | ||||||
|  |  * feedback2_factor and feedback3_factor are the factors used for the | ||||||
|  |  * multiplications that are respectively performed in the second and third | ||||||
|  |  * feedback paths of the loop. | ||||||
|  |  * | ||||||
|  |  * Unless you know what you are doing, you should set these as follow: | ||||||
|  |  * | ||||||
|  |  * o = 2 * M_PI * bandwidth * period | ||||||
|  |  * feedback2_factor = sqrt(2 * o) | ||||||
|  |  * feedback3_factor = o * o | ||||||
|  |  * | ||||||
|  |  * Where bandwidth is up to you to choose. Smaller values will filter out more | ||||||
|  |  * of the jitter, but also take a longer time for the loop to settle. A good | ||||||
|  |  * starting point is something between 0.3 and 3 Hz. | ||||||
|  |  * | ||||||
|  |  * For more details about these parameters and background concepts please see: | ||||||
|  |  * http://www.kokkinizita.net/papers/usingdll.pdf | ||||||
|  |  */ | ||||||
|  | TimeFilter * ff_timefilter_new(double period, double feedback2_factor, double feedback3_factor); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Update the filter | ||||||
|  |  * | ||||||
|  |  * This function must be called in real time, at each process cycle. | ||||||
|  |  * | ||||||
|  |  * system_time, in seconds, should be the value of the system clock time, | ||||||
|  |  * at (or as close as possible to) the moment the device hardware interrupt | ||||||
|  |  * occured (or any other event the device clock raises at the beginning of a | ||||||
|  |  * cycle). | ||||||
|  |  */ | ||||||
|  | void ff_timefilter_update(TimeFilter *self, double system_time); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Retrieve the filtered time | ||||||
|  |  * | ||||||
|  |  * The returned value represents the filtered time, in seconds, of the | ||||||
|  |  * beginning of the current cycle as updated by the last call to | ||||||
|  |  * ff_timefilter_update() | ||||||
|  |  * | ||||||
|  |  * This is the value that should be used for timestamping. | ||||||
|  |  * | ||||||
|  |  * Warning: you must call ff_timefilter_update() before this, otherwise the | ||||||
|  |  * result is undetermined. | ||||||
|  |  */ | ||||||
|  | double ff_timefilter_read(TimeFilter *); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Reset the filter | ||||||
|  |  * | ||||||
|  |  * This function should mainly be called in case of XRUN. | ||||||
|  |  * | ||||||
|  |  * Warning: after calling this, the filter is in an undetermined state until | ||||||
|  |  * the next call to ff_timefilter_update() | ||||||
|  |  */ | ||||||
|  | void ff_timefilter_reset(TimeFilter *); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Free all resources associated with the filter | ||||||
|  |  */ | ||||||
|  | void ff_timefilter_destroy(TimeFilter *); | ||||||
|  |  | ||||||
|  | #endif /* AVFORMAT_TIMEFILTER_H */ | ||||||
		Reference in New Issue
	
	Block a user