[FFmpeg-devel] [PATCH 1/6] lavu: add av_gettime_relative()

Nicolas George george at nsup.org
Wed May 7 16:12:01 CEST 2014


Le septidi 17 floréal, an CCXXII, Olivier Langlois a écrit :
> These functions are using the POSIX clock_gettime() function with the
> CLOCK_MONOTONIC clock id. If these are not present on the targeted
> platform, the new functions will fallback on using the original realtime functions
> av_gettime() and av_usleep().
> 
> Monotonic support can be added on other platforms with their
> equivalent native system API eventually if possible.
> 
> Whenever time is requested to measure relative time, the monotonic clock,
> when available, is superior to the system realtime clock because it is
> not affected by discontinuous jumps in the system time
> 
> In a future step, offering the flexibility to let the user choose between
> rt and monotonic clock for avdevices packets will be investigated.
> 
> It is very easy to experience the issues that this patch attempt to address
> by rewinding back in the past the system time while ffmpeg is running.
> 
> this is breaking the ffmpeg report printing (ffmepg.c:print_report()) and
> the the rate emulator functionality (-re) without the patch.
> 
> Signed-off-by: Olivier Langlois <olivier at trillion01.com>
> ---

>  configure          |  2 ++
>  libavdevice/v4l2.c | 14 ++------------
>  libavutil/time.c   | 31 ++++++++++++++++++++++++++++++-
>  libavutil/time.h   | 15 +++++++++++++++
>  4 files changed, 49 insertions(+), 13 deletions(-)

Did you want to keep the lavd change with the lavu change? I suppose they
used to conflict, but they no longer do.

> 
> diff --git a/configure b/configure
> index e5ff72b..656ae3d 100755
> --- a/configure
> +++ b/configure
> @@ -1659,6 +1659,7 @@ SYSTEM_FUNCS="
>      access
>      aligned_malloc
>      clock_gettime

> +    clock_nanosleep

Seems not useful anymore.

>      closesocket
>      CommandLineToArgvW
>      CoTaskMemFree
> @@ -4489,6 +4490,7 @@ check_func  ${malloc_prefix}posix_memalign      && enable posix_memalign
>  
>  check_func  access
>  check_func  clock_gettime || { check_func clock_gettime -lrt && add_extralibs -lrt; }

> +check_func  clock_nanosleep || { check_func clock_nanosleep && add_extralibs -lrt; }

Ditto.

>  check_func  fcntl
>  check_func  fork
>  check_func  gethrtime
> diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
> index 4b3f6a8..cbc70e6 100644
> --- a/libavdevice/v4l2.c
> +++ b/libavdevice/v4l2.c
> @@ -424,16 +424,6 @@ static void mmap_release_buffer(void *opaque, uint8_t *data)
>      avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
>  }
>  
> -#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
> -static int64_t av_gettime_monotonic(void)
> -{
> -    struct timespec tv;
> -
> -    clock_gettime(CLOCK_MONOTONIC, &tv);
> -    return (int64_t)tv.tv_sec * 1000000 + tv.tv_nsec / 1000;
> -}
> -#endif
> -
>  static int init_convert_timestamp(AVFormatContext *ctx, int64_t ts)
>  {
>      struct video_data *s = ctx->priv_data;
> @@ -448,7 +438,7 @@ static int init_convert_timestamp(AVFormatContext *ctx, int64_t ts)
>      }
>  #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
>      if (ctx->streams[0]->avg_frame_rate.num) {
> -        now = av_gettime_monotonic();
> +        now = av_gettime_relative();
>          if (s->ts_mode == V4L_TS_MONO2ABS ||
>              (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE)) {
>              AVRational tb = {AV_TIME_BASE, 1};
> @@ -479,7 +469,7 @@ static int convert_timestamp(AVFormatContext *ctx, int64_t *ts)
>  #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
>      if (s->timefilter) {
>          int64_t nowa = av_gettime();
> -        int64_t nowm = av_gettime_monotonic();
> +        int64_t nowm = av_gettime_relative();
>          ff_timefilter_update(s->timefilter, nowa, nowm - s->last_time_m);
>          s->last_time_m = nowm;
>          *ts = ff_timefilter_eval(s->timefilter, *ts - nowm);
> diff --git a/libavutil/time.c b/libavutil/time.c
> index 5a00e70..0406ae8 100644
> --- a/libavutil/time.c
> +++ b/libavutil/time.c
> @@ -38,7 +38,15 @@
>  
>  int64_t av_gettime(void)
>  {
> -#if HAVE_GETTIMEOFDAY

> +#if HAVE_CLOCK_GETTIME
> +    /*
> +     * POSIX.1-2008 marks gettimeofday() as obsolete,
> +     * recommending the use of clock_gettime(2) instead.
> +     */
> +    struct timespec ts;
> +    clock_gettime(CLOCK_REALTIME, &ts);
> +    return (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
> +#elif HAVE_GETTIMEOFDAY

I really think this is unnecessary: gettimeofday() is not going away anytime
soon, so this would just be more code in FFmpeg for no benefit.

>      struct timeval tv;
>      gettimeofday(&tv, NULL);
>      return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
> @@ -53,6 +61,26 @@ int64_t av_gettime(void)
>  #endif
>  }
>  
> +int64_t av_gettime_relative(void)
> +{
> +#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
> +    struct timespec ts;
> +    clock_gettime(CLOCK_MONOTONIC, &ts);
> +    return (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
> +#else
> +    return av_gettime();
> +#endif
> +}
> +
> +int av_gettime_relative_is_monotonic(void)
> +{
> +#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
> +    return 1;
> +#else
> +    return 0;
> +#endif
> +}
> +
>  int av_usleep(unsigned usec)
>  {
>  #if HAVE_NANOSLEEP
> @@ -68,3 +96,4 @@ int av_usleep(unsigned usec)
>      return AVERROR(ENOSYS);
>  #endif
>  }
> +
> diff --git a/libavutil/time.h b/libavutil/time.h
> index 90eb436..910d28e 100644
> --- a/libavutil/time.h
> +++ b/libavutil/time.h
> @@ -29,6 +29,21 @@
>  int64_t av_gettime(void);
>  
>  /**
> + * Get the current time in microseconds since some unspecified starting point.
> + * On platforms that support it, the time comes from a monotonic clock
> + * This property makes this time source ideal for measuring relative time.
> + * If a monotonic clock is not available on the targeted platform, the
> + * implementation fallsback on using av_gettime().
> + */
> +int64_t av_gettime_relative(void);
> +
> +/**
> + * Indicates with a boolean result if the av_gettime_relative() time source
> + * is monotonic.
> + */
> +int av_gettime_relative_is_monotonic(void);
> +
> +/**
>   * Sleep for a period of time.  Although the duration is expressed in
>   * microseconds, the actual delay may be rounded to the precision of the
>   * system timer.

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140507/58a86184/attachment.asc>


More information about the ffmpeg-devel mailing list