diff options
author | Luca Barbato <lu_zero@gentoo.org> | 2013-04-03 14:11:10 +0200 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2013-04-25 10:13:27 +0200 |
commit | c2cb01d418dd18e1cf997c038d37378d773121be (patch) | |
tree | 4a9a581316f6a1f9cba7de6460319224601d21f3 /libavformat/mux.c | |
parent | fc18cc44ebfae07da153dc782572e7ce2f6fe47d (diff) | |
download | ffmpeg-c2cb01d418dd18e1cf997c038d37378d773121be.tar.gz |
lavf: introduce AVFMT_TS_NEGATIVE
Most formats do not support negative timestamps, shift them to avoid
unexpected behaviour and a number of bad crashes.
CC:libav-stable@libav.org
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
Diffstat (limited to 'libavformat/mux.c')
-rw-r--r-- | libavformat/mux.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/libavformat/mux.c b/libavformat/mux.c index 76b0fb4dc6..0b537b8c1f 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -391,6 +391,34 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) return 0; } +/* + * 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 int write_packet(AVFormatContext *s, AVPacket *pkt) +{ + if (!(s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS))) { + 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); +} + int av_write_frame(AVFormatContext *s, AVPacket *pkt) { int ret; @@ -406,7 +434,7 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt) if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) return ret; - ret = s->oformat->write_packet(s, pkt); + ret = write_packet(s, pkt); if (ret >= 0) s->streams[pkt->stream_index]->nb_frames++; @@ -544,7 +572,7 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) if (ret <= 0) //FIXME cleanup needed for ret<0 ? return ret; - ret = s->oformat->write_packet(s, &opkt); + ret = write_packet(s, &opkt); if (ret >= 0) s->streams[opkt.stream_index]->nb_frames++; @@ -568,7 +596,7 @@ int av_write_trailer(AVFormatContext *s) if (!ret) break; - ret = s->oformat->write_packet(s, &pkt); + ret = write_packet(s, &pkt); if (ret >= 0) s->streams[pkt.stream_index]->nb_frames++; |