AVFifoBuffer

108 阅读2分钟

头文件在libavutil/fifo.h

typedef struct AVFifoBuffer {
    uint8_t *buffer;   // 指向缓冲区的数据指针
    uint8_t *rptr;     // 读指针
    uint8_t *wptr;     // 写指针
    uint8_t *end;      // 缓冲区末尾的指针
    uint32_t rndx;     // 读索引(可选,用于调试)
    uint32_t wndx;     // 写索引(可选,用于调试)
} AVFifoBuffer;

注意:这个不是线程安全的 ,需要外部来做同步 关键的api

  1. av_fifo_alloc(size_t size)
    分配一个大小为 size 的 FIFO 缓冲区
  2. av_fifo_free(AVFifoBuffer* fifo)
    释放 FIFO 缓冲区及其分配的内存。
  3. av_fifo_reset(AVFifoBuffer* fifo)
    重置 FIFO 缓冲区,使其为空(读写指针回到初始状态)。
  4. int av_fifo_generic_write(AVFifoBuffer *f, const void *src, int size, void (*func)(void*, void*, int))
    size 字节从 src 写入 FIFO。如果缓冲区已满,写入会失败
  5. int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int size, void (*func)(void*, void*, int))
    从 FIFO 读取 size 字节到 dest
  6. int av_fifo_size(const AVFifoBuffer *f)
    返回 FIFO 中存储的数据大小(以字节为单位)
  7. int av_fifo_space(const AVFifoBuffer *f)
    返回 FIFO 中剩余的可用空间(以字节为单位)
  8. int av_fifo_grow(AVFifoBuffer *fifo, unsigned int size)
    扩展 FIFO 缓冲区的大小,以便为更多的数据提供空间

这里一个范例 ffplay.c 里面用来存解封装后的数据

下面是一个基本用法

#include <iostream>

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/fifo.h>
#include <SDL2/SDL.h>
}

typedef struct MyAVPacketList {
    AVPacket *pkt;
    int serial;
} MyAVPacketList;

// TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
int main() {
    // TIP Press <shortcut actionId="RenameElement"/> when your caret is at the
    // <b>lang</b> variable name to see how CLion can help you rename it.
    // auto lang = "C++";
    // std::cout << "Hello and welcome to " << lang << "!\n";
    // std::cout << "PATH: " << std::getenv("PATH") << std::endl;

    unsigned long long size = sizeof(MyAVPacketList);
    printf("buffer size %llu \n",size);
    // 创建一个初始大小为 1024 字节的 FIFO 缓冲区
    AVFifoBuffer* fifo = av_fifo_alloc(1024);
    if (!fifo) {
        fprintf(stderr, "Failed to allocate FIFO buffer\n");
        return -1;
    }

    // 写入数据
    std::string str = "Hello, World!";
    // 转换为 void* 指针
    void* data = static_cast<void*>(const_cast<char*>(str.data()));
    int data_size = str.size() + 1; // 包括 '\0'
    if (av_fifo_space(fifo) >= data_size) {
        av_fifo_generic_write(fifo, data, data_size, NULL);
    } else {
        fprintf(stderr, "Not enough space in FIFO\n");
    }

    // 读取数据
    if (av_fifo_size(fifo) >= data_size) {
        char buffer[1024];
        av_fifo_generic_read(fifo, buffer, data_size, NULL);
        printf("Read from FIFO: %s\n", buffer);
    } else {
        fprintf(stderr, "Not enough data in FIFO\n");
    }

    // 释放 FIFO 缓冲区
    av_fifo_free(fifo);


    return 0;
}