FFMPEG将MP4转HLS DTS不严格递增 解决之法

问题

    在用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);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老中医的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值