正文

struct InputStream 是单个输入流的管理器。是由 add_input_stream() 函数申请内存,以及赋值 InputStream 的各个字段的。

而 input_streams 数组是一个全局变量,包含了所有输入文件里面的所有输入流。

nputStream **input_streams = NULL;
int        nb_input_streams = 0;

你在二次开发 ffmpeg.exe 的时候,可以用 input_streams 全局变量来获取到所有的输入流

struct InputStream数据结构定义

typedef struct InputStream {
    int file_index;
    AVStream *st;
    int discard;             /* true if stream data should be discarded */
    int user_set_discard;
    int decoding_needed;     /* non zero if the packets must be decoded in 'raw_fifo', see DECODING_FOR_* */
#define DECODING_FOR_OST    1
#define DECODING_FOR_FILTER 2
    AVCodecContext *dec_ctx;
    const AVCodec *dec;
    AVFrame *decoded_frame;
    AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */
    AVPacket *pkt;
    int64_t       start;     /* time when read started */
    /* predicted dts of the next packet read for this stream or (when there are
     * several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */
    int64_t       next_dts;
    int64_t       dts;       ///< dts of the last packet read for this stream (in AV_TIME_BASE units)
    int64_t       next_pts;  ///< synthetic pts for the next decode frame (in AV_TIME_BASE units)
    int64_t       pts;       ///< current pts of the decoded frame  (in AV_TIME_BASE units)
    int           wrap_correction_done;
    int64_t filter_in_rescale_delta_last;
    int64_t min_pts; /* pts with the smallest value in a current stream */
    int64_t max_pts; /* pts with the higher value in a current stream */
    // when forcing constant input framerate through -r,
    // this contains the pts that will be given to the next decoded frame
    int64_t cfr_next_pts;
    int64_t nb_samples; /* number of samples in the last decoded audio frame before looping */
    double ts_scale;
    int saw_first_ts;
    AVDictionary *decoder_opts;
    AVRational framerate;               /* framerate forced with -r */
    int top_field_first;
    int guess_layout_max;
    int autorotate;
    ...省略字幕相关字段...
    int dr1;
    /* decoded data from this stream goes into all those filters
     * currently video and audio only */
    InputFilter **filters;
    int        nb_filters;
    int reinit_filters;
    /* hwaccel options */
    ...省略硬件解码相关字段...
    /* hwaccel context */
   ...省略硬件解码相关字段...
    /* stats */
    // combined size of all the packets read
    uint64_t data_size;
    /* number of packets successfully read for this stream */
    uint64_t nb_packets;
    // number of frames/samples retrieved from the decoder
    uint64_t frames_decoded;
    uint64_t samples_decoded;
    int64_t *dts_buffer;
    int nb_dts_buffer;
    int got_output;
} InputStream;

各个字段的解析

(省略了字幕相关的字段):

1, int file_indexinput_files 数组里面的下标,代表 InputStream 对应的 InputFile

2, AVStream *stAVFormatContext 里面的 AVStream 。

3, int discard,如果是 1 会丢弃读取到的 AVPacket,刚开始的时候都是 1。例如文件里面有多个视频流,会全部都把 discard 设置为 1,然后再从中选出质量最好的视频流,把它的 discard 设置为 0 。

或者当输出流需要这个输入流的时候,也会置为 0 ,如下:

if (source_index >= 0) {
    ost->sync_ist = input_streams[source_index];
    input_streams[source_index]->discard = 0;
    input_streams[source_index]->st->discard = input_streams[source_index]->user_set_discard;
}

因此,如果你用 ffmpeg.exe 对一个有多个视频流的文件进行转换,默认只会输出一个视频流。

4, int user_set_discard,命令行选项 -discard 的值,默认是 AVDISCARD_NONE,可选的值在 AVDiscard 枚举里面。

enum AVDiscard{
    /* We leave some space between them for extensions (drop some
     * keyframes for intra-only or drop just some bidir frames). */
    AVDISCARD_NONE    =-16, ///< discard nothing
    AVDISCARD_DEFAULT =  0, ///< discard useless packets like 0 size packets in avi
    AVDISCARD_NONREF  =  8, ///< discard all non reference
    AVDISCARD_BIDIR   = 16, ///< discard all bidirectional frames
    AVDISCARD_NONINTRA= 24, ///< discard all non intra frames
    AVDISCARD_NONKEY  = 32, ///< discard all frames except keyframes
    AVDISCARD_ALL     = 48, ///< discard all
};

