zoukankan      html  css  js  c++  java
  • FFmpeg 协议初步学习

    typedef struct URLContext {
        const AVClass *av_class;    /**< information for av_log(). Set by url_open(). */
        struct URLProtocol *prot;
        void *priv_data;
        char *filename;             /**< specified URL */
        int flags;
        int max_packet_size;        /**< if non zero, the stream is packetized with this max packet size */
        int is_streamed;            /**< true if streamed (no seek possible), default = false */
        int is_connected;
        AVIOInterruptCB interrupt_callback;
        int64_t rw_timeout;         /**< maximum time to wait for (network) read/write operation completion, in mcs */
    } URLContext;
    


    1、context 当前执行的上下文环境,事实上说白了就是C的全局变量,用来保存当前模块执行时的多个函数须要使用到的共同变量。每个模块里面都会有一个 context 来表示执行上下文,模块里面的详细实现都要使用到和其相应的 context 。file 协议是在 file.c 中实现的,里面有一个 FileContext, 和一个 AVClass file_class

    2、URLContext  中的 av_class 是它自身的 AVClass ffurl_context_class

    3、URLContext 中的 prot 是指向详细的协议的,URLProtocol 抽象出了一些接口,上层使用这些接口去操作数据,而在不同的协议里面实现了这些接口。打开的是一个文件协议的话,此时的 prot 就是指向 URLProtocol ff_file_protocol 


    4、URLContext  中的 priv_data,有点比較难理解,先理解一下 URLProtocol  再回来就比較easy理解一点

    typedef struct URLProtocol {
        const char *name;
        int     (*url_open)( URLContext *h, const char *url, int flags);
        /**
         * This callback is to be used by protocols which open further nested
         * protocols. options are then to be passed to ffurl_open()/ffurl_connect()
         * for those nested protocols.
         */
        int     (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);
    
        /**
         * Read data from the protocol.
         * If data is immediately available (even less than size), EOF is
         * reached or an error occurs (including EINTR), return immediately.
         * Otherwise:
         * In non-blocking mode, return AVERROR(EAGAIN) immediately.
         * In blocking mode, wait for data/EOF/error with a short timeout (0.1s),
         * and return AVERROR(EAGAIN) on timeout.
         * Checking interrupt_callback, looping on EINTR and EAGAIN and until
         * enough data has been read is left to the calling function; see
         * retry_transfer_wrapper in avio.c.
         */
        int     (*url_read)( URLContext *h, unsigned char *buf, int size);
        int     (*url_write)(URLContext *h, const unsigned char *buf, int size);
        int64_t (*url_seek)( URLContext *h, int64_t pos, int whence);
        int     (*url_close)(URLContext *h);
        struct URLProtocol *next;
        int (*url_read_pause)(URLContext *h, int pause);
        int64_t (*url_read_seek)(URLContext *h, int stream_index,
                                 int64_t timestamp, int flags);
        int (*url_get_file_handle)(URLContext *h);
        int (*url_get_multi_file_handle)(URLContext *h, int **handles,
                                         int *numhandles);
        int (*url_shutdown)(URLContext *h, int flags);
        int priv_data_size;
        const AVClass *priv_data_class;
        int flags;
        int (*url_check)(URLContext *h, int mask);
    } URLProtocol;



    5、URLProtocol  中的 priv_data_size 指的是当前详细实现的 context 的大小,在file协议中就是 FileContext 结构的大小

    6、URLProtocol 中的 priv_data_class 指的是当前详细实现的 AVClass,在file协议中就是指向 AVClass file_class

    URLProtocol ff_file_protocol = {
        .name                = "file",
        .url_open            = file_open,
        .url_read            = file_read,
        .url_write           = file_write,
        .url_seek            = file_seek,
        .url_close           = file_close,
        .url_get_file_handle = file_get_handle,
        .url_check           = file_check,
        .priv_data_size      = sizeof(FileContext),
        .priv_data_class     = &file_class,
    };
    



    7、file 协议的详细实现,实现了 URLProtocol  中的接口,而且里面的两个 priv 变量是指的是它自身的 FileContext 结构的大小和 AVClass file_class

    8、URLContext  中的 priv_data 指向的事实上是详细协议的 context,在file协议中就是分配的一个 FileContext,FileContext 中的 class 指向的自身的 AVClass ,也就是和 ff_file_protocol  中的 priv_data_class 指向的是同一个AVClass

    typedef struct FileContext {
        const AVClass *class;
        int fd;
        int trunc;
        int blocksize;
    } FileContext;



    9、AVClass 眼下还没有发现是干嘛用的,在file协议中好像是和一些设置參数有关,通过參数能够更改 FileContext 中成员的值

    static const AVClass file_class = {
        .class_name = "file",
        .item_name  = av_default_item_name,
        .option     = file_options,
        .version    = LIBAVUTIL_VERSION_INT,
    };



    10、找到详细的协议是在 url_find_protocol 函数中查找的,查找是依照协议的名字和 URLProtocol.name 匹配的,假设给到的 filename 是没有写协议的路径,会被直接当做 file 协议。查找到了相关的协议后就要分配 context(比方:FileContext),并设置 URLContext  中的成员,实现是在 url_alloc_for_protocol 函数中

    11、avio.c 中维护了一个 URLProtocol 列表,通过 ffurl_register_protocol 函数将协议注冊。这个函数是在 av_register_all 里面触发的,在这里会完毕全部的 codecs,muxers,protocol,libraries 等的注冊


     

  • 相关阅读:
    Kafka设计解析(二)- Kafka High Availability (上)
    Kafka设计解析(三)- Kafka High Availability (下)
    Kafka深度解析
    Cloudera Manager(CDH5)内部结构、功能包括配置文件、目录位置等
    Failed to start /etc/rc.d/rc.local Compatibility
    Offset Management For Apache Kafka With Apache Spark Streaming
    maven-assembly-plugin打包可执行的jar包
    How Cigna Tuned Its Spark Streaming App for Real-time Processing with Apache Kafka
    SystemTap Beginners Guide
    数据可视化的开源方案: Superset vs Redash vs Metabase (二)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4194139.html
Copyright © 2011-2022 走看看