Browse code

lavf: Add support offset timestamps on muxing.

This allows avoiding negative timestamps.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2012/09/26 22:55:16
Showing 4 changed files
... ...
@@ -832,6 +832,13 @@ typedef struct AVStream {
832 832
      * its lifetime differs from info which is why its not in that structure.
833 833
      */
834 834
     int nb_decoded_frames;
835
+
836
+    /**
837
+     * Timestamp offset added to timestamps before muxing
838
+     * NOT PART OF PUBLIC API
839
+     */
840
+    int64_t mux_ts_offset;
841
+
835 842
 } AVStream;
836 843
 
837 844
 #define AV_PROGRAM_RUNNING 1
... ...
@@ -1111,6 +1118,17 @@ typedef struct AVFormatContext {
1111 1111
      */
1112 1112
     int use_wallclock_as_timestamps;
1113 1113
 
1114
+    /**
1115
+     * Avoids negative timestamps during muxing
1116
+     *  0 -> allow negative timestamps
1117
+     *  1 -> avoid negative timestamps
1118
+     * -1 -> choose automatically (default)
1119
+     * Note, this is only works when interleave_packet_per_dts is in use
1120
+     * - encoding: Set by user via AVOptions (NO direct access)
1121
+     * - decoding: unused
1122
+     */
1123
+    int avoid_negative_ts;
1124
+
1114 1125
     /*****************************************************************
1115 1126
      * All fields below this line are not part of the public API. They
1116 1127
      * may not be used outside of libavformat and can be changed and
... ...
@@ -71,6 +71,7 @@ static const AVOption options[]={
71 71
 {"compliant",  "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, D, "err_detect"},
72 72
 {"aggressive", "consider things that a sane encoder shouldnt do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"},
73 73
 {"use_wallclock_as_timestamps", "use wallclock as timestamps", OFFSET(use_wallclock_as_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D},
74
+{"avoid_negative_ts", "avoid negative timestamps", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E},
74 75
 {NULL},
75 76
 };
76 77
 
... ...
@@ -3699,16 +3699,36 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
3699 3699
         }
3700 3700
     }
3701 3701
     if(stream_count && flush){
3702
+        AVStream *st;
3702 3703
         pktl= s->packet_buffer;
3703 3704
         *out= pktl->pkt;
3705
+        st = s->streams[out->stream_index];
3704 3706
 
3705 3707
         s->packet_buffer= pktl->next;
3706 3708
         if(!s->packet_buffer)
3707 3709
             s->packet_buffer_end= NULL;
3708 3710
 
3709
-        if(s->streams[out->stream_index]->last_in_packet_buffer == pktl)
3710
-            s->streams[out->stream_index]->last_in_packet_buffer= NULL;
3711
+        if(st->last_in_packet_buffer == pktl)
3712
+            st->last_in_packet_buffer= NULL;
3711 3713
         av_freep(&pktl);
3714
+
3715
+        if (s->avoid_negative_ts > 0) {
3716
+            if (out->dts != AV_NOPTS_VALUE) {
3717
+                if (!st->mux_ts_offset && out->dts < 0) {
3718
+                    for(i=0; i < s->nb_streams; i++) {
3719
+                        s->streams[i]->mux_ts_offset =
3720
+                            av_rescale_q_rnd(-out->dts,
3721
+                                             st->time_base,
3722
+                                             s->streams[i]->time_base,
3723
+                                             AV_ROUND_UP);
3724
+                    }
3725
+                }
3726
+                out->dts += st->mux_ts_offset;
3727
+            }
3728
+            if (out->pts != AV_NOPTS_VALUE)
3729
+                out->pts += st->mux_ts_offset;
3730
+        }
3731
+
3712 3732
         return 1;
3713 3733
     }else{
3714 3734
         av_init_packet(out);
... ...
@@ -30,7 +30,7 @@
30 30
 #include "libavutil/avutil.h"
31 31
 
32 32
 #define LIBAVFORMAT_VERSION_MAJOR 54
33
-#define LIBAVFORMAT_VERSION_MINOR 28
33
+#define LIBAVFORMAT_VERSION_MINOR 29
34 34
 #define LIBAVFORMAT_VERSION_MICRO 101
35 35
 
36 36
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \