From 3f1ebca8032e7efd44389b1f2efb246c99710599 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 24 Aug 2015 21:15:33 -0400 Subject: [PATCH] added max bandwidth test preview and in/out bw estimate. Still missing the logic inside the codec --- plugins/VOIP/gui/AudioInputConfig.cpp | 9 ++++ plugins/VOIP/gui/AudioInputConfig.h | 5 ++- plugins/VOIP/gui/AudioInputConfig.ui | 35 ++++++++++++++- plugins/VOIP/gui/QVideoDevice.cpp | 32 +++---------- plugins/VOIP/gui/QVideoDevice.h | 6 +-- plugins/VOIP/gui/VOIPChatWidgetHolder.cpp | 2 +- plugins/VOIP/gui/VideoProcessor.cpp | 55 +++++++++++++++++++---- plugins/VOIP/gui/VideoProcessor.h | 21 +++++++-- 8 files changed, 120 insertions(+), 45 deletions(-) diff --git a/plugins/VOIP/gui/AudioInputConfig.cpp b/plugins/VOIP/gui/AudioInputConfig.cpp index 5f6aacfb8..6ef39bce5 100644 --- a/plugins/VOIP/gui/AudioInputConfig.cpp +++ b/plugins/VOIP/gui/AudioInputConfig.cpp @@ -120,6 +120,8 @@ AudioInputConfig::AudioInputConfig(QWidget * parent, Qt::WindowFlags flags) videoProcessor = new VideoProcessor() ; videoProcessor->setDisplayTarget(NULL) ; + videoProcessor->setMaximumBandwidth(ui.availableBW_SB->value()) ; + videoInput->setVideoProcessor(videoProcessor) ; graph_source = new voipGraphSource ; @@ -130,8 +132,15 @@ AudioInputConfig::AudioInputConfig(QWidget * parent, Qt::WindowFlags flags) graph_source->start() ; QObject::connect(ui.showEncoded_CB,SIGNAL(toggled(bool)),this,SLOT(togglePreview(bool))) ; + QObject::connect(ui.availableBW_SB,SIGNAL(valueChanged(double)),this,SLOT(updateAvailableBW(double))) ; } +void AudioInputConfig::updateAvailableBW(double r) +{ + std::cerr << "Setting max bandwidth to " << r << " KB/s" << std::endl; + videoProcessor->setMaximumBandwidth((uint32_t)(r*1024)) ; +} + void AudioInputConfig::togglePreview(bool b) { if(b) diff --git a/plugins/VOIP/gui/AudioInputConfig.h b/plugins/VOIP/gui/AudioInputConfig.h index e838744b4..ef53c28e9 100644 --- a/plugins/VOIP/gui/AudioInputConfig.h +++ b/plugins/VOIP/gui/AudioInputConfig.h @@ -93,8 +93,9 @@ class AudioInputConfig : public ConfigPage virtual QPixmap iconPixmap() const { return QPixmap(":/images/talking_on.svg") ; } virtual QString pageName() const { return tr("VOIP") ; } virtual QString helpText() const { return ""; } - - private slots: + +private slots: + void updateAvailableBW(double r); void loadSettings(); void emptyBuffer(); void togglePreview(bool) ; diff --git a/plugins/VOIP/gui/AudioInputConfig.ui b/plugins/VOIP/gui/AudioInputConfig.ui index 7b77fb3a9..71ed06569 100644 --- a/plugins/VOIP/gui/AudioInputConfig.ui +++ b/plugins/VOIP/gui/AudioInputConfig.ui @@ -7,7 +7,7 @@ 0 0 1155 - 713 + 832 @@ -391,6 +391,39 @@ + + + + + + Available bandwidth: + + + + + + + <html><head/><body><p>Use this field to simulate the maximum bandwidth available so as to preview what the encoded video will look like with the corresponding compression rate.</p></body></html> + + + KB/s + + + 1 + + + 5.000000000000000 + + + 200.000000000000000 + + + 30.000000000000000 + + + + + diff --git a/plugins/VOIP/gui/QVideoDevice.cpp b/plugins/VOIP/gui/QVideoDevice.cpp index c3deac879..516933807 100644 --- a/plugins/VOIP/gui/QVideoDevice.cpp +++ b/plugins/VOIP/gui/QVideoDevice.cpp @@ -13,9 +13,6 @@ QVideoInputDevice::QVideoInputDevice(QWidget *parent) _capture_device = NULL ; _video_processor = NULL ; _echo_output_device = NULL ; - _estimated_bw = 0 ; - _total_encoded_size = 0 ; - _last_bw_estimate_TS = time(NULL) ; } void QVideoInputDevice::stop() @@ -80,27 +77,7 @@ void QVideoInputDevice::grabFrame() if(_video_processor != NULL) { - uint32_t encoded_size ; - - _video_processor->processImage(image,0,encoded_size) ; -#ifdef DEBUG_VIDEO_OUTPUT_DEVICE - std::cerr << "Encoded size = " << encoded_size << std::endl; -#endif - _total_encoded_size += encoded_size ; - - time_t now = time(NULL) ; - - if(now > _last_bw_estimate_TS) - { - _estimated_bw = uint32_t(0.75*_estimated_bw + 0.25 * (_total_encoded_size / (float)(now - _last_bw_estimate_TS))) ; - - _total_encoded_size = 0 ; - _last_bw_estimate_TS = now ; - -#ifdef DEBUG_VIDEO_OUTPUT_DEVICE - std::cerr << "new bw estimate: " << _estimated_bw << std::endl; -#endif - } + _video_processor->processImage(image,0) ; emit networkPacketReady() ; } @@ -113,7 +90,12 @@ bool QVideoInputDevice::getNextEncodedPacket(RsVOIPDataChunk& chunk) if(_video_processor) return _video_processor->nextEncodedPacket(chunk) ; else - return false ; + return false ; +} + +uint32_t QVideoInputDevice::currentBandwidth() const +{ + return _video_processor->currentBandwidthOut() ; } QVideoInputDevice::~QVideoInputDevice() diff --git a/plugins/VOIP/gui/QVideoDevice.h b/plugins/VOIP/gui/QVideoDevice.h index d12fe5f38..20a837446 100644 --- a/plugins/VOIP/gui/QVideoDevice.h +++ b/plugins/VOIP/gui/QVideoDevice.h @@ -45,7 +45,7 @@ class QVideoInputDevice: public QObject // gets the estimated current bandwidth required to transmit the encoded data, in B/s // - uint32_t currentBandwidth() const { return _estimated_bw ; } + uint32_t currentBandwidth() const ; // control @@ -66,9 +66,5 @@ class QVideoInputDevice: public QObject QVideoOutputDevice *_echo_output_device ; std::list _out_queue ; - - uint32_t _estimated_bw ; - time_t _last_bw_estimate_TS; - uint32_t _total_encoded_size ; }; diff --git a/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp b/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp index 4d1f8ff49..f8760132d 100644 --- a/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp +++ b/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp @@ -365,7 +365,7 @@ void VOIPChatWidgetHolder::botMouseLeave() void VOIPChatWidgetHolder::setAcceptedBandwidth(uint32_t bytes_per_sec) { - videoProcessor->setMaximumFrameRate(bytes_per_sec) ; + videoProcessor->setMaximumBandwidth(bytes_per_sec) ; } void VOIPChatWidgetHolder::addAudioData(const RsPeerId &peer_id, QByteArray* array) diff --git a/plugins/VOIP/gui/VideoProcessor.cpp b/plugins/VOIP/gui/VideoProcessor.cpp index 51c97b780..c4934ee0c 100644 --- a/plugins/VOIP/gui/VideoProcessor.cpp +++ b/plugins/VOIP/gui/VideoProcessor.cpp @@ -32,9 +32,19 @@ VideoProcessor::VideoProcessor() //_encoding_current_codec = VIDEO_PROCESSOR_CODEC_ID_JPEG_VIDEO; //_encoding_current_codec = VIDEO_PROCESSOR_CODEC_ID_DDWT_VIDEO; _encoding_current_codec = VIDEO_PROCESSOR_CODEC_ID_MPEG_VIDEO; + + _estimated_bandwidth_in = 0 ; + _estimated_bandwidth_out = 0 ; + _target_bandwidth_out = 0 ; + + _total_encoded_size_in = 0 ; + _total_encoded_size_out = 0 ; + + _last_bw_estimate_in_TS = time(NULL) ; + _last_bw_estimate_out_TS = time(NULL) ; } -bool VideoProcessor::processImage(const QImage& img,uint32_t size_hint,uint32_t& encoded_size) +bool VideoProcessor::processImage(const QImage& img,uint32_t size_hint) { VideoCodec *codec ; @@ -52,17 +62,30 @@ bool VideoProcessor::processImage(const QImage& img,uint32_t size_hint,uint32_t& // std::cerr << "reducing to " << _frame_size.width() << " x " << _frame_size.height() << std::endl; - encoded_size = 0 ; - if(codec) { RsVOIPDataChunk chunk ; if(codec->encodeData(img.scaled(_encoded_frame_size,Qt::IgnoreAspectRatio,Qt::SmoothTransformation),size_hint,chunk) && chunk.size > 0) - { - encoded_size = chunk.size ; - _encoded_out_queue.push_back(chunk) ; - } + { + _encoded_out_queue.push_back(chunk) ; + + _total_encoded_size_out += chunk.size ; + } + + time_t now = time(NULL) ; + + if(now > _last_bw_estimate_out_TS) + { + _estimated_bandwidth_out = uint32_t(0.75*_estimated_bandwidth_out + 0.25 * (_total_encoded_size_out / (float)(now - _last_bw_estimate_out_TS))) ; + + _total_encoded_size_out = 0 ; + _last_bw_estimate_out_TS = now ; + +#ifdef DEBUG_VIDEO_OUTPUT_DEVICE + std::cerr << "new bw estimate: " << _estimated_bw << std::endl; +#endif + } return true ; } @@ -134,6 +157,21 @@ void VideoProcessor::receiveEncodedData(const RsVOIPDataChunk& chunk) return ; } + _total_encoded_size_in += chunk.size ; + + time_t now = time(NULL) ; + + if(now > _last_bw_estimate_in_TS) + { + _estimated_bandwidth_in = uint32_t(0.75*_estimated_bandwidth_in + 0.25 * (_total_encoded_size_in / (float)(now - _last_bw_estimate_in_TS))) ; + + _total_encoded_size_in = 0 ; + _last_bw_estimate_in_TS = now ; + +#ifdef DEBUG_VIDEO_OUTPUT_DEVICE + std::cerr << "new bw estimate (in): " << _estimated_bandwidth_in << std::endl; +#endif + } if(!codec->decodeData(chunk,img)) { std::cerr << "No image decoded. Probably in the middle of something..." << std::endl; @@ -144,9 +182,10 @@ void VideoProcessor::receiveEncodedData(const RsVOIPDataChunk& chunk) _decoded_output_device->showFrame(img) ; } -void VideoProcessor::setMaximumFrameRate(uint32_t bytes_per_sec) +void VideoProcessor::setMaximumBandwidth(uint32_t bytes_per_sec) { std::cerr << "Video Encoder: maximum frame rate is set to " << bytes_per_sec << " Bps" << std::endl; + _target_bandwidth_out = bytes_per_sec ; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/VOIP/gui/VideoProcessor.h b/plugins/VOIP/gui/VideoProcessor.h index f5057e5e4..230c9dc9b 100644 --- a/plugins/VOIP/gui/VideoProcessor.h +++ b/plugins/VOIP/gui/VideoProcessor.h @@ -117,7 +117,7 @@ class VideoProcessor // returns the current (measured) frame rate in bytes per second. // - uint32_t currentDecodingFrameRate() const; + uint32_t currentBandwidthIn() const { return _estimated_bandwidth_in ; } private: QVideoOutputDevice *_decoded_output_device ; @@ -130,15 +130,19 @@ class VideoProcessor public: // Takes the next image to be encoded. // - bool processImage(const QImage& Image, uint32_t size_hint, uint32_t &encoded_size) ; + bool processImage(const QImage& Image, uint32_t size_hint) ; bool encodedPacketReady() const { return !_encoded_out_queue.empty() ; } bool nextEncodedPacket(RsVOIPDataChunk& ) ; // Used to tweak the compression ratio so that the video can stream ok. // - void setMaximumFrameRate(uint32_t bytes_per_second) ; + void setMaximumBandwidth(uint32_t bytes_per_second) ; void setInternalFrameSize(QSize) ; + // returns the current encoding frame rate in bytes per second. + // + uint32_t currentBandwidthOut() const { return _estimated_bandwidth_out ; } + protected: std::list _encoded_out_queue ; QSize _encoded_frame_size ; @@ -152,5 +156,16 @@ class VideoProcessor FFmpegVideo _mpeg_video_codec ; uint16_t _encoding_current_codec ; + + time_t _last_bw_estimate_in_TS; + time_t _last_bw_estimate_out_TS; + + uint32_t _total_encoded_size_in ; + uint32_t _total_encoded_size_out ; + + float _estimated_bandwidth_in ; + float _estimated_bandwidth_out ; + + float _target_bandwidth_out ; };