diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-04-26 10:47:31 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-04-26 10:59:45 +0200 |
commit | c4bf74022562036bac3f53f4d5b8b1787d904c24 (patch) | |
tree | cd4fe28c3ddd2c5a33bf92e470a7c40ddbe7b76a /libavformat | |
parent | 05f4c0506198548c2e93e2029763008383ab48ca (diff) | |
parent | c2cb01d418dd18e1cf997c038d37378d773121be (diff) | |
download | ffmpeg-c4bf74022562036bac3f53f4d5b8b1787d904c24.tar.gz |
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>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/avformat.h | 17 | ||||
-rw-r--r-- | libavformat/ffmenc.c | 1 | ||||
-rw-r--r-- | libavformat/framecrcenc.c | 3 | ||||
-rw-r--r-- | libavformat/md5enc.c | 3 | ||||
-rw-r--r-- | libavformat/mux.c | 71 | ||||
-rw-r--r-- | libavformat/oggenc.c | 1 |
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, }; |