音视频的Buffer处理

最近在做安卓下UVC的一个案子。正好之前搞过ST方案的开机广告,这个也是我少数最后没搞成功的项目。当时也有点客观原因,当时ST要退出机顶盒市场,所以一切的支持都停了,当时啃他家播放器几十万行的代码,而且几乎没有文档,真的是非常痛苦。后面虽然功能是搞出来了,但是不稳定,持续几次后就会crash。

还记得当时最后到底层ST是用的滑动窗口缓存,双指针,一个写指针和一个读指针,当时我做了一个管道往缓存中注数据。估计还是没有完全吃透,某些细节处理有问题。正好现在又做到类似项目,所以简单总结总结相关要点。主要就是共享内存,滑动窗口,双缓冲,环形缓冲这些内容。

下面是一个简单的具有读写指针的循环缓冲区。

#include <iostream>
#include <vector>
#include <stdexcept>

template<typename T>
class MediaQueue {
public:
    explicit MediaQueue(size_t size)
        : buffer(size), readPtr(0), writePtr(0), count(0), maxSize(size) {}

    // 添加一个元素到队列中
    void enqueue(const T& item) {
        if (isFull()) {
            throw std::overflow_error("Queue is full");
        }
        buffer[writePtr] = item;
        writePtr = (writePtr + 1) % maxSize;
        ++count;
    }

    // 从队列中读取一个元素
    T dequeue() {
        if (isEmpty()) {
            throw std::underflow_error("Queue is empty");
        }
        T item = buffer[readPtr];
        readPtr = (readPtr + 1) % maxSize;
        --count;
        return item;
    }

    // 检查队列是否为空
    bool isEmpty() const {
        return count == 0;
    }

    // 检查队列是否已满
    bool isFull() const {
        return count == maxSize;
    }

    // 获取队列中的元素数量
    size_t size() const {
        return count;
    }

    // 获取队列的最大容量
    size_t capacity() const {
        return maxSize;
    }

private:
    std::vector<T> buffer;
    size_t readPtr;
    size_t writePtr;
    size_t count;
    size_t maxSize;
};

还有一种叫做乒乓buffer

就是两个buffer,一个读一个写,写完之后交换。

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <cstring> // For memcpy
#include <chrono> // For sleep

class PingPongBuffer {
public:
    PingPongBuffer(size_t bufferSize)
        : bufferSize(bufferSize), readBufferIndex(0), writeBufferIndex(1), buffers(2, std::vector<char>(bufferSize)) {}

    // 写入数据到当前写缓冲区
    void write(const char* data, size_t size) {
        std::unique_lock<std::mutex> lock(mutex);
        while (writeBufferFull) {
            condVar.wait(lock);
        }
        if (size > bufferSize) {
            throw std::overflow_error("Data size exceeds buffer capacity");
        }
        std::memcpy(buffers[writeBufferIndex].data(), data, size);
        writeBufferFull = true;
        readBufferEmpty = false;
        swapBuffers();
        condVar.notify_all();
    }

    // 从当前读缓冲区读取数据
    void read(char* data, size_t size) {
        std::unique_lock<std::mutex> lock(mutex);
        while (readBufferEmpty) {
            condVar.wait(lock);
        }
        if (size > bufferSize) {
            throw std::underflow_error("Data size exceeds buffer capacity");
        }
        std::memcpy(data, buffers[readBufferIndex].data(), size);
        readBufferEmpty = true;
        writeBufferFull = false;
        condVar.notify_all();
    }

private:
    void swapBuffers() {
        std::swap(readBufferIndex, writeBufferIndex);
    }

    size_t bufferSize;
    int readBufferIndex;
    int writeBufferIndex;
    std::vector<std::vector<char>> buffers;
    bool readBufferEmpty = true;
    bool writeBufferFull = false;
    std::mutex mutex;
    std::condition_variable condVar;
};

void producer(PingPongBuffer& buffer) {
    const char* messages[] = {"Message 1", "Message 2", "Message 3"};
    for (const char* message : messages) {
        std::this_thread::sleep_for(std::chrono::seconds(1)); // Simulate work
        buffer.write(message, std::strlen(message) + 1);
        std::cout << "Produced: " << message << std::endl;
    }
}

void consumer(PingPongBuffer& buffer) {
    char data[1024];
    for (int i = 0; i < 3; ++i) {
        buffer.read(data, 1024);
        std::cout << "Consumed: " << data << std::endl;
    }
}

int main() {
    size_t bufferSize = 1024;
    PingPongBuffer buffer(bufferSize);

    std::thread producerThread(producer, std::ref(buffer));
    std::thread consumerThread(consumer, std::ref(buffer));

    producerThread.join();
    consumerThread.join();

    return 0;
}

空了有时间看看V4L2和ffmpeg这方面的内容再更新一下吧。。。

相关推荐
顶顶年华正版软件官方3 小时前
关键帧功能怎么使用 关键帧控制视频特效怎么用 会声会影视频剪辑软件教程
前端·javascript·音视频·学习方法·关键帧·会声会影教程·视频剪辑软件
星光一影3 小时前
抖音矩阵云混剪系统源码 短视频矩阵营销系统V2(全开源版)
人工智能·chatgpt·矩阵·音视频·人机交互
TSINGSEE3 小时前
智慧矿山:EasyCVR助力矿井视频多业务融合及视频转发服务建设
音视频·视频编解码·h.264·视频监控技术
EelBarb3 小时前
python源码:opencv多视频源同屏拼接播放
python·opencv·音视频
昨日之日20066 小时前
AI一键音频转文字工具 速度超快,支持实时转换,无需联网,本地整合包下载
人工智能·音视频
罗兰Yolanda6 小时前
BLOB视频技术原理,如何将Blob视频转换为MP4格式?
音视频
LiveMedia视频中间件13 小时前
视频网关的作用
音视频·实时音视频·视频编解码
LDG_AGI16 小时前
【机器学习】FFmpeg+Whisper:二阶段法视频理解(video-to-text)大模型实战
人工智能·python·深度学习·机器学习·ffmpeg·whisper·音视频
Ren1915494813621 小时前
MIPI竖屏解决方案,普立晶POL8901升级POL8903 两PORT LVDS转MIPIDSI,加90度旋转
单片机·嵌入式硬件·车载系统·音视频·显示器
数据蛙恢复专家1 天前
电脑录制视频的软件,电脑录制,4款免费软件推荐
电脑·音视频·录屏软件