123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #pragma once
- #include "media/base/video_broadcaster.h"
- #include "api/media_stream_interface.h"
- #include "api/video/i420_buffer.h"
- class VideoScaler : public rtc::VideoSinkInterface<webrtc::VideoFrame>, public rtc::VideoSourceInterface<webrtc::VideoFrame>
- {
- public:
- VideoScaler(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> videoSource, const std::map<std::string, std::string> &opts) :
- m_videoSource(videoSource),
- m_width(0), m_height(0),
- m_rotation(webrtc::kVideoRotation_0)//,
- // m_roi_x(0), m_roi_y(0), m_roi_width(0), m_roi_height(0)
- {
- if (opts.find("width") != opts.end())
- {
- m_width = std::stoi(opts.at("width"));
- }
- if (opts.find("height") != opts.end())
- {
- m_height = std::stoi(opts.at("height"));
- }
- if (opts.find("rotation") != opts.end())
- {
- int rotation = std::stoi(opts.at("rotation"));
- switch (rotation) {
- case 90: m_rotation = webrtc::kVideoRotation_90; break;
- case 180: m_rotation = webrtc::kVideoRotation_180; break;
- case 270: m_rotation = webrtc::kVideoRotation_270; break;
- }
- }
- /*
- if (opts.find("roi_x") != opts.end())
- {
- m_roi_x = std::stoi(opts.at("roi_x"));
- if (m_roi_x < 0)
- {
- RTC_LOG(LS_ERROR) << "Ignore roi_x=" << m_roi_x << ", it muss be >=0";
- m_roi_x = 0;
- }
- }
- if (opts.find("roi_y") != opts.end())
- {
- m_roi_y = std::stoi(opts.at("roi_y"));
- if (m_roi_y < 0)
- {
- RTC_LOG(LS_ERROR) << "Ignore roi_<=" << m_roi_y << ", it muss be >=0";
- m_roi_y = 0;
- }
- }
- if (opts.find("roi_width") != opts.end())
- {
- m_roi_width = std::stoi(opts.at("roi_width"));
- if (m_roi_width <= 0)
- {
- RTC_LOG(LS_ERROR) << "Ignore roi_width<=" << m_roi_width << ", it muss be >0";
- m_roi_width = 0;
- }
- }
- if (opts.find("roi_height") != opts.end())
- {
- m_roi_height = std::stoi(opts.at("roi_height"));
- if (m_roi_height <= 0)
- {
- RTC_LOG(LS_ERROR) << "Ignore roi_height<=" << m_roi_height << ", it muss be >0";
- m_roi_height = 0;
- }
- }
- */
- }
- virtual ~VideoScaler()
- {
- }
- void OnFrame(const webrtc::VideoFrame &frame) override
- {
- /*
- if (m_roi_x >= frame.width())
- {
- RTC_LOG(LS_ERROR) << "The ROI position protrudes beyond the right edge of the image. Ignore roi_x.";
- m_roi_x = 0;
- }
- if (m_roi_y >= frame.height())
- {
- RTC_LOG(LS_ERROR) << "The ROI position protrudes beyond the bottom edge of the image. Ignore roi_y.";
- m_roi_y = 0;
- }
- if (m_roi_width != 0 && (m_roi_width + m_roi_x) > frame.width())
- {
- RTC_LOG(LS_ERROR) << "The ROI protrudes beyond the right edge of the image. Ignore roi_width.";
- m_roi_width = 0;
- }
- if (m_roi_height != 0 && (m_roi_height + m_roi_y) > frame.height())
- {
- RTC_LOG(LS_ERROR) << "The ROI protrudes beyond the bottom edge of the image. Ignore roi_height.";
- m_roi_height = 0;
- }
- if (m_roi_width == 0)
- {
- m_roi_width = frame.width() - m_roi_x;
- }
- if (m_roi_height == 0)
- {
- m_roi_height = frame.height() - m_roi_y;
- }
- // source image is croped but destination image size is not set
- if ((m_roi_width != frame.width() || m_roi_height != frame.height()) && (m_height == 0 && m_width == 0))
- {
- m_height = m_roi_height;
- m_width = m_roi_width;
- }
- if ( ((m_height == 0) && (m_width == 0) && (m_rotation == webrtc::kVideoRotation_0)) || (frame.video_frame_buffer()->type() == webrtc::VideoFrameBuffer::Type::kNative) )
- {
- m_broadcaster.OnFrame(frame);
- }
- else
- {
- int height = m_height;
- int width = m_width;
- if ( (height == 0) && (width == 0) )
- {
- height = frame.height();
- width = frame.width();
- }
- else if (height == 0)
- {
- height = (m_roi_height * width) / m_roi_width;
- }
- else if (width == 0)
- {
- width = (m_roi_width * height) / m_roi_height;
- }
- rtc::scoped_refptr<webrtc::I420Buffer> scaled_buffer = webrtc::I420Buffer::Create(width, height);
- if (m_roi_width != frame.width() || m_roi_height != frame.height())
- {
- scaled_buffer->CropAndScaleFrom(*frame.video_frame_buffer()->ToI420(), m_roi_x, m_roi_y, m_roi_width, m_roi_height);
- }
- else
- {
- scaled_buffer->ScaleFrom(*frame.video_frame_buffer()->ToI420());
- }
- */
- // webrtc::VideoFrame scaledFrame = webrtc::VideoFrame(scaled_buffer, frame.timestamp(),
- // frame.render_time_ms(), m_rotation);
-
- /* if(m_rotation!=webrtc::kVideoRotation_0)
- {
-
- rtc::scoped_refptr<webrtc::I420Buffer> scaled_buffer = webrtc::I420Buffer::Rotate(*frame.video_frame_buffer()->ToI420(),m_rotation);
- std::cout<<scaled_buffer->width()<<","<<scaled_buffer->height()<<std::endl;
-
- // scaled_buffer->ScaleFrom(*frame.video_frame_buffer()->ToI420());
-
-
- // webrtc::VideoFrame scaledFrame = webrtc::VideoFrame::Builder().set_video_frame_buffer(scaled_buffer, m_rotation))
- // .set_rotation(webrtc::kVideoRotation_0).set_timestamp_us(frame.timestamp_us()).set_id(frame.id()).build();
- // webrtc::VideoFrame scaledFrame = webrtc::VideoFrame::Builder().set_video_frame_buffer(webrtc::I420Buffer::Rotate(*frame.video_frame_buffer()->ToI420(), m_rotation))
- // .set_rotation(webrtc::kVideoRotation_0).set_timestamp_us(frame.timestamp_us()).set_id(frame.id()).build();
- webrtc::VideoFrame scaledFrame = webrtc::VideoFrame(scaled_buffer,frame.timestamp(),frame.render_time_ms(),m_rotation);
- // scaledFrame.set_rotation(webrtc::kVideoRotation_0);
- m_broadcaster.OnFrame(scaledFrame);
- }
- else{
- */
-
-
- m_broadcaster.OnFrame(frame);
- // }
- }
- void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame> *sink, const rtc::VideoSinkWants &wants) override
- {
- m_videoSource->AddOrUpdateSink(this,wants);
- m_broadcaster.AddOrUpdateSink(sink, wants);
- }
- void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame> *sink) override
- {
- m_videoSource->RemoveSink(this);
- m_broadcaster.RemoveSink(sink);
- }
- // int width() { return m_roi_width; }
- // int height() { return m_roi_height; }
- private:
- rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> m_videoSource;
- rtc::VideoBroadcaster m_broadcaster;
- int m_width;
- int m_height;
- webrtc::VideoRotation m_rotation;
- /* int m_roi_x;
- int m_roi_y;
- int m_roi_width;
- int m_roi_height;
- */
- };
|