X-Git-Url: https://git.piment-noir.org/?p=deb_ffmpeg.git;a=blobdiff_plain;f=ffmpeg%2Flibavformat%2Fmux.c;h=023832c3360e6de3aafafb089b718fdee23c753a;hp=55add43ebb8da5bd1971047ff6c6a8ca988ba332;hb=f6fa7814ccfe3e76514b36cf04f5cd3cb657c8cf;hpb=2ba45a602cbfa7b771effba9b11bb4245c21bc00 diff --git a/ffmpeg/libavformat/mux.c b/ffmpeg/libavformat/mux.c index 55add43..023832c 100644 --- a/ffmpeg/libavformat/mux.c +++ b/ffmpeg/libavformat/mux.c @@ -171,16 +171,6 @@ error: return ret; } -#if FF_API_ALLOC_OUTPUT_CONTEXT -AVFormatContext *avformat_alloc_output_context(const char *format, - AVOutputFormat *oformat, const char *filename) -{ - AVFormatContext *avctx; - int ret = avformat_alloc_output_context2(&avctx, oformat, format, filename); - return ret < 0 ? NULL : avctx; -} -#endif - static int validate_codec_tag(AVFormatContext *s, AVStream *st) { const AVCodecTag *avctag; @@ -209,7 +199,7 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st) } if (id != AV_CODEC_ID_NONE) return 0; - if (tag >= 0 && (st->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL)) + if (tag >= 0 && (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL)) return 0; return 1; } @@ -429,10 +419,11 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) return ret; if (s->avoid_negative_ts < 0) { + av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO); if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) { s->avoid_negative_ts = 0; } else - s->avoid_negative_ts = 1; + s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE; } return 0; @@ -465,7 +456,7 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) /* duration field */ if (pkt->duration == 0) { - ff_compute_frame_duration(&num, &den, st, NULL, pkt); + ff_compute_frame_duration(s, &num, &den, st, NULL, pkt); if (den && num) { pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num); } @@ -506,8 +497,10 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) return AVERROR(EINVAL); } if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts) { - av_log(s, AV_LOG_ERROR, "pts (%s) < dts (%s) in stream %d\n", - av_ts2str(pkt->pts), av_ts2str(pkt->dts), st->index); + av_log(s, AV_LOG_ERROR, + "pts (%s) < dts (%s) in stream %d\n", + av_ts2str(pkt->pts), av_ts2str(pkt->dts), + st->index); return AVERROR(EINVAL); } @@ -564,12 +557,13 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) AVStream *st = s->streams[pkt->stream_index]; int64_t offset = st->mux_ts_offset; - if ((pkt->dts < 0 || s->avoid_negative_ts == 2) && pkt->dts != AV_NOPTS_VALUE && !s->offset) { + if (s->offset == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && + (pkt->dts < 0 || s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)) { s->offset = -pkt->dts; s->offset_timebase = st->time_base; } - if (s->offset && !offset) { + if (s->offset != AV_NOPTS_VALUE && !offset) { offset = st->mux_ts_offset = av_rescale_q_rnd(s->offset, s->offset_timebase, @@ -582,7 +576,16 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) if (pkt->pts != AV_NOPTS_VALUE) pkt->pts += offset; - av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0); + av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0 || s->max_interleave_delta > 0); + if (pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) { + av_log(s, AV_LOG_WARNING, + "Packets poorly interleaved, failed to avoid negative " + "timestamp %s in stream %d.\n" + "Try -max_interleave_delta 0 as a possible workaround.\n", + av_ts2str(pkt->dts), + pkt->stream_index + ); + } } did_split = av_packet_split_side_data(pkt); @@ -923,7 +926,7 @@ int av_write_trailer(AVFormatContext *s) for (;; ) { AVPacket pkt; ret = interleave_packet(s, &pkt, NULL, 1); - if (ret < 0) //FIXME cleanup needed for ret<0 ? + if (ret < 0) goto fail; if (!ret) break; @@ -940,10 +943,14 @@ int av_write_trailer(AVFormatContext *s) goto fail; } +fail: if (s->oformat->write_trailer) + if (ret >= 0) { ret = s->oformat->write_trailer(s); + } else { + s->oformat->write_trailer(s); + } -fail: if (s->pb) avio_flush(s->pb); if (ret == 0)