zoukankan      html  css  js  c++  java
  • FFMPEG 中的avio

    1.avio接口
    const char *avio_find_protocol_name(const char *url);
    int avio_check(const char *url, int flags);
    int avpriv_io_move(const char *url_src, const char *url_dst);
    int avpriv_io_delete(const char *url);
    int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options);
    int avio_read_dir(AVIODirContext *s, AVIODirEntry **next);
    int avio_close_dir(AVIODirContext **s);
    void avio_free_directory_entry(AVIODirEntry **entry);
    AVIOContext *avio_alloc_context(
                      unsigned char *buffer,
                      int buffer_size,
                      int write_flag,
                      void *opaque,
                      int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
                      int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
                      int64_t (*seek)(void *opaque, int64_t offset, int whence));
    void avio_context_free(AVIOContext **s);
    
    void avio_w8(AVIOContext *s, int b);
    void avio_write(AVIOContext *s, const unsigned char *buf, int size);
    void avio_wl64(AVIOContext *s, uint64_t val);
    void avio_wb64(AVIOContext *s, uint64_t val);
    void avio_wl32(AVIOContext *s, unsigned int val);
    void avio_wb32(AVIOContext *s, unsigned int val);
    void avio_wl24(AVIOContext *s, unsigned int val);
    void avio_wb24(AVIOContext *s, unsigned int val);
    void avio_wl16(AVIOContext *s, unsigned int val);
    void avio_wb16(AVIOContext *s, unsigned int val);
    int avio_put_str(AVIOContext *s, const char *str);
    int avio_put_str16le(AVIOContext *s, const char *str);
    int avio_put_str16be(AVIOContext *s, const char *str);
    void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type);
    int64_t avio_seek(AVIOContext *s, int64_t offset, int whence);
    int64_t avio_skip(AVIOContext *s, int64_t offset);
    static av_always_inline int64_t avio_tell(AVIOContext *s);
    int64_t avio_size(AVIOContext *s);
    int avio_feof(AVIOContext *s);
    void avio_flush(AVIOContext *s);
    
    int avio_read(AVIOContext *s, unsigned char *buf, int size);
    int avio_read_partial(AVIOContext *s, unsigned char *buf, int size);
    int          avio_r8  (AVIOContext *s);
    unsigned int avio_rl16(AVIOContext *s);
    unsigned int avio_rl24(AVIOContext *s);
    unsigned int avio_rl32(AVIOContext *s);
    uint64_t     avio_rl64(AVIOContext *s);
    unsigned int avio_rb16(AVIOContext *s);
    unsigned int avio_rb24(AVIOContext *s);
    unsigned int avio_rb32(AVIOContext *s);
    uint64_t     avio_rb64(AVIOContext *s);
    int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen);
    int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen);
    int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen);
    
    int avio_open(AVIOContext **s, const char *url, int flags);
    int avio_open2(AVIOContext **s, const char *url, int flags,
                   const AVIOInterruptCB *int_cb, AVDictionary **options);
    int avio_close(AVIOContext *s);
    int avio_closep(AVIOContext **s);
    int avio_open_dyn_buf(AVIOContext **s);
    int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
    int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
    const char *avio_enum_protocols(void **opaque, int output);
    int     avio_pause(AVIOContext *h, int pause);
    int64_t  avio_seek_time(AVIOContext *h, int stream_index,
                           int64_t timestamp, int flags);
    int avio_read_to_bprint(AVIOContext *h, struct AVBPrint *pb, size_t max_size);
    int avio_accept(AVIOContext *s, AVIOContext **c);
    int avio_handshake(AVIOContext *c);
    2.avio结构
    typedef struct AVIODirEntry {
        char *name;                           /**< Filename */
        int type;                             /**< Type of the entry */
        int utf8;                             /**< Set to 1 when name is encoded with UTF-8, 0 otherwise.
                                                   Name can be encoded with UTF-8 even though 0 is set. */
        int64_t size;                         /**< File size in bytes, -1 if unknown. */
        int64_t modification_timestamp;       /**< Time of last modification in microseconds since unix
                                                   epoch, -1 if unknown. */
        int64_t access_timestamp;             /**< Time of last access in microseconds since unix epoch,
                                                   -1 if unknown. */
        int64_t status_change_timestamp;      /**< Time of last status change in microseconds since unix
                                                   epoch, -1 if unknown. */
        int64_t user_id;                      /**< User ID of owner, -1 if unknown. */
        int64_t group_id;                     /**< Group ID of owner, -1 if unknown. */
        int64_t filemode;                     /**< Unix file mode, -1 if unknown. */
    } AVIODirEntry;
    
    typedef struct AVIODirContext {
        struct URLContext *url_context;
    } AVIODirContext;
    
    
    typedef struct AVIOContext {
        /**
         * A class for private options.
         *
         * If this AVIOContext is created by avio_open2(), av_class is set and
         * passes the options down to protocols.
         *
         * If this AVIOContext is manually allocated, then av_class may be set by
         * the caller.
         *
         * warning -- this field can be NULL, be sure to not pass this AVIOContext
         * to any av_opt_* functions in that case.
         */
        const AVClass *av_class;
    
        /*
         * The following shows the relationship between buffer, buf_ptr,
         * buf_ptr_max, buf_end, buf_size, and pos, when reading and when writing
         * (since AVIOContext is used for both):
         *
         **********************************************************************************
         *                                   READING
         **********************************************************************************
         *
         *                            |              buffer_size              |
         *                            |---------------------------------------|
         *                            |                                       |
         *
         *                         buffer          buf_ptr       buf_end
         *                            +---------------+-----------------------+
         *                            |/ / / / / / / /|/ / / / / / /|         |
         *  read buffer:              |/ / consumed / | to be read /|         |
         *                            |/ / / / / / / /|/ / / / / / /|         |
         *                            +---------------+-----------------------+
         *
         *                                                         pos
         *              +-------------------------------------------+-----------------+
         *  input file: |                                           |                 |
         *              +-------------------------------------------+-----------------+
         *
         *
         **********************************************************************************
         *                                   WRITING
         **********************************************************************************
         *
         *                             |          buffer_size                 |
         *                             |--------------------------------------|
         *                             |                                      |
         *
         *                                                buf_ptr_max
         *                          buffer                 (buf_ptr)       buf_end
         *                             +-----------------------+--------------+
         *                             |/ / / / / / / / / / / /|              |
         *  write buffer:              | / / to be flushed / / |              |
         *                             |/ / / / / / / / / / / /|              |
         *                             +-----------------------+--------------+
         *                               buf_ptr can be in this
         *                               due to a backward seek
         *
         *                            pos
         *               +-------------+----------------------------------------------+
         *  output file: |             |                                              |
         *               +-------------+----------------------------------------------+
         *
         */
        unsigned char *buffer;  /**< Start of the buffer. */
        int buffer_size;        /**< Maximum buffer size */
        unsigned char *buf_ptr; /**< Current position in the buffer */
        unsigned char *buf_end; /**< End of the data, may be less than
                                     buffer+buffer_size if the read function returned
                                     less data than requested, e.g. for streams where
                                     no more data has been received yet. */
        void *opaque;           /**< A private pointer, passed to the read/write/seek/...
                                     functions. */
        int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);
        int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
        int64_t (*seek)(void *opaque, int64_t offset, int whence);
        int64_t pos;            /**< position in the file of the current buffer */
        int eof_reached;        /**< true if eof reached */
        int write_flag;         /**< true if open for writing */
        int max_packet_size;
        unsigned long checksum;
        unsigned char *checksum_ptr;
        unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);
        int error;              /**< contains the error code or 0 if no error happened */
        /**
         * Pause or resume playback for network streaming protocols - e.g. MMS.
         */
        int (*read_pause)(void *opaque, int pause);
        /**
         * Seek to a given timestamp in stream with the specified stream_index.
         * Needed for some network streaming protocols which don't support seeking
         * to byte position.
         */
        int64_t (*read_seek)(void *opaque, int stream_index,
                             int64_t timestamp, int flags);
        /**
         * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
         */
        int seekable;
    
        /**
         * max filesize, used to limit allocations
         * This field is internal to libavformat and access from outside is not allowed.
         */
        int64_t maxsize;
    
        /**
         * avio_read and avio_write should if possible be satisfied directly
         * instead of going through a buffer, and avio_seek will always
         * call the underlying seek function directly.
         */
        int direct;
    
        /**
         * Bytes read statistic
         * This field is internal to libavformat and access from outside is not allowed.
         */
        int64_t bytes_read;
    
        /**
         * seek statistic
         * This field is internal to libavformat and access from outside is not allowed.
         */
        int seek_count;
    
        /**
         * writeout statistic
         * This field is internal to libavformat and access from outside is not allowed.
         */
        int writeout_count;
    
        /**
         * Original buffer size
         * used internally after probing and ensure seekback to reset the buffer size
         * This field is internal to libavformat and access from outside is not allowed.
         */
        int orig_buffer_size;
    
        /**
         * Threshold to favor readahead over seek.
         * This is current internal only, do not use from outside.
         */
        int short_seek_threshold;
    
        /**
         * ',' separated list of allowed protocols.
         */
        const char *protocol_whitelist;
    
        /**
         * ',' separated list of disallowed protocols.
         */
        const char *protocol_blacklist;
    
        /**
         * A callback that is used instead of write_packet.
         */
        int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size,
                               enum AVIODataMarkerType type, int64_t time);
        /**
         * If set, don't call write_data_type separately for AVIO_DATA_MARKER_BOUNDARY_POINT,
         * but ignore them and treat them as AVIO_DATA_MARKER_UNKNOWN (to avoid needlessly
         * small chunks of data returned from the callback).
         */
        int ignore_boundary_point;
    
        /**
         * Internal, not meant to be used from outside of AVIOContext.
         */
        enum AVIODataMarkerType current_type;
        int64_t last_time;
    
        /**
         * A callback that is used instead of short_seek_threshold.
         * This is current internal only, do not use from outside.
         */
        int (*short_seek_get)(void *opaque);
    
        int64_t written;
    
        /**
         * Maximum reached position before a backward seek in the write buffer,
         * used keeping track of already written data for a later flush.
         */
        unsigned char *buf_ptr_max;
    
        /**
         * Try to buffer at least this amount of data before flushing it
         */
        int min_packet_size;
    } AVIOContext;
    3.测试demo
    #include "libavformat/avio.h"
    //遍历支持的protocol
    int show_protocols()
    {
        void *opaque = NULL;
        const char *name;
    
        printf("Supported file protocols:
    "
            "Input:
    ");
        while ((name = avio_enum_protocols(&opaque, 0)))
            printf("  %s
    ", name);
        printf("Output:
    ");
        while ((name = avio_enum_protocols(&opaque, 1)))
            printf("  %s
    ", name);
        return 0;
    }
    
    int main()
    {
        char* srcName = "src1.mp4";
        char* dstName = "test.mp4";
        AVIOContext* pReadCtx = NULL;
        AVIOContext* pWriteCtx = NULL;
        unsigned char buf[1024];
        int nRet = 0;
    
        show_protocols();
        
        char* protocolName = avio_find_protocol_name(srcName);
        printf("protocol name: %s
    ", protocolName);
    
        nRet = avio_open(&pReadCtx, srcName, AVIO_FLAG_READ);
        nRet = avio_open(&pWriteCtx, dstName, AVIO_FLAG_WRITE);
    
        int64_t srcSize = avio_size(pReadCtx);
        printf("srcSize: %lld
    ", srcSize);
    
        nRet = avio_read(pReadCtx, buf, 1024);
    
        avio_write(pWriteCtx, buf, 1024);
    
        nRet = avio_close(pReadCtx);
        nRet = avio_close(pWriteCtx);
        
        AVIOContext* pWriteOnlyBufCtx = NULL;
        uint8_t* pWriteBuf = NULL;
        uint8_t* pWriteBuf1 = NULL;
    
        nRet = avio_open_dyn_buf(&pWriteOnlyBufCtx);
        avio_write(pWriteOnlyBufCtx, buf, 1024);
        //int nSize = avio_get_dyn_buf(pWriteOnlyBufCtx, &pWriteBuf);
        nRet = avio_close_dyn_buf(pWriteOnlyBufCtx, &pWriteBuf1);
        
    
        av_free(pWriteBuf1);
    
        printf("end
    ");
        return 0;
    }
    4.找文件protocol类型

    //libavformat/protocols.c
    const URLProtocol **ffurl_get_protocols(const char *whitelist,
                                            const char *blacklist)
    {
        const URLProtocol **ret;
        int i, ret_idx = 0;
        //url_protocols数组中保存了支持的Protocol类型
        ret = av_mallocz_array(FF_ARRAY_ELEMS(url_protocols), sizeof(*ret));
        if (!ret)
            return NULL;
    
        for (i = 0; url_protocols[i]; i++) {
            const URLProtocol *up = url_protocols[i];
    
            if (whitelist && *whitelist && !av_match_name(up->name, whitelist))
                continue;
            if (blacklist && *blacklist && av_match_name(up->name, blacklist))
                continue;
    
            ret[ret_idx++] = up;
        }
    
        return ret;
    }
    
    static const struct URLProtocol *url_find_protocol(const char *filename)
    {
        const URLProtocol **protocols;
        char proto_str[128], proto_nested[128], *ptr;
        size_t proto_len = strspn(filename, URL_SCHEME_CHARS);
        int i;
    
        if (filename[proto_len] != ':' &&
            (strncmp(filename, "subfile,", 8) || !strchr(filename + proto_len + 1, ':')) ||
            is_dos_path(filename))
            strcpy(proto_str, "file");
        else
            av_strlcpy(proto_str, filename,
                       FFMIN(proto_len + 1, sizeof(proto_str)));
    
        av_strlcpy(proto_nested, proto_str, sizeof(proto_nested));
        if ((ptr = strchr(proto_nested, '+')))
            *ptr = '';
    
        protocols = ffurl_get_protocols(NULL, NULL);
        if (!protocols)
            return NULL;
        for (i = 0; protocols[i]; i++) {
                const URLProtocol *up = protocols[i];
            if (!strcmp(proto_str, up->name)) {
                av_freep(&protocols);
                return up;
            }
            if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME &&
                !strcmp(proto_nested, up->name)) {
                av_freep(&protocols);
                return up;
            }
        }
        av_freep(&protocols);
    
        return NULL;
    }

    url_protocols数组定义在libavformat/protocol_list.c中

    static const URLProtocol *url_protocols[] = {
        &ff_async_protocol,
        &ff_bluray_protocol,
        &ff_cache_protocol,
        &ff_concat_protocol,
        &ff_crypto_protocol,
        &ff_data_protocol,
        &ff_ffrtmpcrypt_protocol,
        &ff_ffrtmphttp_protocol,
        &ff_file_protocol,
        &ff_ftp_protocol,
        &ff_gopher_protocol,
        &ff_hls_protocol,
        &ff_http_protocol,
        &ff_httpproxy_protocol,
        &ff_https_protocol,
        &ff_icecast_protocol,
        &ff_mmsh_protocol,
        &ff_mmst_protocol,
        &ff_md5_protocol,
        &ff_pipe_protocol,
        &ff_prompeg_protocol,
        &ff_rtmp_protocol,
        &ff_rtmpe_protocol,
        &ff_rtmps_protocol,
        &ff_rtmpt_protocol,
        &ff_rtmpte_protocol,
        &ff_rtmpts_protocol,
        &ff_rtp_protocol,
        &ff_srtp_protocol,
        &ff_subfile_protocol,
        &ff_tee_protocol,
        &ff_tcp_protocol,
        &ff_tls_protocol,
        &ff_udp_protocol,
        &ff_udplite_protocol,
        &ff_libssh_protocol,
        NULL };
  • 相关阅读:
    注解之------@WebService
    注解之----@component,@controller,@service ,@repository简介
    Java 之 I/O
    标签之----@Override
    注解之----@Resource
    弹指之间 -- 简谱
    弹指之间 -- Prerequisites
    MVC5 + EF6 完整入门教程三
    MVC5 + EF6 入门完整教程二
    MVC5 + EF6 入门完整教程
  • 原文地址:https://www.cnblogs.com/CoderTian/p/13845426.html
Copyright © 2011-2022 走看看