Merge commit 'c2cb01d418dd18e1cf997c038d37378d773121be'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 26 Apr 2013 08:47:31 +0000 (10:47 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 26 Apr 2013 08:59:45 +0000 (10:59 +0200)
* commit 'c2cb01d418dd18e1cf997c038d37378d773121be':
  lavf: introduce AVFMT_TS_NEGATIVE

Conflicts:
libavformat/avformat.h
libavformat/mux.c
tests/ref/lavf/asf
tests/ref/lavf/mkv
tests/ref/lavf/mpg
tests/ref/lavf/ts
tests/ref/seek/lavf-asf
tests/ref/seek/lavf-mkv
tests/ref/seek/lavf-mpg
tests/ref/seek/lavf-ts

This commit does not change the default ts behaviour, such
change will, if its done, be done separately.

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/avformat.h
libavformat/ffmenc.c
libavformat/framecrcenc.c
libavformat/md5enc.c
libavformat/mux.c
libavformat/oggenc.c

@@@ -358,17 -357,15 +358,22 @@@ typedef struct AVProbeData 
  #define AVFMT_NOGENSEARCH   0x4000 /**< Format does not allow to fallback to generic search */
  #define AVFMT_NO_BYTE_SEEK  0x8000 /**< Format does not allow seeking by bytes */
  #define AVFMT_ALLOW_FLUSH  0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
 -#define AVFMT_TS_NONSTRICT 0x20000 /**< Format does not require strictly
 +#if LIBAVFORMAT_VERSION_MAJOR <= 54
 +#define AVFMT_TS_NONSTRICT 0x8020000 //we try to be compatible to the ABIs of ffmpeg and major forks
 +#else
 +#define AVFMT_TS_NONSTRICT 0x20000
 +#endif
 +                                   /**< Format does not require strictly
                                          increasing timestamps, but they must
                                          still be monotonic */
+ #define AVFMT_TS_NEGATIVE  0x40000 /**< Format allows muxing negative
+                                         timestamps. If not set the timestamp
+                                         will be shifted in av_write_frame and
+                                         av_interleaved_write_frame so they
+                                         start from 0. */
  
 +#define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
 +
  /**
   * @addtogroup lavf_encoding
   * @{
@@@ -1259,21 -1028,18 +1264,33 @@@ typedef struct AVFormatContext 
      int raw_packet_buffer_remaining_size;
  
      /**
+      * Offset to remap timestamps to be non-negative.
+      * Expressed in timebase units.
++     * @see AVStream.mux_ts_offset
+      */
+     int64_t offset;
+     /**
+      * Timebase for the timestamp offset.
+      */
+     AVRational offset_timebase;
++    /**
 +     * IO repositioned flag.
 +     * This is set by avformat when the underlaying IO context read pointer
 +     * is repositioned, for example when doing byte based seeking.
 +     * Demuxers can use the flag to detect such changes.
 +     */
 +    int io_repositioned;
  } AVFormatContext;
  
 +/**
 + * Returns the method used to set ctx->duration.
 + *
 + * @return AVFMT_DURATION_FROM_PTS, AVFMT_DURATION_FROM_STREAM, or AVFMT_DURATION_FROM_BITRATE.
 + */
 +enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx);
 +
  typedef struct AVPacketList {
      AVPacket pkt;
      struct AVPacketList *next;
Simple merge
Simple merge
Simple merge
@@@ -484,21 -391,32 +484,61 @@@ static int compute_pkt_fields2(AVFormat
      return 0;
  }
  
 -/*
 +/**
-  * Move side data from payload to internal struct, call muxer, and restore
-  * original packet.
++ * Make timestamps non negative, move side data from payload to internal struct, call muxer, and restore
++ * sidedata.
++ *
+  * FIXME: this function should NEVER get undefined pts/dts beside when the
+  * AVFMT_NOTIMESTAMPS is set.
+  * Those additional safety checks should be dropped once the correct checks
+  * are set in the callers.
   */
- static inline int split_write_packet(AVFormatContext *s, AVPacket *pkt)
 -
+ static int write_packet(AVFormatContext *s, AVPacket *pkt)
  {
-     int ret, did_split;
 -    if (!(s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS))) {
++    int ret, did_split, i;
++
++    if (s->avoid_negative_ts > 0) {
++        AVStream *st = s->streams[pkt->stream_index];
++        if (pkt->dts != AV_NOPTS_VALUE) {
++            if (!st->mux_ts_offset && pkt->dts < 0) {
++                for (i = 0; i < s->nb_streams; i++) {
++                    s->streams[i]->mux_ts_offset =
++                        av_rescale_q_rnd(-pkt->dts,
++                                            st->time_base,
++                                            s->streams[i]->time_base,
++                                            AV_ROUND_UP);
++                }
++            }
++            pkt->dts += st->mux_ts_offset;
++        }
++        if (pkt->pts != AV_NOPTS_VALUE)
++            pkt->pts += st->mux_ts_offset;
++    }
++
++    if (!(s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) && 0) {
+         AVRational time_base = s->streams[pkt->stream_index]->time_base;
+         int64_t offset = 0;
+         if (!s->offset && pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) {
+             s->offset = -pkt->dts;
+             s->offset_timebase = time_base;
+         }
+         if (s->offset)
+             offset = av_rescale_q(s->offset, s->offset_timebase, time_base);
+         if (pkt->dts != AV_NOPTS_VALUE)
+             pkt->dts += offset;
+         if (pkt->pts != AV_NOPTS_VALUE)
+             pkt->pts += offset;
+     }
 -    return s->oformat->write_packet(s, pkt);
 +
 +    did_split = av_packet_split_side_data(pkt);
 +    ret = s->oformat->write_packet(s, pkt);
 +    if (s->flush_packets && s->pb && s->pb->error >= 0)
 +        avio_flush(s->pb);
 +    if (did_split)
 +        av_packet_merge_side_data(pkt);
 +    return ret;
  }
  
  int av_write_frame(AVFormatContext *s, AVPacket *pkt)
      if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
          return ret;
  
-     ret = split_write_packet(s, pkt);
+     ret = write_packet(s, pkt);
 +    if (ret >= 0 && s->pb && s->pb->error < 0)
 +        ret = s->pb->error;
  
      if (ret >= 0)
          s->streams[pkt->stream_index]->nb_frames++;
@@@ -675,27 -513,9 +715,10 @@@ int ff_interleave_packet_per_dts(AVForm
          if (!s->packet_buffer)
              s->packet_buffer_end = NULL;
  
 -        if (s->streams[out->stream_index]->last_in_packet_buffer == pktl)
 -            s->streams[out->stream_index]->last_in_packet_buffer = NULL;
 +        if (st->last_in_packet_buffer == pktl)
 +            st->last_in_packet_buffer = NULL;
          av_freep(&pktl);
-         if (s->avoid_negative_ts > 0) {
-             if (out->dts != AV_NOPTS_VALUE) {
-                 if (!st->mux_ts_offset && out->dts < 0) {
-                     for (i = 0; i < s->nb_streams; i++) {
-                         s->streams[i]->mux_ts_offset =
-                             av_rescale_q_rnd(-out->dts,
-                                              st->time_base,
-                                              s->streams[i]->time_base,
-                                              AV_ROUND_UP);
-                     }
-                 }
-                 out->dts += st->mux_ts_offset;
-             }
-             if (out->pts != AV_NOPTS_VALUE)
-                 out->pts += st->mux_ts_offset;
-         }
 +
          return 1;
      } else {
          av_init_packet(out);
Simple merge