123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- #pragma once
- #include "api/video/video_frame.h"
- #include "api/video/video_sink_interface.h"
- #include "callback.h"
- using I420FrameReadyCallback = Callback<const void*,
- const void*,
- const void*,
- const void*,
- int,
- int,
- int,
- int,
- int,
- int>;
- using ARGBFrameReadyCallback = Callback<
- const uint8_t*,int,
- const uint8_t*,int,
- const uint8_t*, int,
- const int,const int,
- const int>;
- //根据图像的高度和每行数据的字节数,计算出整个图像数据所需的总字节数
- constexpr inline size_t ArgbDataSize(int height, int stride)
- {
- return static_cast<size_t>(height) * stride * 4;
- }
- /*
- 自定义的视频帧缓冲区管理类
- */
- class ArgbBuffer : public webrtc::VideoFrameBuffer {
- public:
- // Create a new buffer.
- /*
- 静态方法用于创建一个新的 ArgbBuffer实例
- 该方法接收视频帧的宽度和高度,并计算出所需的缓冲区大小
- 返回类型是rtc::scoped_refptr<ArgbBuffer>,它是一个智能指针,用于管理 ArgbBuffer 的生命周期
- */
- static inline rtc::scoped_refptr<ArgbBuffer> Create(int width, int height) {
- return new rtc::RefCountedObject<ArgbBuffer>(width, height, width * 4);
- }
- //// Create a new buffer and copy the pixel data.
- // static rtc::scoped_refptr<ArgbBuffer> Copy(const I010BufferInterface&
- // buffer);
- //// Convert and put I420 buffer into a new buffer.
- // static rtc::scoped_refptr<ArgbBuffer> Copy(const I420BufferInterface&
- // buffer);
- //// Return a rotated copy of |src|.
- // static rtc::scoped_refptr<ArgbBuffer> Rotate(const I010BufferInterface&
- // src,
- // VideoRotation rotation);
- // VideoFrameBuffer implementation.
- inline Type type() const override { return VideoFrameBuffer::Type::kNative; }
- inline int width() const override { return width_; }
- inline int height() const override { return height_; }
- rtc::scoped_refptr<webrtc::I420BufferInterface> ToI420() override;
- inline uint8_t* Data() { return data_.get(); }
- inline const uint8_t* Data() const { return data_.get(); }
- inline int Stride() const { return stride_; }
- inline constexpr size_t Size() const {
- return ArgbDataSize(height_, stride_);
- }
- protected:
- ArgbBuffer(int width, int height, int stride) ;
- ~ArgbBuffer() override = default;
- private:
- const int width_;
- const int height_;
- const int stride_;
- //指向视频数据的智能指针,使用 webrtc::AlignedFreeDeleter 来管理内存释放
- const std::unique_ptr<uint8_t, webrtc::AlignedFreeDeleter> data_;
- };
- /*
- 管理视频帧的接口类
- */
- /// Video frame observer to get notified of newly available video frames.
- class VideoFrameObserver : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
- public:
- /// Register a callback to get notified on frame available,
- /// and received that frame as a I420-encoded buffer.
- /// This is not exclusive and can be used along another ARGB callback.
- void SetCallback(I420FrameReadyCallback callback) ;
- /// Register a callback to get notified on frame available,
- /// and received that frame as a raw decoded ARGB buffer.
- /// This is not exclusive and can be used along another I420 callback.
- void SetCallback(ARGBFrameReadyCallback callback) ;
- protected:
- //获取一个足够容纳指定大小图像数据的缓冲区(ArgbBuffer),如果已有的缓冲区足够大,则直接返回;否则,创建一个新的缓冲区并返回
- ArgbBuffer* GetArgbScratchBuffer(int width, int height);
- // VideoSinkInterface interface
- void OnFrame(const webrtc::VideoFrame& frame) override;
- private:
- /// Registered callback for receiving I420-encoded frame.
- I420FrameReadyCallback i420_callback_;
- /// Registered callback for receiving raw decoded ARGB frame.
- ARGBFrameReadyCallback argb_callback_;
- /// Mutex protecting all callbacks.
- std::mutex mutex_;
- /// Reusable ARGB scratch buffer to avoid per-frame allocation.
- //定义一个名为argb_scratch_buffer_ 的ArgbBuffer类型的智能指针,指向ARGB暂存缓冲区
- rtc::scoped_refptr<ArgbBuffer> argb_scratch_buffer_;
- };
|