mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-28 13:40:55 +00:00
swr: add swr_next_pts()
parameter descriptions partly reuse text from af_asyncts Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
f88f705abc
commit
72a242c998
@ -24,6 +24,8 @@
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/audioconvert.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#define C30DB M_SQRT2
|
||||
#define C15DB 1.189207115
|
||||
#define C__0DB 1.0
|
||||
@ -78,6 +80,15 @@ static const AVOption options[]={
|
||||
{"phase_shift" , "Resampling Phase Shift" , OFFSET(phase_shift) , AV_OPT_TYPE_INT , {.dbl=10 }, 0 , 30 , PARAM },
|
||||
{"linear_interp" , "Use Linear Interpolation" , OFFSET(linear_interp) , AV_OPT_TYPE_INT , {.dbl=0 }, 0 , 1 , PARAM },
|
||||
{"cutoff" , "Cutoff Frequency Ratio" , OFFSET(cutoff) , AV_OPT_TYPE_DOUBLE,{.dbl=0.8 }, 0 , 1 , PARAM },
|
||||
{"min_comp" , "Minimum difference between timestamps and audio data (in seconds) below which no timestamp compensation of either kind is applied"
|
||||
, OFFSET(min_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=FLT_MAX }, 0 , FLT_MAX , PARAM },
|
||||
{"min_hard_comp" , "Minimum difference between timestamps and audio data (in seconds) to trigger padding/trimming the data."
|
||||
, OFFSET(min_hard_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0.1 }, 0 , INT_MAX , PARAM },
|
||||
{"comp_duration" , "Duration (in seconds) over which data is stretched/squeezeed to make it match the timestamps."
|
||||
, OFFSET(soft_compensation_duration),AV_OPT_TYPE_FLOAT ,{.dbl=1 }, 0 , INT_MAX , PARAM },
|
||||
{"max_soft_comp" , "Maximum factor by which data is stretched/squeezeed to make it match the timestamps."
|
||||
, OFFSET(max_soft_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0 }, 0 , INT_MAX , PARAM },
|
||||
|
||||
{0}
|
||||
};
|
||||
|
||||
@ -644,7 +655,10 @@ int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_coun
|
||||
fill_audiodata(out, out_arg);
|
||||
|
||||
if(s->resample){
|
||||
return swr_convert_internal(s, out, out_count, in, in_count);
|
||||
int ret = swr_convert_internal(s, out, out_count, in, in_count);
|
||||
if(ret>0 && !s->drop_output)
|
||||
s->outpts += ret * (int64_t)s->in_sample_rate;
|
||||
return ret;
|
||||
}else{
|
||||
AudioData tmp= *in;
|
||||
int ret2=0;
|
||||
@ -693,6 +707,8 @@ int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_coun
|
||||
s->in_buffer_count += in_count;
|
||||
}
|
||||
}
|
||||
if(ret2>0 && !s->drop_output)
|
||||
s->outpts += ret2 * (int64_t)s->in_sample_rate;
|
||||
return ret2;
|
||||
}
|
||||
}
|
||||
@ -731,3 +747,28 @@ int swr_inject_silence(struct SwrContext *s, int count){
|
||||
av_freep(&silence.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t swr_next_pts(struct SwrContext *s, int64_t pts){
|
||||
if(pts == INT64_MIN)
|
||||
return s->outpts;
|
||||
if(s->min_compensation >= FLT_MAX) {
|
||||
return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate));
|
||||
} else {
|
||||
int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts;
|
||||
double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate);
|
||||
|
||||
if(fabs(fdelta) > s->min_compensation) {
|
||||
if(!s->outpts || fabs(fdelta) > s->min_hard_compensation){
|
||||
if(delta > 0) swr_inject_silence(s, delta / s->out_sample_rate);
|
||||
else swr_drop_output (s, -delta / s-> in_sample_rate);
|
||||
} else {
|
||||
int duration = s->out_sample_rate * s->soft_compensation_duration;
|
||||
int comp = av_clipf(fdelta, -s->max_soft_compensation, s->max_soft_compensation) * duration ;
|
||||
av_log(s, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
|
||||
swr_set_compensation(s, comp, duration);
|
||||
}
|
||||
}
|
||||
|
||||
return s->outpts;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "libavutil/samplefmt.h"
|
||||
|
||||
#define LIBSWRESAMPLE_VERSION_MAJOR 0
|
||||
#define LIBSWRESAMPLE_VERSION_MINOR 14
|
||||
#define LIBSWRESAMPLE_VERSION_MINOR 15
|
||||
#define LIBSWRESAMPLE_VERSION_MICRO 100
|
||||
|
||||
#define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \
|
||||
@ -132,6 +132,21 @@ void swr_free(struct SwrContext **s);
|
||||
int swr_convert(struct SwrContext *s, uint8_t **out, int out_count,
|
||||
const uint8_t **in , int in_count);
|
||||
|
||||
/**
|
||||
* Convert the next timestamp from input to output
|
||||
* timestampe are in 1/(in_sample_rate * out_sample_rate) units.
|
||||
*
|
||||
* @note There are 2 slightly differently behaving modes.
|
||||
* First is when automatic timestamp compensation is not used, (min_compensation >= FLT_MAX)
|
||||
* in this case timestamps will be passed through with delays compensated
|
||||
* Second is when automatic timestamp compensation is used, (min_compensation < FLT_MAX)
|
||||
* in this case the output timestamps will match output sample numbers
|
||||
*
|
||||
* @param pts timstamp for the next input sample, INT64_MIN if unknown
|
||||
* @returns the output timestamp for the next output sample
|
||||
*/
|
||||
int64_t swr_next_pts(struct SwrContext *s, int64_t pts);
|
||||
|
||||
/**
|
||||
* Activate resampling compensation.
|
||||
*/
|
||||
|
@ -62,6 +62,11 @@ struct SwrContext {
|
||||
int linear_interp; /**< if 1 then the resampling FIR filter will be linearly interpolated */
|
||||
double cutoff; /**< resampling cutoff frequency. 1.0 corresponds to half the output sample rate */
|
||||
|
||||
float min_compensation; ///< minimum below which no compensation will happen
|
||||
float min_hard_compensation; ///< minimum below which no silence inject / sample drop will happen
|
||||
float soft_compensation_duration; ///< duration over which soft compensation is applied
|
||||
float max_soft_compensation; ///< maximum soft compensation in seconds over soft_compensation_duration
|
||||
|
||||
int resample_first; ///< 1 if resampling must come first, 0 if rematrixing
|
||||
int rematrix; ///< flag to indicate if rematrixing is needed (basically if input and output layouts mismatch)
|
||||
int rematrix_custom; ///< flag to indicate that a custom matrix has been defined
|
||||
@ -77,6 +82,7 @@ struct SwrContext {
|
||||
int in_buffer_count; ///< cached buffer length
|
||||
int resample_in_constraint; ///< 1 if the input end was reach before the output end, 0 otherwise
|
||||
int flushed; ///< 1 if data is to be flushed and no further input is expected
|
||||
int64_t outpts; ///< output PTS
|
||||
int drop_output; ///< number of output samples to drop
|
||||
|
||||
struct AudioConvert *in_convert; ///< input conversion context
|
||||
|
Loading…
Reference in New Issue
Block a user