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