5, int decoding_needed,大于 0 代表输入流需要进行解码操作,有两个值,DECODING_FOR_OST ,DECODING_FOR_FILTER

6, AVCodecContext *dec_ctx,解码器上下文/解码器实例,输入流的 AVPacket 会丢给解码实例进行解码。

7, const AVCodec *dec,解码器信息

8, AVFrame *decoded_frame,从解码器上下文 解码出来的 AVFrame

9, AVFrame *filter_frame,这个字段主要是用来增加引用计数的,可能在调用 av_buffersrc_add_frame_flags() 之后,AVFrame 的引用技术会减一,所以需要先复制一份引用,如下:

10, AVPacket *pkt,从 av_read_frame() 里面读出来的 AVPacket,只是复制了一下引用。

11, int64_t start,记录此流是什么时候开始处理的,主要是给 -re 选项使用的,模拟帧率速度,录制视频模拟直播用的。

12, int64_t next_dts,下一帧的 解码时间,这是通过计算得到的预估值,如果读取出来的 AVPacket 没有 dts ,会用这个值代替。

13, int64_t dts,最近一次从 av_read_frame() 读出来的 AVPacket 的 dts

14, int64_t next_pts,下一个 AVFrame 的 pts,通过当前 AVFrame 的 pts 加上 duration 计算出来的,应该是给一些没有 pts 值的 AVFrame 用的。

15, int64_t pts,最近一次从解码器里面解码出来的 AVFrame 的 pts,记录这个值主要是给 send_filter_eof() 用的,防止回滚。

15, int64_t wrap_correction_done,在一些流格式,例如 TS,会有时间戳环回的问题,int64 是有大小限制的,超过这个大小会环回,ffmpeg.exe 需要处理环回的逻辑。

16, int64_t filter_in_rescale_delta_last,专门给音频帧转换时间基用的,因为音频的连续性太强,如果有些许误差需要保存下来,在下次转换的时候进行补偿。

17, int64_t min_pts, 从 av_read_frame() 读出来的 AVPacket 的最小 pts ,不一定是第一帧的 pts,因为命令行参数通过 -ss 选项,指定从哪里开始处理。

18, int64_t max_pts,从 av_read_frame() 读出来的 AVPacket 的最大 pts ,不一定是最后一帧的 pts,因为命令行参数通过 -t 选项,指定只处理多久的时长。

19, int64_t cfr_next_pts,给 -r 选项用的。

20, int64_t nb_samples,记录的是最近一次解码出来的 AVFrame 里面的 nb_samples。用途我也不清楚,后面补充。

21, double ts_scale,默认值是 1.0,可通过命令行选项 -itsscale 进行改变,主要作用是将 pts ,dts 进行放大,放大的方法是乘以 ts_scale

22, int saw_first_ts,标记是不是已经读取到属于该流的第一个 AVPacket

23, AVDictionary *decoder_opts,从 OptionsContext 里面转移过来的解码器参数。

24, AVRational framerate,命令行选项 -r 的值。

25, int top_field_first,命令行选项 -top 的值,好像是给隔行扫描视频用的。

26, int guess_layout_max,命令行选项 -guess_layout_max 的值,猜测的最大的声道布局。

27, int autorotate,命令行选项 -autorotate 的值,是否插入纠正旋转的 filter 滤镜,有些视频的画面中途会上下旋转,设置这个选项可以自动纠正旋转,不会上下颠倒。

28, int dr1,用 Find Useage 找不到使用这个字段的代码,所以是没用的字段。

29, InputFilter **filters 跟 int nb_filters,输入流绑定的 入口滤镜,可以是绑定多个入口滤镜的,输入流解码出来的 AVFrame 会往多个入口滤镜发送。

30, int reinit_filters,命令行选项 -reinit_filter 的值,0 代表输入信息如果产生变化也不重新初始化 FilterGraph,输入信息产生变化是指 解码出来的 AVFrame 的宽高中途变大或者变小之类的。reinit_filters 默认是 -1,就是会重新初始化 FilterGraph

