video_frame_observer.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #pragma once
  2. #include "api/video/video_frame.h"
  3. #include "api/video/video_sink_interface.h"
  4. #include "callback.h"
  5. using I420FrameReadyCallback = Callback<const void*,
  6. const void*,
  7. const void*,
  8. const void*,
  9. int,
  10. int,
  11. int,
  12. int,
  13. int,
  14. int>;
  15. using ARGBFrameReadyCallback = Callback<
  16. const uint8_t*,int,
  17. const uint8_t*,int,
  18. const uint8_t*, int,
  19. const int,const int,
  20. const int>;
  21. constexpr inline size_t ArgbDataSize(int height, int stride) {
  22. return static_cast<size_t>(height) * stride * 4;
  23. }
  24. class ArgbBuffer : public webrtc::VideoFrameBuffer {
  25. public:
  26. // Create a new buffer.
  27. static inline rtc::scoped_refptr<ArgbBuffer> Create(int width, int height) {
  28. return new rtc::RefCountedObject<ArgbBuffer>(width, height, width * 4);
  29. }
  30. //// Create a new buffer and copy the pixel data.
  31. // static rtc::scoped_refptr<ArgbBuffer> Copy(const I010BufferInterface&
  32. // buffer);
  33. //// Convert and put I420 buffer into a new buffer.
  34. // static rtc::scoped_refptr<ArgbBuffer> Copy(const I420BufferInterface&
  35. // buffer);
  36. //// Return a rotated copy of |src|.
  37. // static rtc::scoped_refptr<ArgbBuffer> Rotate(const I010BufferInterface&
  38. // src,
  39. // VideoRotation rotation);
  40. // VideoFrameBuffer implementation.
  41. inline Type type() const override { return VideoFrameBuffer::Type::kNative; }
  42. inline int width() const override { return width_; }
  43. inline int height() const override { return height_; }
  44. rtc::scoped_refptr<webrtc::I420BufferInterface> ToI420() override;
  45. inline uint8_t* Data() { return data_.get(); }
  46. inline const uint8_t* Data() const { return data_.get(); }
  47. inline int Stride() const { return stride_; }
  48. inline constexpr size_t Size() const {
  49. return ArgbDataSize(height_, stride_);
  50. }
  51. protected:
  52. ArgbBuffer(int width, int height, int stride) ;
  53. ~ArgbBuffer() override = default;
  54. private:
  55. const int width_;
  56. const int height_;
  57. const int stride_;
  58. const std::unique_ptr<uint8_t, webrtc::AlignedFreeDeleter> data_;
  59. };
  60. /// Video frame observer to get notified of newly available video frames.
  61. class VideoFrameObserver : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
  62. public:
  63. /// Register a callback to get notified on frame available,
  64. /// and received that frame as a I420-encoded buffer.
  65. /// This is not exclusive and can be used along another ARGB callback.
  66. void SetCallback(I420FrameReadyCallback callback) ;
  67. /// Register a callback to get notified on frame available,
  68. /// and received that frame as a raw decoded ARGB buffer.
  69. /// This is not exclusive and can be used along another I420 callback.
  70. void SetCallback(ARGBFrameReadyCallback callback) ;
  71. protected:
  72. ArgbBuffer* GetArgbScratchBuffer(int width, int height);
  73. // VideoSinkInterface interface
  74. void OnFrame(const webrtc::VideoFrame& frame) override;
  75. private:
  76. /// Registered callback for receiving I420-encoded frame.
  77. I420FrameReadyCallback i420_callback_;
  78. /// Registered callback for receiving raw decoded ARGB frame.
  79. ARGBFrameReadyCallback argb_callback_;
  80. /// Mutex protecting all callbacks.
  81. std::mutex mutex_;
  82. /// Reusable ARGB scratch buffer to avoid per-frame allocation.
  83. rtc::scoped_refptr<ArgbBuffer> argb_scratch_buffer_;
  84. };