avio_alloc_context

avio_alloc_context:从内存中进行读取或者输出到内存。

源码如下:

int ffio_init_context(AVIOContext *s,
                  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))
{
    memset(s, 0, sizeof(AVIOContext));

    s->buffer      = buffer;
    s->orig_buffer_size =
    s->buffer_size = buffer_size;
    s->buf_ptr     = buffer;
    s->buf_ptr_max = buffer;
    s->opaque      = opaque;
    s->direct      = 0;

    url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);

    s->write_packet    = write_packet;
    s->read_packet     = read_packet;
    s->seek            = seek;
    s->pos             = 0;
    s->eof_reached     = 0;
    s->error           = 0;
    s->seekable        = seek ? AVIO_SEEKABLE_NORMAL : 0;
    s->min_packet_size = 0;
    s->max_packet_size = 0;
    s->update_checksum = NULL;
    s->short_seek_threshold = SHORT_SEEK_THRESHOLD;

    if (!read_packet && !write_flag) {
        s->pos     = buffer_size;
        s->buf_end = s->buffer + buffer_size;
    }
    s->read_pause = NULL;
    s->read_seek  = NULL;

    s->write_data_type       = NULL;
    s->ignore_boundary_point = 0;
    s->current_type          = AVIO_DATA_MARKER_UNKNOWN;
    s->last_time             = AV_NOPTS_VALUE;
    s->short_seek_get        = NULL;
    s->written               = 0;

    return 0;
}

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))
{
    //创建一个AVIOContext结构体
    AVIOContext *s = av_malloc(sizeof(AVIOContext));
    if (!s)
        return NULL;
    //初始化AVIOContext结构体
    ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
                  read_packet, write_packet, seek);
    return s;
}

AVIOContext结构体如下: 

typedef struct AVIOContext {
    const AVClass *av_class;
    unsigned char *buffer;  /**< Start of the buffer. */缓存开始位置
    int buffer_size;        /**< Maximum buffer size */缓存大小(默认32768)
    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;

使用方法:

先通过文件的buffer大小,申请一段内存。然后使用avio_alloc_context为AVIOContext分配内存,申请时,注册内存数据读取的回掉接口read_packet,最后将申请到的AVIOContext句柄挂载到AVFormatContext的pb字段,然后就可以通过AVFormatContext对文件进行操作了。
 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
avio_alloc_context 是 FFmpeg 中用于创建 AVIOContext 的函数。AVIOContext 是 FFmpeg 中的 IO 抽象层,用于封装各种输入输出操作,例如从文件读取数据、向网络发送数据等。avio_alloc_context 函数用于分配并初始化 AVIOContext 结构体,以便进行输入输出操作。 函数原型如下: ``` 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) ); ``` 参数说明如下: - `buffer`:指向用于缓存数据的内存地址。可以为 NULL,表示不需要缓存数据。 - `buffer_size`:缓存区的大小。如果 `buffer` 为 NULL,则该参数无效。 - `write_flag`:标志位,表示 AVIOContext 是否支持写操作。如果为 1,表示支持写操作;如果为 0,表示只支持读操作。 - `opaque`:指向用户自定义的数据结构的指针,用于在读写操作中传递额外的数据。 - `read_packet`:读数据的回调函数指针。函数原型为 `int (*read_packet)(void *opaque, uint8_t *buf, int buf_size)`,返回值为读取的字节数,如果读取失败则返回负数。 - `write_packet`:写数据的回调函数指针。函数原型为 `int (*write_packet)(void *opaque, uint8_t *buf, int buf_size)`,返回值为写入的字节数,如果写入失败则返回负数。 - `seek`:定位操作的回调函数指针。函数原型为 `int64_t (*seek)(void *opaque, int64_t offset, int whence)`,返回值为定位后的文件位置,如果定位失败则返回负数。 下面是一个简单的示例,演示如何使用 avio_alloc_context 函数创建 AVIOContext: ```c #include <libavformat/avformat.h> int main(int argc, char *argv[]) { // 打开一个文件 FILE *file = fopen("test.mp4", "rb"); if (!file) { printf("Failed to open file.\n"); return -1; } // 创建 AVIOContext uint8_t *buffer = (uint8_t *)av_malloc(4096); AVIOContext *avio_ctx = avio_alloc_context(buffer, 4096, 0, file, NULL, NULL, NULL); if (!avio_ctx) { printf("Failed to allocate AVIOContext.\n"); return -1; } // 打开输入格式上下文 AVFormatContext *fmt_ctx = avformat_alloc_context(); fmt_ctx->pb = avio_ctx; int ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL); if (ret < 0) { printf("Failed to open input.\n"); return -1; } // 释放资源 avformat_close_input(&fmt_ctx); av_free(avio_ctx->buffer); av_free(avio_ctx); return 0; } ``` 在该示例中,首先打开了一个文件。然后,创建 AVIOContext 的缓存区,并将文件指针作为 opaque 参数传递给 avio_alloc_context 函数。最后,将 AVIOContext 指定为输入格式上下文的 pb 字段,调用 avformat_open_input 函数打开输入。 需要注意的是,在使用完 AVIOContext 后,需要释放它所占用的内存空间,以避免内存泄漏。可以使用 av_free 函数释放缓存区,使用 avio_context_free 函数释放 AVIOContext 结构体。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值