【FFmpeg】AVOutputFormat/AVInputFormat 成员变量 flags 总结

1、分类

AVOutputFormat中flags允许的值:
AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_NOTIMESTAMPS,
AVFMT_GLOBALHEADER,AVFMT_VARIABLE_FPS,
AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH,
AVFMT_TS_NONSTRICT, AVFMT_TS_NEGATIVE

AVInputFormat中flags允许的值:
AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_NOTIMESTAMPS,
AVFMT_SHOW_IDS, AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT,
AVFMT_NOBINSEARCH, AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK,
AVFMT_SEEK_TO_PTS

2、对 flags 赋值,以封装成hls为例

在 FFmpeg-n4.2.2/libavformat/hlsenc.c 中

AVOutputFormat ff_hls_muxer = {
	...
	//      调用者不用打开文件 | 全局头信息 | 允许缓冲 | 不需要宽高信息
    .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_NODIMENSIONS,	
	...
}
3、使用 AVFMT_NOFILE

以 FFmpeg-n4.2.2/doc/examples/muxing.c 为例,如果输出格式不是 AVFMT_NOFILE 类型,需要使用 avio_open 来 创建并初始化一个AVIOContext来访问filename。

if (!(fmt->flags & AVFMT_NOFILE)) {
    ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
}
4、关于 AVFMT_NOFILE 的说明

1> AVFormatContext中AVIOContext *pb 的使用

在 FFmpeg-n4.2.2/libavformat/avformat.h 中有如下说明:
如果 flags 设置了 AVFMT_NOFILE 就不要给 pb 赋值。在这种情况下,封装、解封装将使用其它方式操作IO,这个字段应该设置为空

2> AVFormatContext中AVIOInterruptCB interrupt_callback的使用
设置为AVFMT_NOFILE类型的编解码,如果遇到阻塞无响应,可以使用 interrupt_callback来解决。
参见博客FFmpeg 长时间无响应的解决方法

3> avdevice
在 FFmpeg-n4.2.2/libavdevice/avdevice.h 中也有 AVFMT_NOFILE 相关的说明:大致意思是,libavdevice中的(de)muxer都属于 AVFMT_NOFILE 类型(它们使用自己的I/O函数),不需要用户操作。

5、使用 AVFMT_GLOBALHEADER

以 FFmpeg-n4.2.2/doc/examples/muxing.c 为例

if (oc->oformat->flags & AVFMT_GLOBALHEADER)
	c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;	

以h.264为例:设置了AV_CODEC_FLAG_GLOBAL_HEADER,
1>会在 AVCodecContext::extradata 中放置全局标头,而不是放到每个关键帧里;
2>会将 x4->params.b_repeat_headers 赋值为 0;

6、使用 AVFMT_ALLOW_FLUSH

在 FFmpeg-n4.2.2/libavformat/mux.c 中

int av_write_frame(AVFormatContext *s, AVPacket *pkt)
{...
    if (!pkt) {
        if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
            ret = s->oformat->write_packet(s, NULL);
            flush_if_needed(s);
            if (ret >= 0 && s->pb && s->pb->error < 0)
                ret = s->pb->error;
            return ret;
        }
        return 1;
    }
...
}

如果设置了 AVFMT_ALLOW_FLUSH 标志,在执行向输出写数据时write_packet
pkt可以为空,以便刷新muxer中缓冲的数据。
在刷新时,如果仍有更多数据要刷新,则返回0;如果所有数据都已刷新,且没有更多的缓冲数据,则返回1。

7、flags 可取值见如下列表
#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 */

你可能感兴趣的:(视频)