Merge commit 'c94e2e85cb6af8a570d8542a830556243bd32873'
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 28 May 2014 23:09:51 +0000 (01:09 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 28 May 2014 23:13:59 +0000 (01:13 +0200)
* commit 'c94e2e85cb6af8a570d8542a830556243bd32873':
  nut: Support experimental NUT 4 features

Conflicts:
doc/nut.texi
libavformat/nut.h
libavformat/nutdec.c
libavformat/nutenc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
doc/muxers.texi
doc/nut.texi
libavformat/nut.h
libavformat/nutdec.c
libavformat/nutenc.c

diff --cc doc/muxers.texi
@@@ -703,9 -441,26 +703,26 @@@ syntax
  
  Alternatively you can write the command as:
  @example
 -avconv -benchmark -i INPUT -f null -
 +ffmpeg -benchmark -i INPUT -f null -
  @end example
  
 -avconv -i INPUT -f_strict experimental -syncpoints none - | processor
+ @section nut
+ @table @option
+ @item -syncpoints @var{flags}
+ Change the syncpoint usage in nut:
+ @table @option
+ @item @var{default} use the normal low-overhead seeking aids.
+ @item @var{none} do not use the syncpoints at all, reducing the overhead but making the stream non-seekable;
+ @item @var{timestamped} extend the syncpoint with a wallclock field.
+ @end table
+ The @var{none} and @var{timestamped} flags are experimental.
+ @end table
+ @example
++ffmpeg -i INPUT -f_strict experimental -syncpoints none - | processor
+ @end example
  @section ogg
  
  Ogg container muxer.
diff --cc doc/nut.texi
@@@ -17,10 -17,27 +17,31 @@@ subtitle and user-defined streams in a 
  It was created by a group of FFmpeg and MPlayer developers in 2003
  and was finalized in 2008.
  
 +The official nut specification is at svn://svn.mplayerhq.hu/nut
 +In case of any differences between this text and the official specification,
 +the official specification shall prevail.
 +
+ @chapter Modes
+ NUT has some variants signaled by using the flags field in its main header.
+ @multitable @columnfractions .4 .4
+ @item BROADCAST   @tab Extend the syncpoint to report the sender wallclock
+ @item PIPE        @tab Omit completely the syncpoint
+ @end multitable
+ @section BROADCAST
+ The BROADCAST variant provides a secondary time reference to facilitate
+ detecting endpoint latency and network delays.
+ It assumes all the endpoint clocks are syncronized.
+ To be used in real-time scenarios.
+ @section PIPE
+ The PIPE variant assumes NUT is used as non-seekable intermediate container,
+ by not using syncpoint removes unneeded overhead and reduces the overall
+ memory usage.
  @chapter Container-specific codec tags
  
  @section Generic raw YUVA formats
@@@ -102,11 -103,10 +105,14 @@@ typedef struct NUTContext 
      int header_count;
      AVRational *time_base;
      struct AVTreeNode *syncpoints;
-     int version;
 +    int sp_count;
 +    int64_t max_pts;
 +    AVRational *max_pts_tb;
+ #define NUT_BROADCAST 1 // use extended syncpoints
+ #define NUT_PIPE 2      // do not write syncpoints
+     int flags;
+     int version; // version currently in use
 +    int minor_version;
  } NUTContext;
  
  extern const AVCodecTag ff_nut_subtitle_tags[];
@@@ -228,8 -213,8 +228,8 @@@ static int decode_main_header(NUTContex
      end  = get_packetheader(nut, bc, 1, MAIN_STARTCODE);
      end += avio_tell(bc);
  
 -    nut->version = ffio_read_varlen(bc);
 +    tmp = ffio_read_varlen(bc);
-     if (tmp < 2 && tmp > 4) {
+     if (tmp < NUT_MIN_VERSION && tmp > NUT_MAX_VERSION) {
          av_log(s, AV_LOG_ERROR, "Version %"PRId64" not supported.\n",
                 tmp);
          return AVERROR(ENOSYS);
              avio_read(bc, hdr, nut->header_len[i]);
              nut->header[i] = hdr;
          }
 -        assert(nut->header_len[0] == 0);
 +        av_assert0(nut->header_len[0] == 0);
      }
  
+     // flags had been effectively introduced in version 4
+     if (nut->version > NUT_STABLE_VERSION) {
+         nut->flags = ffio_read_varlen(bc);
+     }
      if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
          av_log(s, AV_LOG_ERROR, "main header checksum mismatch\n");
          return AVERROR_INVALIDDATA;
  #include "libavutil/mathematics.h"
  #include "libavutil/tree.h"
  #include "libavutil/dict.h"
 +#include "libavutil/avassert.h"
+ #include "libavutil/time.h"
+ #include "libavutil/opt.h"
 +#include "libavcodec/bytestream.h"
  #include "libavcodec/mpegaudiodata.h"
  #include "nut.h"
  #include "internal.h"
@@@ -338,9 -327,7 +340,9 @@@ static void write_mainheader(NUTContex
          tmp_head_idx;
      int64_t tmp_match;
  
-     ff_put_v(bc, nut->version = NUT_VERSION);
+     ff_put_v(bc, nut->version);
 +    if (nut->version > 3)
 +        ff_put_v(bc, nut->minor_version);
      ff_put_v(bc, nut->avf->nb_streams);
      ff_put_v(bc, nut->max_distance);
      ff_put_v(bc, nut->time_base_count);
@@@ -692,11 -648,22 +697,21 @@@ static int nut_write_header(AVFormatCon
  
      nut->avf = s;
  
 -    nut->stream = av_mallocz(sizeof(StreamContext) * s->nb_streams);
 -    if (s->nb_chapters)
 -        nut->chapter = av_mallocz(sizeof(ChapterContext) * s->nb_chapters);
 -    nut->time_base = av_mallocz(sizeof(AVRational) * (s->nb_streams +
 -                                                      s->nb_chapters));
 -    if (!nut->stream || (s->nb_chapters && !nut->chapter) || !nut->time_base) {
+     nut->version = NUT_STABLE_VERSION + !!nut->flags;
+     if (nut->flags && s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+         av_log(s, AV_LOG_ERROR,
+                "The additional syncpoint modes require version %d, "
+                "that is currently not finalized, "
+                "please set -f_strict experimental in order to enable it.\n",
+                nut->version);
+         return AVERROR_EXPERIMENTAL;
+     }
 +    nut->stream   = av_calloc(s->nb_streams,  sizeof(*nut->stream ));
 +    nut->chapter  = av_calloc(s->nb_chapters, sizeof(*nut->chapter));
 +    nut->time_base= av_calloc(s->nb_streams +
 +                              s->nb_chapters, sizeof(*nut->time_base));
 +    if (!nut->stream || !nut->chapter || !nut->time_base) {
          av_freep(&nut->stream);
          av_freep(&nut->chapter);
          av_freep(&nut->time_base);
@@@ -1110,7 -938,7 +1131,7 @@@ static int nut_write_packet(AVFormatCon
      nus->last_pts   = pkt->pts;
  
      //FIXME just store one per syncpoint
-     if (flags & FLAG_KEY) {
 -    if (flags & FLAG_KEY && !(nut->flags & NUT_PIPE))
++    if (flags & FLAG_KEY && !(nut->flags & NUT_PIPE)) {
          av_add_index_entry(
              s->streams[pkt->stream_index],
              nut->last_syncpoint_pos,