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

视频帧双缓冲区的第一个版本,仅缓冲视频帧,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_; 
};

 

posted @ 2019-10-24 11:40  飞鹰007  阅读(124)  评论(0编辑  收藏