下面这些都是统计相关的字段。

31, uint64_t data_size,从 av_read_frame() 读出来的 AVPacket 的 size 的总和。也就是统计当前流一共读出出来了多少字节的数据。

32, uint64_t nb_packets,从 av_read_frame() 读出来的 AVPacket 数量的总和。

33, uint64_t frames_decodeduint64_t samples_decoded,从解码器解码出来的 AVFrame 的数量。

34, int64_t *dts_bufferint nb_dts_buffer,我没看懂这两个字段干什么的,可能是旧代码没有删除。

35, int got_output,只要解码器已经解码出一帧 AVFrame,这个字段就会置为 1。

以上就是InputStream数据结构示例解析的详细内容,更多关于InputStream 数据结构的资料请关注Devmax其它相关文章!

InputStream数据结构示例解析的更多相关文章

  1. swift篇第一期:简单的数据结构

    首先我们可以去使用Playground来编码,并且会实时的显示对应的编码信息,这样我们就不用每次都去运行程序来显示输出的东西了哦,也方便了我们对某些语句的验证,这个是比较赞的var与let前者为可变修饰符,后者为不可变从字面意思我们就可以很好的区分了常用的类型呢,跟其他语言基本相同啦,主要有几种:1.int类型2.Float,Double类型3.String类型4.Boolean类型当我们去声明一

  2. Swift 集合数据结构性能分析

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  3. Swift中的集合类数据结构

    在那种情况下,你将会需要一种基本的集合类数据结构。继续学习,你将会比较成熟的Cocoa数据结构与对应的纯Swift结构的性能。常见iOS数据结构iOS中三种最常用的数据结构是arrays,dictionaries和sets。除了在Swift和Objective-C中旧的Foundation框架中的数据结构,现在又有了新的仅支持Swift版本的数据结构与语言紧密结合在一起。Swift数组是同质的,意味着每一个Swift数组都只包含一种类型的对象。

  4. 11.Swift 中的类和结构体

    举例来说,以下情境中适合使用结构体:1.几何形状的大小,封装一个width属性和height属性,两者均为Double类型。这次就讲到这里,下次我们继续

  5. a place you can learn algorithms and data structures(算法和数据结构) in swift

    https://github.com/raywenderlich/swift-algorithm-club

  6. Swift3.0 类和结构体的选择

    结构体实例总是通过值传递,类实例总是通过引用传递先说说值类型和引用类型的区别值类型被赋予给一个变量、常量或者被传递给一个函数的时候,其值会被拷贝在Swift中,所有的结构体和枚举类型都是值类型。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体”Swift中,许多基本类型,诸如String,Array和Dictionary类型均以结构体的形式实现。Objective-C中Nsstring,NSArray和NSDictionary类型均以类的形式实现,而并非结构体。

  7. 【Swift】结构体和类

    Swift中结构体和类有很多共同点与结构体相比,类还有如下的附加功能:结构体和枚举是值类型值类型被赋予给一个变量、常量或者被传递给一个函数的时候,其值会被拷贝。为了达到这个目的,Swift内建了两个恒等运算符:类和结构体的选择在你的代码中,你可以使用类和结构体来定义你的自定义数据类型。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。Swift中,许多基本类型,诸如String,Array和Dictionary类型均以结构体的形式实现。

  8. 如何在Swift中创建打包数据结构?

    我正在将一个项目从Objective-C转换为Swift,我正在使用一个打包的结构来输入通过套接字发送的转换二进制消息:我不确定Swift中最好的方法是什么,我能得到的最接近的近似值是:翻译中丢失了两个重要的细节:没有保证整数类型的比特,并且没有结构打包.我不认为这可以在Swift中表达,但如果是这样,怎么样?

  9. android – 如何正确删除保留的实例片段

    解决方法正如@Luksprog所建议的,以下方法有效.但是,它仍然无法解释为什么通过onDetach完成的先前清理不起作用.如果有人能解释为什么这个解决方案有效,而以前没有,我会非常感激.版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  10. android – 数组适配器notifyDataSetChanged()将无法正常工作

    .有任何想法吗?

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部