问题
在用ffmpeg将mp4转封装为hls切片时,出现以下报错:
[mp4 @ 0x13460f8e0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 276134871 >= 276134871
[libx264 @ 0x134610380] frame I:1 Avg QP:18.04 size: 64315
[libx264 @ 0x134610380] frame P:61 Avg QP:17.81 size: 3377
[libx264 @ 0x134610380] frame B:149 Avg QP:15.74 size: 291
[libx264 @ 0x134610380] consecutive B-frames: 3.8% 4.7% 4.3% 87.2%
[libx264 @ 0x134610380] mb I I16..4: 32.4% 42.0% 25.6%
[libx264 @ 0x134610380] mb P I16..4: 2.2% 4.3% 0.8% P16..4: 3.4% 0.3% 0.4% 0.0% 0.0% skip:88.5%
[libx264 @ 0x134610380] mb B I16..4: 0.4% 0.2% 0.0% B16..8: 4.1% 0.0% 0.0% direct: 0.1% skip:95.2% L0:56.1% L1:43.5% BI: 0.4%
[libx264 @ 0x134610380] 8x8 transform intra:52.4% inter:49.0%
[libx264 @ 0x134610380] coded y,uvDC,uvAC intra: 9.3% 4.0% 3.1% inter: 0.6% 0.3% 0.2%
[libx264 @ 0x134610380] i16 v,h,dc,p: 61% 36% 3% 0%
[libx264 @ 0x134610380] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 43% 17% 39% 0% 0% 0% 0% 0% 0%
[libx264 @ 0x134610380] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 38% 23% 19% 3% 3% 3% 3% 4% 3%
[libx264 @ 0x134610380] i8c dc,h,v,p: 91% 6% 3% 0%
[libx264 @ 0x134610380] Weighted P-Frames: Y:3.3% UV:0.0%
[libx264 @ 0x134610380] ref P L0: 56.7% 34.0% 7.1% 2.1% 0.1%
[libx264 @ 0x134610380] ref B L0: 50.3% 47.7% 2.1%
[libx264 @ 0x134610380] ref B L1: 98.8% 1.2%
[libx264 @ 0x134610380] kb/s:255.32
Error occurred: Invalid argument
分析
查看ffmpeg相关代码,打印出现在libavformat模块 mux.c文件中:
关键代码:
if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE &&
((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE &&
st->codecpar->codec_type != AVMEDIA_TYPE_DATA &&
st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
av_log(s, AV_LOG_ERROR,
"Application provided invalid, non monotonically increasing dts to muxer in stream %d: %s >= %s\n",
st->index, av_ts2str(st->cur_dts), av_ts2str(pkt->dts));
//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);
return AVERROR(EINVAL);
}
这里主要有3个判断条件:
1)st->cur_dts != 0
2)st->cur_dts != AV_NOPTS_VALUE
3)((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE &&
st->codecpar->codec_type != AVMEDIA_TYPE_DATA &&
st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)
AVFormatContext => AVOutputFormat => flags有以下值:
/// Demuxer will use avio_open, no opened file should be provided by the caller.
#define AVFMT_NOFILE 0x0001
#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */
#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */
#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */
#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */
#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */
#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. Note, muxers always require valid (monotone) timestamps */
#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */
#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */
#define AVFMT_NOSTREAMS 0x1000 /**< Format does not require any streams */
#define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fall back on binary search via read_timestamp */
#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fall back on generic search */
#define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */
#define AVFMT_ALLOW_FLUSH 0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
#define AVFMT_TS_NONSTRICT 0x20000 /**< 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.
The user or muxer can override this through
AVFormatContext.avoid_negative_ts
*/
#define AVFMT_SEEK_TO_PTS 0x4000000 /**< Seeking is based on PTS */
可以看到第3个条件要满足的话,要么AVFMT_TS_NONSTRICT未设置,要么st->cur_dts > pkt->dts,dts需严格递增,也即 >,而非>=
解决
1)设置 AVFormatContext => AVOutputFormat => flags:
ofmt_ctx->oformat->flags |= AVFMT_TS_NONSTRICT;
2)或,忽略以下逻辑判断,只打印日志:
if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE &&
((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE &&
st->codecpar->codec_type != AVMEDIA_TYPE_DATA &&
st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
av_log(s, AV_LOG_ERROR,
"Application provided invalid, non monotonically increasing dts to muxer in stream %d: %s >= %s\n",
st->index, av_ts2str(st->cur_dts), av_ts2str(pkt->dts));
//return AVERROR(EINVAL);
}