Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -0,0 +1,276 @@
|
|||
//
|
||||
// Created by Grishka on 25/02/2019.
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#include "ScreamCongestionController.h"
|
||||
#include "../logging.h"
|
||||
#include "../VoIPController.h"
|
||||
|
||||
using namespace tgvoip;
|
||||
using namespace tgvoip::video;
|
||||
|
||||
namespace{
|
||||
/*static*/ constexpr float QDELAY_TARGET_LO=0.1f; // seconds
|
||||
/*static*/ constexpr float QDELAY_TARGET_HI=0.4f; // seconds
|
||||
/*static*/ constexpr float QDELAY_WEIGHT=0.1f;
|
||||
/*static*/ constexpr float QDELAY_TREND_TH=0.2f;
|
||||
/*static*/ constexpr uint32_t MIN_CWND=3000; // bytes
|
||||
/*static*/ constexpr float MAX_BYTES_IN_FLIGHT_HEAD_ROOM=1.1f;
|
||||
/*static*/ constexpr float GAIN=1.0f;
|
||||
/*static*/ constexpr float BETA_LOSS=0.8f;
|
||||
/*static*/ constexpr float BETA_ECN=0.9f;
|
||||
/*static*/ constexpr float BETA_R=0.9f;
|
||||
/*static*/ constexpr uint32_t MSS=1024;
|
||||
/*static*/ constexpr float RATE_ADJUST_INTERVAL=0.2f;
|
||||
/*static*/ constexpr uint32_t TARGET_BITRATE_MIN=50*1024; // bps
|
||||
/*static*/ constexpr uint32_t TARGET_BITRATE_MAX=500*1024; // bps
|
||||
/*static*/ constexpr uint32_t RAMP_UP_SPEED=200000; // bps/s
|
||||
/*static*/ constexpr float PRE_CONGESTION_GUARD=0.1f;
|
||||
/*static*/ constexpr float TX_QUEUE_SIZE_FACTOR=1.0f;
|
||||
/*static*/ constexpr float RTP_QDELAY_TH=0.02f; // seconds
|
||||
/*static*/ constexpr float TARGET_RATE_SCALE_RTP_QDELAY=0.95f;
|
||||
/*static*/ constexpr float QDELAY_TREND_LO=0.2f;
|
||||
/*static*/ constexpr float T_RESUME_FAST_INCREASE=5.0f; // seconds
|
||||
/*static*/ constexpr uint32_t RATE_PACE_MIN=50000; // bps
|
||||
}
|
||||
|
||||
ScreamCongestionController::ScreamCongestionController() : qdelayTarget(QDELAY_TARGET_LO), cwnd(MIN_CWND) {
|
||||
|
||||
}
|
||||
|
||||
void ScreamCongestionController::UpdateVariables(float qdelay){
|
||||
float qdelayFraction=qdelay/qdelayTarget;
|
||||
qdelayFractionAvg=(1.0f-QDELAY_WEIGHT)*qdelayFractionAvg+qdelayFraction*QDELAY_WEIGHT;
|
||||
qdelayFractionHist.Add(qdelayFraction);
|
||||
float avg=qdelayFractionHist.Average();
|
||||
|
||||
float r1=0.0, r0=0.0;
|
||||
for(int i=(int)qdelayFractionHist.Size()-1;i>=0;i--){
|
||||
float v=qdelayFractionHist[i]-avg;
|
||||
r0+=v*v;
|
||||
}
|
||||
for(int i=(int)qdelayFractionHist.Size()-1;i>=1;i--){
|
||||
float v1=qdelayFractionHist[i]-avg;
|
||||
float v2=qdelayFractionHist[i-1]-avg;
|
||||
r1+=v1*v2;
|
||||
}
|
||||
float a=r1/r0;
|
||||
qdelayTrend=std::min(1.0f, std::max(0.0f, a*qdelayFractionAvg));
|
||||
qdelayTrendMem=std::max(0.99f*qdelayTrendMem, qdelayTrend);
|
||||
|
||||
if(qdelayTrend>QDELAY_TREND_LO){
|
||||
lastTimeQDelayTrendWasGreaterThanLo=VoIPController::GetCurrentTime();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreamCongestionController::UpdateCWnd(float qdelay){
|
||||
if(inFastIncrease){
|
||||
if(qdelayTrend>=QDELAY_TREND_TH){
|
||||
inFastIncrease=false;
|
||||
}else{
|
||||
if((float)bytesInFlight*1.5f+bytesNewlyAcked>cwnd){
|
||||
LOGD("HERE");
|
||||
cwnd+=bytesNewlyAcked;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float offTarget=(qdelayTarget-qdelay)/qdelayTarget;
|
||||
|
||||
float gain=GAIN;
|
||||
float cwndDelta=gain*offTarget*bytesNewlyAcked*MSS/(float)cwnd;
|
||||
if(offTarget>0 && (float)bytesInFlight*1.25f+bytesNewlyAcked<=cwnd){
|
||||
cwndDelta=0.0;
|
||||
}
|
||||
cwnd+=cwndDelta;
|
||||
cwnd=std::min(cwnd, (uint32_t)(maxBytesInFlight*MAX_BYTES_IN_FLIGHT_HEAD_ROOM));
|
||||
cwnd=std::max(cwnd, MIN_CWND);
|
||||
}
|
||||
|
||||
void ScreamCongestionController::AdjustQDelayTarget(float qdelay){
|
||||
float qdelayNorm=qdelay/QDELAY_TARGET_LO;
|
||||
qdelayNormHist.Add(qdelayNorm);
|
||||
|
||||
float qdelayNormAvg=qdelayNormHist.Average();
|
||||
float qdelayNormVar=0.0;
|
||||
for(uint32_t i=0;i<qdelayNormHist.Size();i++){
|
||||
float tmp=qdelayNormHist[i]-qdelayNormAvg;
|
||||
qdelayNormVar+=tmp*tmp;
|
||||
}
|
||||
qdelayNormVar/=qdelayNormHist.Size();
|
||||
|
||||
float newTarget=qdelayNormAvg+sqrt(qdelayNormVar);
|
||||
newTarget*=QDELAY_TARGET_LO;
|
||||
|
||||
if(lossEventRate>0.002f){
|
||||
qdelayTarget=1.5f*newTarget;
|
||||
}else{
|
||||
if(qdelayNormVar<0.2f){
|
||||
qdelayTarget=newTarget;
|
||||
}else{
|
||||
if(newTarget<QDELAY_TARGET_LO){
|
||||
qdelayTarget=std::max(qdelayTarget*0.5f, newTarget);
|
||||
}else{
|
||||
qdelayTarget*=0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qdelayTarget=std::min(QDELAY_TARGET_HI, qdelayTarget);
|
||||
qdelayTarget=std::max(QDELAY_TARGET_LO, qdelayTarget);
|
||||
}
|
||||
|
||||
void ScreamCongestionController::AdjustBitrate(){
|
||||
if(lossPending){
|
||||
lossPending=false;
|
||||
targetBitrate=std::max((uint32_t)(BETA_R*(float)targetBitrate), TARGET_BITRATE_MIN);
|
||||
return;
|
||||
}
|
||||
|
||||
float rampUpSpeed=std::min(RAMP_UP_SPEED, targetBitrate/2);
|
||||
float scale=(float)(targetBitrate-targetBitrateLastMax)/(float)targetBitrateLastMax;
|
||||
scale=std::max(0.2f, std::min(1.0f, (scale*4)*(scale*4)));
|
||||
float currentRate=std::max(rateTransmit, rateAck);
|
||||
|
||||
if(inFastIncrease){
|
||||
float increment=(rampUpSpeed*RATE_ADJUST_INTERVAL)*scale;
|
||||
targetBitrate+=increment;
|
||||
}else{
|
||||
float deltaRate=currentRate*(1.0f-PRE_CONGESTION_GUARD*qdelayTrend)-TX_QUEUE_SIZE_FACTOR*(float)rtpQueueSize;
|
||||
if(deltaRate>0.0f){
|
||||
deltaRate*=scale;
|
||||
deltaRate=std::min(deltaRate, rampUpSpeed*RATE_ADJUST_INTERVAL);
|
||||
}
|
||||
targetBitrate+=deltaRate;
|
||||
float rtpQueueDelay=(float)rtpQueueSize/currentRate;
|
||||
if(rtpQueueDelay>RTP_QDELAY_TH){
|
||||
targetBitrate=(uint32_t)((float)targetBitrate*TARGET_RATE_SCALE_RTP_QDELAY);
|
||||
}
|
||||
}
|
||||
|
||||
float rateMediaLimit=std::max(currentRate, std::max(rateMedia, rateMediaMedian));
|
||||
rateMediaLimit*=(2.0-qdelayTrendMem);
|
||||
targetBitrate=std::min(targetBitrate, (uint32_t)rateMediaLimit);
|
||||
targetBitrate=std::min(TARGET_BITRATE_MAX, std::max(TARGET_BITRATE_MIN, targetBitrate));
|
||||
}
|
||||
|
||||
void ScreamCongestionController::CalculateSendWindow(float qdelay){
|
||||
if(qdelay<=qdelayTarget)
|
||||
sendWnd=cwnd+MSS-bytesInFlight;
|
||||
else
|
||||
sendWnd=cwnd-bytesInFlight;
|
||||
}
|
||||
|
||||
void ScreamCongestionController::ProcessAcks(float oneWayDelay, uint32_t bytesNewlyAcked, uint32_t lossCount, double rtt){
|
||||
if(prevOneWayDelay!=0.0f){
|
||||
double currentTime=VoIPController::GetCurrentTime();
|
||||
float qdelay=oneWayDelay-prevOneWayDelay;
|
||||
sRTT=(float)rtt;
|
||||
bytesInFlight-=bytesNewlyAcked;
|
||||
rtpQueueSize-=(bytesNewlyAcked*8);
|
||||
UpdateBytesInFlightHistory();
|
||||
bytesAcked+=bytesNewlyAcked;
|
||||
//LOGV("Scream: qdelay = %f, newly acked = %u, in flight = %u, losses = %u", qdelay, bytesNewlyAcked, bytesInFlight, lossCount);
|
||||
if(currentTime-lastVariablesUpdateTime>=0.050){
|
||||
lastVariablesUpdateTime=currentTime;
|
||||
UpdateVariables(qdelay);
|
||||
}
|
||||
if(currentTime-lastRateAdjustmentTime>=RATE_ADJUST_INTERVAL){
|
||||
lastRateAdjustmentTime=currentTime;
|
||||
AdjustBitrate();
|
||||
//LOGV("Scream: target bitrate = %u", targetBitrate);
|
||||
}
|
||||
if(lossCount>prevLossCount && currentTime>ignoreLossesUntil){
|
||||
LOGD("Scream: loss detected");
|
||||
ignoreLossesUntil=currentTime+rtt;
|
||||
inFastIncrease=false;
|
||||
cwnd=std::max(MIN_CWND, (uint32_t)(cwnd*BETA_LOSS));
|
||||
AdjustQDelayTarget(qdelay);
|
||||
CalculateSendWindow(qdelay);
|
||||
lossPending=true;
|
||||
prevLossCount=lossCount;
|
||||
lastTimeQDelayTrendWasGreaterThanLo=currentTime;
|
||||
}else{
|
||||
this->bytesNewlyAcked+=bytesNewlyAcked;
|
||||
if(currentTime-lastCWndUpdateTime>=0.15){
|
||||
lastCWndUpdateTime=currentTime;
|
||||
UpdateCWnd(qdelay);
|
||||
//LOGI("Scream: cwnd = %u", cwnd);
|
||||
this->bytesNewlyAcked=0;
|
||||
}
|
||||
AdjustQDelayTarget(qdelay);
|
||||
CalculateSendWindow(qdelay);
|
||||
if(!inFastIncrease){
|
||||
if(currentTime-lastTimeQDelayTrendWasGreaterThanLo>=T_RESUME_FAST_INCREASE){
|
||||
inFastIncrease=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prevOneWayDelay=oneWayDelay;
|
||||
}
|
||||
|
||||
void ScreamCongestionController::ProcessPacketSent(uint32_t size){
|
||||
bytesInFlight+=size;
|
||||
rtpQueueSize+=(size*8);
|
||||
bytesSent+=size;
|
||||
double currentTime=VoIPController::GetCurrentTime();
|
||||
if(currentTime-rateTransmitUpdateTime>=0.2){
|
||||
rateTransmit=(float)(bytesSent*8)/(float)(currentTime-rateTransmitUpdateTime);
|
||||
rateAck=(float)(bytesAcked*8)/(float)(currentTime-rateTransmitUpdateTime);
|
||||
rateTransmitUpdateTime=currentTime;
|
||||
bytesSent=0;
|
||||
bytesAcked=0;
|
||||
//LOGV("rateTransmit %f, rateAck %f", rateTransmit, rateAck);
|
||||
}
|
||||
UpdateBytesInFlightHistory();
|
||||
}
|
||||
|
||||
void ScreamCongestionController::ProcessPacketLost(uint32_t size){
|
||||
bytesInFlight-=size;
|
||||
rtpQueueSize-=(size*8);
|
||||
UpdateBytesInFlightHistory();
|
||||
}
|
||||
|
||||
double ScreamCongestionController::GetPacingInterval(){
|
||||
float paceBitrate=std::max((float)RATE_PACE_MIN, cwnd*8.0f/sRTT);
|
||||
//LOGV("RTT=%f cwnd=%u paceBitrate=%f fastIncrease=%d", sRTT, cwnd, paceBitrate, inFastIncrease);
|
||||
double pacingInterval=rtpSize*8.0f/paceBitrate;
|
||||
return std::min(0.010, pacingInterval);
|
||||
}
|
||||
|
||||
void ScreamCongestionController::UpdateBytesInFlightHistory(){
|
||||
double currentTime=VoIPController::GetCurrentTime();
|
||||
ValueSample now={bytesInFlight, currentTime};
|
||||
bytesInFlightHistory.push_back(now);
|
||||
uint32_t max=0;
|
||||
for(std::vector<ValueSample>::iterator i=bytesInFlightHistory.begin();i!=bytesInFlightHistory.end();){
|
||||
if(currentTime-i->time>=5.0){
|
||||
i=bytesInFlightHistory.erase(i);
|
||||
}else{
|
||||
max=std::max(max, i->sample);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
maxBytesInFlight=max;
|
||||
}
|
||||
|
||||
void ScreamCongestionController::UpdateMediaRate(uint32_t frameSize){
|
||||
bytesMedia+=frameSize;
|
||||
double currentTime=VoIPController::GetCurrentTime();
|
||||
if(currentTime-rateMediaUpdateTime>=0.5){
|
||||
rateMedia=(float)(bytesMedia*8)/(float)(currentTime-rateMediaUpdateTime);
|
||||
bytesMedia=0;
|
||||
rateMediaUpdateTime=currentTime;
|
||||
LOGV("rateMedia %f", rateMedia);
|
||||
rateMediaHistory.Add(rateMedia);
|
||||
rateMediaMedian=rateMediaHistory.NonZeroAverage();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ScreamCongestionController::GetBitrate(){
|
||||
return targetBitrate;
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// Created by Grishka on 25/02/2019.
|
||||
//
|
||||
|
||||
#ifndef LIBTGVOIP_SCREAMCONGESTIONCONTROLLER_H
|
||||
#define LIBTGVOIP_SCREAMCONGESTIONCONTROLLER_H
|
||||
|
||||
#include "../Buffers.h"
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace tgvoip{
|
||||
namespace video{
|
||||
class ScreamCongestionController{
|
||||
public:
|
||||
ScreamCongestionController();
|
||||
void AdjustBitrate();
|
||||
void ProcessAcks(float oneWayDelay, uint32_t bytesNewlyAcked, uint32_t lossCount, double rtt);
|
||||
void ProcessPacketSent(uint32_t size);
|
||||
void ProcessPacketLost(uint32_t size);
|
||||
double GetPacingInterval();
|
||||
void UpdateMediaRate(uint32_t frameSize);
|
||||
uint32_t GetBitrate();
|
||||
|
||||
private:
|
||||
void UpdateVariables(float qdelay);
|
||||
void UpdateCWnd(float qdelay);
|
||||
void AdjustQDelayTarget(float qdelay);
|
||||
void CalculateSendWindow(float qdelay);
|
||||
|
||||
void UpdateBytesInFlightHistory();
|
||||
|
||||
struct ValueSample{
|
||||
uint32_t sample;
|
||||
double time;
|
||||
};
|
||||
|
||||
float qdelayTarget;
|
||||
float qdelayFractionAvg=0.0f;
|
||||
HistoricBuffer<float, 20> qdelayFractionHist;
|
||||
float qdelayTrend=0.0f;
|
||||
float qdelayTrendMem=0.0f;
|
||||
HistoricBuffer<float, 100> qdelayNormHist;
|
||||
bool inFastIncrease=true;
|
||||
uint32_t cwnd;
|
||||
uint32_t bytesNewlyAcked=0;
|
||||
uint32_t maxBytesInFlight=0;
|
||||
uint32_t sendWnd=0;
|
||||
uint32_t targetBitrate=0;
|
||||
uint32_t targetBitrateLastMax=1;
|
||||
float rateTransmit=0.0f;
|
||||
float rateAck=0.0f;
|
||||
float rateMedia=0.0f;
|
||||
float rateMediaMedian=0.0f;
|
||||
float sRTT=0.0f;
|
||||
uint32_t rtpQueueSize=0;
|
||||
uint32_t rtpSize=1024; //0;
|
||||
float lossEventRate=0.0f;
|
||||
|
||||
bool lossPending=false;
|
||||
float prevOneWayDelay=0.0f;
|
||||
double ignoreLossesUntil=0.0;
|
||||
uint32_t prevLossCount=0;
|
||||
double lastTimeQDelayTrendWasGreaterThanLo=0.0;
|
||||
double lastVariablesUpdateTime=0.0;
|
||||
double lastRateAdjustmentTime=0.0;
|
||||
double lastCWndUpdateTime=0.0;
|
||||
uint32_t bytesInFlight=0;
|
||||
std::vector<ValueSample> bytesInFlightHistory;
|
||||
uint32_t bytesSent=0;
|
||||
uint32_t bytesAcked=0;
|
||||
uint32_t bytesMedia=0;
|
||||
double rateTransmitUpdateTime=0.0;
|
||||
double rateMediaUpdateTime=0.0;
|
||||
HistoricBuffer<float, 25> rateMediaHistory;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //LIBTGVOIP_SCREAMCONGESTIONCONTROLLER_H
|
||||
29
TMessagesProj/jni/voip/libtgvoip/video/VideoRenderer.cpp
Normal file
29
TMessagesProj/jni/voip/libtgvoip/video/VideoRenderer.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// Created by Grishka on 10.08.2018.
|
||||
//
|
||||
|
||||
#include "VideoRenderer.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "../os/android/VideoRendererAndroid.h"
|
||||
#elif defined(__APPLE__) && !defined(TARGET_OSX32)
|
||||
#include "../os/darwin/SampleBufferDisplayLayerRenderer.h"
|
||||
#endif
|
||||
|
||||
std::vector<uint32_t> tgvoip::video::VideoRenderer::GetAvailableDecoders(){
|
||||
#ifdef __ANDROID__
|
||||
return VideoRendererAndroid::availableDecoders;
|
||||
#elif defined(__APPLE__)
|
||||
return SampleBufferDisplayLayerRenderer::GetAvailableDecoders();
|
||||
#endif
|
||||
return std::vector<uint32_t>();
|
||||
}
|
||||
|
||||
int tgvoip::video::VideoRenderer::GetMaximumResolution(){
|
||||
#ifdef __ANDROID__
|
||||
return VideoRendererAndroid::maxResolution;
|
||||
#elif defined(__APPLE__) && !defined(TARGET_OSX32)
|
||||
return SampleBufferDisplayLayerRenderer::GetMaximumResolution();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
26
TMessagesProj/jni/voip/libtgvoip/video/VideoRenderer.h
Normal file
26
TMessagesProj/jni/voip/libtgvoip/video/VideoRenderer.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Created by Grishka on 10.08.2018.
|
||||
//
|
||||
|
||||
#ifndef LIBTGVOIP_VIDEORENDERER_H
|
||||
#define LIBTGVOIP_VIDEORENDERER_H
|
||||
|
||||
#include <vector>
|
||||
#include "../Buffers.h"
|
||||
|
||||
namespace tgvoip{
|
||||
namespace video{
|
||||
class VideoRenderer{
|
||||
public:
|
||||
static std::vector<uint32_t> GetAvailableDecoders();
|
||||
virtual ~VideoRenderer(){};
|
||||
virtual void Reset(uint32_t codec, unsigned int width, unsigned int height, std::vector<Buffer>& csd)=0;
|
||||
virtual void DecodeAndDisplay(Buffer frame, uint32_t pts)=0;
|
||||
virtual void SetStreamEnabled(bool enabled)=0;
|
||||
virtual void SetRotation(uint16_t rotation)=0;
|
||||
static int GetMaximumResolution();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //LIBTGVOIP_VIDEORENDERER_H
|
||||
44
TMessagesProj/jni/voip/libtgvoip/video/VideoSource.cpp
Executable file
44
TMessagesProj/jni/voip/libtgvoip/video/VideoSource.cpp
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// Created by Grishka on 10.08.2018.
|
||||
//
|
||||
|
||||
#include "VideoSource.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "../os/android/VideoSourceAndroid.h"
|
||||
#elif defined(__APPLE__) && !defined(TARGET_OSX32)
|
||||
#include "../os/darwin/VideoToolboxEncoderSource.h"
|
||||
#endif
|
||||
|
||||
using namespace tgvoip;
|
||||
using namespace tgvoip::video;
|
||||
|
||||
std::shared_ptr<VideoSource> VideoSource::Create(){
|
||||
#ifdef __ANDROID__
|
||||
//return std::make_shared<VideoSourceAndroid>();
|
||||
return nullptr;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void VideoSource::SetCallback(std::function<void(const Buffer &, uint32_t, uint32_t)> callback){
|
||||
this->callback=callback;
|
||||
}
|
||||
|
||||
bool VideoSource::Failed(){
|
||||
return failed;
|
||||
}
|
||||
|
||||
std::string VideoSource::GetErrorDescription(){
|
||||
return error;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> VideoSource::GetAvailableEncoders(){
|
||||
#ifdef __ANDROID__
|
||||
return VideoSourceAndroid::availableEncoders;
|
||||
#elif defined(__APPLE__) && !defined(TARGET_OSX32)
|
||||
return VideoToolboxEncoderSource::GetAvailableEncoders();
|
||||
#endif
|
||||
return std::vector<uint32_t>();
|
||||
}
|
||||
54
TMessagesProj/jni/voip/libtgvoip/video/VideoSource.h
Normal file
54
TMessagesProj/jni/voip/libtgvoip/video/VideoSource.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// Created by Grishka on 10.08.2018.
|
||||
//
|
||||
|
||||
#ifndef LIBTGVOIP_VIDEOSOURCE_H
|
||||
#define LIBTGVOIP_VIDEOSOURCE_H
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "../Buffers.h"
|
||||
|
||||
namespace tgvoip{
|
||||
namespace video {
|
||||
class VideoSource{
|
||||
public:
|
||||
virtual ~VideoSource(){};
|
||||
static std::shared_ptr<VideoSource> Create();
|
||||
static std::vector<uint32_t> GetAvailableEncoders();
|
||||
void SetCallback(std::function<void(const Buffer& buffer, uint32_t flags, uint32_t rotation)> callback);
|
||||
virtual void Start()=0;
|
||||
virtual void Stop()=0;
|
||||
virtual void Reset(uint32_t codec, int maxResolution)=0;
|
||||
virtual void RequestKeyFrame()=0;
|
||||
virtual void SetBitrate(uint32_t bitrate)=0;
|
||||
bool Failed();
|
||||
std::string GetErrorDescription();
|
||||
std::vector<Buffer>& GetCodecSpecificData(){
|
||||
return csd;
|
||||
}
|
||||
unsigned int GetFrameWidth(){
|
||||
return width;
|
||||
}
|
||||
unsigned int GetFrameHeight(){
|
||||
return height;
|
||||
}
|
||||
void SetRotation(unsigned int rotation){
|
||||
this->rotation=rotation;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::function<void(const Buffer &, uint32_t, uint32_t)> callback;
|
||||
bool failed;
|
||||
std::string error;
|
||||
unsigned int width=0;
|
||||
unsigned int height=0;
|
||||
unsigned int rotation=0;
|
||||
std::vector<Buffer> csd;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //LIBTGVOIP_VIDEOSOURCE_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue