added max bandwidth test preview and in/out bw estimate. Still missing the logic inside the codec

This commit is contained in:
csoler 2015-08-24 21:15:33 -04:00
parent 79aac23b6c
commit 3f1ebca803
8 changed files with 120 additions and 45 deletions

View File

@ -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)

View File

@ -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) ;

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1155</width>
<height>713</height>
<height>832</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@ -391,6 +391,39 @@
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Available bandwidth:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="availableBW_SB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string>KB/s</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>5.000000000000000</double>
</property>
<property name="maximum">
<double>200.000000000000000</double>
</property>
<property name="value">
<double>30.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="showEncoded_CB">
<property name="toolTip">

View File

@ -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()

View File

@ -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<RsVOIPDataChunk> _out_queue ;
uint32_t _estimated_bw ;
time_t _last_bw_estimate_TS;
uint32_t _total_encoded_size ;
};

View File

@ -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)

View File

@ -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 ;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -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<RsVOIPDataChunk> _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 ;
};