• 视频帧双缓冲区的两个版本


    视频帧双缓冲区的第一个版本,仅缓冲视频帧,CSharedCriticalSection是临界区保护类

    class CFrameCache{
    public:
        CFrameCache()
            : pop_frame_ptr_(nullptr)
            , push_frame_ptr_(nullptr)
            , width_(0), hight_(0), channels_(0){
    
        }
    
        ~CFrameCache() {
            if(pop_frame_ptr_) {
                delete[] pop_frame_ptr_;
                pop_frame_ptr_ = nullptr;
            }
    
            if(push_frame_ptr_){
                delete[] push_frame_ptr_;
                push_frame_ptr_ = nullptr;
            }
        }
    
        void push_frame(const char* frame, int width, int hight, int channels){
            if(nullptr == frame || width < 0 || hight < 0 || channels < 0) {
                return ;
            }
    
            CSharedMutex lock(mutex_);
    
            if(push_frame_ptr_ == nullptr && 
                pop_frame_ptr_ == nullptr) {
                    width_ = width;
                    hight_ = hight;
                    channels_ = channels;
                    pop_frame_ptr_ = new char[width_ * hight_ * channels_];
                    push_frame_ptr_ = new char[width_ * hight_ * channels_];
                    memset(pop_frame_ptr_, 0x00, width_ * hight_ * channels_);
                    memset(push_frame_ptr_, 0x00, width_ * hight_ * channels_);
            }
    
            if((width != width_ || hight_ != hight || channels_ != channels) && push_frame_ptr_ && pop_frame_ptr_) {
                width_ = width;
                hight_ = hight;
                channels_ = channels;
                delete[] pop_frame_ptr_;
                delete[] push_frame_ptr_;
                pop_frame_ptr_ = new char[width_ * hight_ * channels_];
                push_frame_ptr_ = new char[width_ * hight_ * channels_];
    
                memset(pop_frame_ptr_, 0x00, width_ * hight_ * channels_);
                memset(push_frame_ptr_, 0x00, width_ * hight_ * channels_);
            }
    
            memset(push_frame_ptr_, 0x00, width_ * hight_ * channels_);
            memcpy(push_frame_ptr_, frame, width_ * hight_ * channels_);
        }
    
        const char* pop_frame(){
            CSharedMutex lock(mutex_);
            std::swap(push_frame_ptr_, pop_frame_ptr_);
            return pop_frame_ptr_;
        }
    
        int size(){
            CSharedMutex lock(mutex_);
            return width_ * hight_ * channels_;
        }
    
        int Width() {
            CSharedMutex lock(mutex_);
            return width_;
        }
    
        int Hight() {
            CSharedMutex lock(mutex_);
            return hight_;
        }
    
        int Channels() {
            CSharedMutex lock(mutex_);
            return channels_;
        }
    
    protected:
        CFrameCache(const CFrameCache& rhs){
    
        }
    
        CFrameCache& operator=(const CFrameCache& rhs){
            return *this;
        }
    
    private:
        char* pop_frame_ptr_;
        char* push_frame_ptr_;
        int width_, hight_, channels_;
        CSharedCriticalSection mutex_; 
    };

    视频帧双缓冲区的第二个版本,缓冲视频帧,并允许保存一些视频的附加信息

    // 带EXIF信息的帧缓冲
    template <typename ExifClass>
    class CFrameCacheWithExif{
    public:
        CFrameCacheWithExif()
            : pop_frame_ptr_(nullptr)
            , push_frame_ptr_(nullptr)
            , width_(0), hight_(0), channels_(0){
    
        }
    
        ~CFrameCacheWithExif() {
            if(pop_frame_ptr_) {
                delete[] pop_frame_ptr_;
                pop_frame_ptr_ = nullptr;
            }
    
            if(push_frame_ptr_){
                delete[] push_frame_ptr_;
                push_frame_ptr_ = nullptr;
            }
            if(pop_exif_ptr_) {
                delete[] pop_exif_ptr_;
                pop_exif_ptr_ = nullptr;
            }
    
            if(push_exif_ptr_){
                delete[] push_exif_ptr_;
                push_exif_ptr_ = nullptr;
            }
        }
    
        void push_frame(const char* frame, const void* exif, int width, int hight, int channels){
            if(nullptr == frame || width < 0 || hight < 0 || channels < 0) {
                return ;
            }
    
            CSharedMutex lock(mutex_);
    
            if(push_frame_ptr_ == nullptr && 
                pop_frame_ptr_ == nullptr) {
                    width_ = width;
                    hight_ = hight;
                    channels_ = channels;
                    pop_frame_ptr_ = new char[width_ * hight_ * channels_];
                    push_frame_ptr_ = new char[width_ * hight_ * channels_];
                    memset(pop_frame_ptr_, 0x00, width_ * hight_ * channels_);
                    memset(push_frame_ptr_, 0x00, width_ * hight_ * channels_);
    
                    pop_exif_ptr_ = new unsigned char[sizeof(ExifClass)];
                    push_exif_ptr_ = new unsigned char[sizeof(ExifClass)];
                    memset(pop_exif_ptr_, 0x00,  sizeof(ExifClass));
                    memset(push_exif_ptr_, 0x00, sizeof(ExifClass));
            }
    
            if((width != width_ || hight_ != hight || channels_ != channels) && push_frame_ptr_ && pop_frame_ptr_) {
                width_ = width;
                hight_ = hight;
                channels_ = channels;
                delete[] pop_frame_ptr_;
                delete[] push_frame_ptr_;
                pop_frame_ptr_ = new char[width_ * hight_ * channels_];
                push_frame_ptr_ = new char[width_ * hight_ * channels_];
    
                memset(pop_frame_ptr_, 0x00, width_ * hight_ * channels_);
                memset(push_frame_ptr_, 0x00, width_ * hight_ * channels_);
    
                delete[] pop_exif_ptr_;
                delete[] push_exif_ptr_;
                pop_exif_ptr_ = new unsigned char[sizeof(ExifClass)];
                push_exif_ptr_ = new unsigned char[sizeof(ExifClass)];
                memset(pop_exif_ptr_, 0x00,  sizeof(ExifClass));
                memset(push_exif_ptr_, 0x00, sizeof(ExifClass));
            }
    
            memset(push_frame_ptr_, 0x00, width_ * hight_ * channels_);
            memcpy(push_frame_ptr_, frame, width_ * hight_ * channels_);
    
            memset(push_exif_ptr_, 0x00, sizeof(ExifClass));
            memcpy(push_exif_ptr_, exif, sizeof(ExifClass));
        }
    
        const char* pop_frame(void** exif){
            CSharedMutex lock(mutex_);
            std::swap(push_frame_ptr_, pop_frame_ptr_);
            std::swap(push_exif_ptr_,  pop_exif_ptr_);
            if (nullptr != exif) {
                *exif = pop_exif_ptr_;
            }
            return pop_frame_ptr_;
        }
    
        int size(){
            CSharedMutex lock(mutex_);
            return width_ * hight_ * channels_;
        }
    
        int Width() {
            CSharedMutex lock(mutex_);
            return width_;
        }
    
        int Hight() {
            CSharedMutex lock(mutex_);
            return hight_;
        }
    
        int Channels() {
            CSharedMutex lock(mutex_);
            return channels_;
        }
    
    protected:
        CFrameCacheWithExif(const CFrameCacheWithExif& rhs){
    
        }
    
        CFrameCacheWithExif& operator=(const CFrameCacheWithExif& rhs){
            return *this;
        }
    
    private:
        char* pop_frame_ptr_;
        unsigned char* pop_exif_ptr_;
        char* push_frame_ptr_;
        unsigned char* push_exif_ptr_;
        int width_, hight_, channels_;
        CSharedCriticalSection mutex_; 
    };
  • 相关阅读:
    记一次JVM Full GC (Metadata GC Threshold)调优经历
    非root用户启动nginx
    springboot项目报错解决:ERROR StatusLogger No Log4j 2 configuration file found
    分布式锁的常见实现思路
    虚拟机安装redis及宿主机连接测试
    使用console.log打印的内容不一定可信
    《数据库系统概论》第九章笔记
    《数据库系统概论》第六章笔记
    英文论文里的缩写:e.g. etc. et al. i.e.
    英文论文里的缩写:e.g. etc. et al. i.e.
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/11731281.html
Copyright © 2020-2023  润新知