#pragma once #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" #include "callback.h" using I420FrameReadyCallback = Callback; 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(height) * stride * 4; } class ArgbBuffer : public webrtc::VideoFrameBuffer { public: // Create a new buffer. static inline rtc::scoped_refptr Create(int width, int height) { return new rtc::RefCountedObject(width, height, width * 4); } //// Create a new buffer and copy the pixel data. // static rtc::scoped_refptr Copy(const I010BufferInterface& // buffer); //// Convert and put I420 buffer into a new buffer. // static rtc::scoped_refptr Copy(const I420BufferInterface& // buffer); //// Return a rotated copy of |src|. // static rtc::scoped_refptr 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 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_; const std::unique_ptr data_; }; /// Video frame observer to get notified of newly available video frames. class VideoFrameObserver : public rtc::VideoSinkInterface { 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* 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. rtc::scoped_refptr argb_scratch_buffer_; };