summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-04-26 10:47:31 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-04-26 10:59:45 +0200
commitc4bf74022562036bac3f53f4d5b8b1787d904c24 (patch)
treecd4fe28c3ddd2c5a33bf92e470a7c40ddbe7b76a
parent05f4c0506198548c2e93e2029763008383ab48ca (diff)
parentc2cb01d418dd18e1cf997c038d37378d773121be (diff)
Merge commit 'c2cb01d418dd18e1cf997c038d37378d773121be'
* 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>
-rw-r--r--libavformat/avformat.h17
-rw-r--r--libavformat/ffmenc.c1
-rw-r--r--libavformat/framecrcenc.c3
-rw-r--r--libavformat/md5enc.c3
-rw-r--r--libavformat/mux.c71
-rw-r--r--libavformat/oggenc.c1
6 files changed, 70 insertions, 26 deletions
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 80d693a113..d26964a165 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -366,6 +366,11 @@ typedef struct AVProbeData {
/**< 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 */
@@ -1259,6 +1264,18 @@ 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.
diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index 522945ec58..eb809eb64c 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -277,4 +277,5 @@ AVOutputFormat ff_ffm_muxer = {
.write_header = ffm_write_header,
.write_packet = ffm_write_packet,
.write_trailer = ffm_write_trailer,
+ .flags = AVFMT_TS_NEGATIVE,
};
diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
index df0ae79330..f63113b06e 100644
--- a/libavformat/framecrcenc.c
+++ b/libavformat/framecrcenc.c
@@ -56,5 +56,6 @@ AVOutputFormat ff_framecrc_muxer = {
.video_codec = AV_CODEC_ID_RAWVIDEO,
.write_header = ff_framehash_write_header,
.write_packet = framecrc_write_packet,
- .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
+ .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+ AVFMT_TS_NEGATIVE,
};
diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
index 050efb1513..d5c1fdd987 100644
--- a/libavformat/md5enc.c
+++ b/libavformat/md5enc.c
@@ -125,6 +125,7 @@ AVOutputFormat ff_framemd5_muxer = {
.write_header = framemd5_write_header,
.write_packet = framemd5_write_packet,
.write_trailer = framemd5_write_trailer,
- .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
+ .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+ AVFMT_TS_NEGATIVE,
};
#endif
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 1153ab69a8..1529eec468 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -485,12 +485,52 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
}
/**
- * 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;
+ 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;
+ }
did_split = av_packet_split_side_data(pkt);
ret = s->oformat->write_packet(s, pkt);
@@ -522,7 +562,7 @@ 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;
@@ -679,23 +719,6 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
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);
@@ -752,7 +775,7 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
if (ret <= 0) //FIXME cleanup needed for ret<0 ?
return ret;
- ret = split_write_packet(s, &opkt);
+ ret = write_packet(s, &opkt);
if (ret >= 0)
s->streams[opkt.stream_index]->nb_frames++;
@@ -778,7 +801,7 @@ int av_write_trailer(AVFormatContext *s)
if (!ret)
break;
- ret = split_write_packet(s, &pkt);
+ ret = write_packet(s, &pkt);
if (ret >= 0)
s->streams[pkt.stream_index]->nb_frames++;
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index 9a815d14a2..1255364259 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -632,5 +632,6 @@ AVOutputFormat ff_ogg_muxer = {
.write_header = ogg_write_header,
.write_packet = ogg_write_packet,
.write_trailer = ogg_write_trailer,
+ .flags = AVFMT_TS_NEGATIVE,
.priv_class = &ogg_muxer_class,
};