[FFmpeg-devel] [PATCH] Extracting NTP timestamp from RTCP

Michael Niedermayer michaelni at gmx.at
Wed Dec 4 16:09:00 CET 2013


On Mon, Dec 02, 2013 at 03:44:16PM -0700, Fred Rothganger wrote:
> On 11/26/2013 06:51 PM, Michael Niedermayer wrote:
> >On Mon, Nov 25, 2013 at 01:11:04PM -0700, Fred Rothganger wrote:
> >>On 11/14/2013 01:14 PM, Reimar Döffinger wrote:
> >>>I believe that _someone_ at _some point_ will have to make that
> >>>assumption though. Unless they want to have some ugly
> >>>user-interface mess like every stream initially showing as
> >>>"created 1970" to the suddenly jump to the correct value. Either
> >>>way, the short of it is that I can't see that 0 as an
> >>>initialization value will cause anything but annoyance long-term.
> >>>INT64_MAX hopefully only long beyond the time we would care about.
> >>>And UINT64_MAX means you have to be careful to not involve
> >>>anything signed at any point, unless there's a good reason I'd
> >>>prefer sticking with INT64_MAX (and ideally some error handling if
> >>>the received timestamps should be >= than that).
> >>INT64_MAX will work. Attached is another patch which creates
> >>AV_NO_REALTIME and uses it instead of 0.
> >why isnt AV_NOPTS_VALUE used ?
> >
> >
> 
> Here's a version that uses AV_NOPTS_VALUE instead.
> 
> AV_NOPTS_VALUE works because it is outside the useful range of date
> values, given the scaling of the field.
> 
> The following observation is not directly related to this patch. A
> few lines above in rtsp.c it says:
> 
>             if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
>             ...
> 
> NTP time is defined in the standard as an unsigned 64-bit value.
> However, the field first_rtcp_ntp_time is signed. AV_NOPTS_VALUE
> falls in the middle of its range, so there is latent bug when NTP
> time crosses through this value. We aren't in any danger of this
> happening soon, unless one works with historic footage.

>  doc/APIchanges              |    3 +++
>  libavformat/avformat.h      |    2 +-
>  libavformat/options_table.h |    1 +
>  libavformat/rtpenc.c        |    2 +-
>  libavformat/rtsp.c          |   10 ++++++++++
>  libavformat/version.h       |    2 +-
>  6 files changed, 17 insertions(+), 3 deletions(-)
> 62a25ef689a08f817fcbc7feec12469793b4b178  rtsp.patch
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 08ba47f..77d2ae6 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -15,6 +15,9 @@ libavutil:     2012-10-22
>  
>  API changes, most recent first:
>  
> +2013-12-02 - xxxxxxx - lavf 55.22.101 - avformat.h
> +  Set AVFormatContext.start_time_realtime when decoding.
> +
>  2013-11-xx - xxxxxxx - lavu 52.56.100 - ffversion.h
>    Moves version.h to libavutil/ffversion.h.
>    Install ffversion.h and make it public.
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 6bd54ce..6f54627 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -1127,7 +1127,7 @@ typedef struct AVFormatContext {
>       * since the unix epoch (00:00 1st January 1970). That is, pts=0
>       * in the stream was captured at this real world time.
>       * - encoding: Set by user.
> -     * - decoding: Unused.
> +     * - decoding: Set by libavformt. Set to AV_NOPTS_VALUE if unknown.
>       */
>      int64_t start_time_realtime;
>  
> diff --git a/libavformat/options_table.h b/libavformat/options_table.h
> index 8145325..1047a32 100644
> --- a/libavformat/options_table.h
> +++ b/libavformat/options_table.h
> @@ -57,6 +57,7 @@ static const AVOption avformat_options[] = {
>  {"fdebug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, E|D, "fdebug"},
>  {"ts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, "fdebug"},
>  {"max_delay", "maximum muxing or demuxing delay in microseconds", OFFSET(max_delay), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, INT_MAX, E|D},
> +{"start_time_realtime", "wall-clock time when stream begins (PTS==0)", OFFSET(start_time_realtime), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX, E|D},

this would allow the user to set start_time_realtime for decoding which
makes no sense


>  {"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX-1, D},
>  {"audio_preload", "microseconds by which audio packets should be interleaved earlier", OFFSET(audio_preload), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E},
>  {"chunk_duration", "microseconds for each chunk", OFFSET(max_chunk_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E},
> diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
> index 6fdc908..5e73661 100644
> --- a/libavformat/rtpenc.c
> +++ b/libavformat/rtpenc.c
> @@ -119,7 +119,7 @@ static int rtp_write_header(AVFormatContext *s1)
>          s->ssrc = av_get_random_seed();
>      s->first_packet = 1;
>      s->first_rtcp_ntp_time = ff_ntp_time();
> -    if (s1->start_time_realtime)
> +    if (s1->start_time_realtime != AV_NOPTS_VALUE)

this looks like it breaks ABI
a application that means "no value" would have used 0 before but now
0 is interpreted as a litteral 0


>          /* Round the NTP time to whole milliseconds. */
>          s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 +
>                                   NTP_OFFSET_US;
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index 3b88fc7..b436164 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -2066,6 +2066,16 @@ redo:
>                              st2->time_base);
>                      }
>                  }
> +                // Make real NTP start time available in AVFormatContext
> +                if (s->start_time_realtime == AV_NOPTS_VALUE) {
> +                    s->start_time_realtime = av_rescale (rtpctx->first_rtcp_ntp_time - (NTP_OFFSET << 32), 1000000, 1LL << 32);
> +                    if (rtpctx->st) {
> +                        s->start_time_realtime -=
> +                            av_rescale (rtpctx->rtcp_ts_offset,
> +                                        (uint64_t) rtpctx->st->time_base.num * 1000000,
> +                                                   rtpctx->st->time_base.den);
> +                    }
> +                }
>              }
>              if (ret == -RTCP_BYE) {
>                  rt->nb_byes++;
> diff --git a/libavformat/version.h b/libavformat/version.h
> index 4fe8364..84a75aa 100644
> --- a/libavformat/version.h
> +++ b/libavformat/version.h
> @@ -31,7 +31,7 @@
>  
>  #define LIBAVFORMAT_VERSION_MAJOR 55
>  #define LIBAVFORMAT_VERSION_MINOR 22
> -#define LIBAVFORMAT_VERSION_MICRO 100
> +#define LIBAVFORMAT_VERSION_MICRO 101
>  
>  #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
>                                                 LIBAVFORMAT_VERSION_MINOR, \

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Everything should be made as simple as possible, but not simpler.
-- Albert Einstein
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20131204/aa26a0ab/attachment.asc>


More information about the ffmpeg-devel mailing list