1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-26 20:24:38 +01:00
This commit is contained in:
Grishka 2019-04-24 19:36:32 +03:00
parent a121aef1a9
commit bb25caf814
10 changed files with 78 additions and 66 deletions

View File

@ -41,7 +41,7 @@ tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):que
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(1));
opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO));
requestedBitrate=20000;
currentBitrate=0;
running=false;
@ -59,9 +59,7 @@ tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):que
secondaryEncoder=opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL);
opus_encoder_ctl(secondaryEncoder, OPUS_SET_COMPLEXITY(10));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
//opus_encoder_ctl(secondaryEncoder, OPUS_SET_VBR(0));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(8000));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(secondaryEnabledBandwidth));
}else{
secondaryEncoder=NULL;
}
@ -107,9 +105,11 @@ void tgvoip::OpusEncoder::Encode(int16_t* data, size_t len){
levelMeter->Update(data, len);
if(secondaryEncoderEnabled!=wasSecondaryEncoderEnabled){
wasSecondaryEncoderEnabled=secondaryEncoderEnabled;
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(secondaryEncoderEnabled ? secondaryEnabledBandwidth : OPUS_BANDWIDTH_FULLBAND));
}
int32_t r=opus_encode(enc, data, static_cast<int>(len), buffer, 4096);
// int bw;
// opus_encoder_ctl(enc, OPUS_GET_BANDWIDTH(&bw));
// LOGV("Opus bandwidth: %d", bw);
if(r<=0){
LOGE("Error encoding: %d", r);
}else if(r==1){
@ -185,27 +185,21 @@ void tgvoip::OpusEncoder::RunThread(){
if(vadMode){
if(frameHasVoice){
opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate));
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(vadModeVoiceBandwidth));
if(secondaryEncoder){
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(vadModeVoiceBandwidth));
}
}else{
opus_encoder_ctl(enc, OPUS_SET_BITRATE(vadNoVoiceBitrate));
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(vadModeNoVoiceBandwidth));
if(secondaryEncoder){
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(vadNoVoiceBitrate));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(vadModeNoVoiceBandwidth));
}
}
wasVadMode=true;
}else if(wasVadMode){
wasVadMode=false;
opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate));
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(secondaryEncoderEnabled ? secondaryEnabledBandwidth : OPUS_AUTO));
if(secondaryEncoder){
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(secondaryEnabledBandwidth));
}
}
Encode(frame, 960*packetsPerFrame);

View File

@ -3303,7 +3303,7 @@ void VoIPController::SendPacketReliably(unsigned char type, unsigned char *data,
void VoIPController::SendExtra(Buffer &data, unsigned char type){
ENFORCE_MSG_THREAD;
LOGV("Sending extra type %u length %lu", type, (unsigned int)data.Length());
LOGV("Sending extra type %u length %u", type, (unsigned int)data.Length());
for(vector<UnacknowledgedExtraData>::iterator x=currentExtras.begin();x!=currentExtras.end();++x){
if(x->type==type){
x->firstContainingSeq=0;

View File

@ -532,6 +532,10 @@ namespace tgvoip {
((video::VideoSourceAndroid*)(intptr_t)inst)->SetRotation((unsigned int)rotation);
}
void VideoSource_nativeSetPaused(JNIEnv* env, jobject thiz, jlong inst, jboolean paused){
((video::VideoSourceAndroid*)(intptr_t)inst)->SetStreamPaused((bool)paused);
}
#pragma mark - VideoRenderer
jlong VideoRenderer_nativeInit(JNIEnv* env, jobject thiz){
@ -612,7 +616,7 @@ extern "C" void tgvoipRegisterNatives(JNIEnv* env){
if(videoRenderer){
video::VideoRendererAndroid::decodeAndDisplayMethod=env->GetMethodID(videoRenderer, "decodeAndDisplay", "(Ljava/nio/ByteBuffer;IJ)V");
video::VideoRendererAndroid::resetMethod=env->GetMethodID(videoRenderer, "reset", "(Ljava/lang/String;II[[B)V");
video::VideoRendererAndroid::setStreamEnabledMethod=env->GetMethodID(videoRenderer, "setStreamEnabled", "(Z)V");
video::VideoRendererAndroid::setStreamEnabledMethod=env->GetMethodID(videoRenderer, "setStreamEnabled", "(ZZ)V");
video::VideoRendererAndroid::setRotationMethod=env->GetMethodID(videoRenderer, "setRotation", "(I)V");
}
}
@ -713,7 +717,8 @@ extern "C" void tgvoipRegisterNatives(JNIEnv* env){
{"nativeRelease", "(J)V", (void *) &tgvoip::VideoSource_nativeRelease},
{"nativeSetVideoStreamParameters", "(J[Ljava/nio/ByteBuffer;II)V", (void *) &tgvoip::VideoSource_nativeSetVideoStreamParameters},
{"nativeSendFrame", "(JLjava/nio/ByteBuffer;III)V", (void *) &tgvoip::VideoSource_nativeSendFrame},
{"nativeSetRotation", "(JI)V", (void*)&tgvoip::VideoSource_nativeSetRotation}
{"nativeSetRotation", "(JI)V", (void*)&tgvoip::VideoSource_nativeSetRotation},
{"nativeSetPaused", "(JZ)V", (void*)&tgvoip::VideoSource_nativeSetPaused}
};
env->RegisterNatives(videoSource, videoSourceMethods, sizeof(videoSourceMethods)/sizeof(JNINativeMethod));
}

View File

@ -127,7 +127,7 @@ void VideoRendererAndroid::RunThread(){
}
env->CallVoidMethod(jobj, resetMethod, env->NewStringUTF(codecStr.c_str()), (jint)width, (jint)height, jcsd);
}else if(request.type==Request::Type::UpdateStreamState){
env->CallVoidMethod(jobj, setStreamEnabledMethod, streamEnabled);
env->CallVoidMethod(jobj, setStreamEnabledMethod, streamEnabled, streamPaused);
}
}
free(buf);
@ -150,5 +150,10 @@ void VideoRendererAndroid::SetRotation(uint16_t rotation){
}
void VideoRendererAndroid::SetStreamPaused(bool paused){
streamPaused=paused;
Request req{
Buffer(0),
Request::Type::UpdateStreamState
};
queue.Put(std::move(req));
}

View File

@ -49,6 +49,7 @@ namespace tgvoip{
int width;
int height;
bool streamEnabled=true;
bool streamPaused=false;
uint32_t codec;
uint16_t rotation=0;
jobject jobj;

View File

@ -86,3 +86,7 @@ void VideoSourceAndroid::SetBitrate(uint32_t bitrate){
env->CallVoidMethod(javaObject, setBitrateMethod, (jint)bitrate);
});
}
void VideoSourceAndroid::SetStreamPaused(bool paused){
streamStateCallback(paused);
}

View File

@ -23,6 +23,7 @@ namespace tgvoip{
void SetStreamParameters(std::vector<Buffer> csd, unsigned int width, unsigned int height);
virtual void RequestKeyFrame() override;
virtual void SetBitrate(uint32_t bitrate) override;
void SetStreamPaused(bool paused);
static std::vector<uint32_t> availableEncoders;
private:

View File

@ -12,28 +12,28 @@ 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.9f;
/*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
constexpr float QDELAY_TARGET_LO=0.1f; // seconds
constexpr float QDELAY_TARGET_HI=0.4f; // seconds
constexpr float QDELAY_WEIGHT=0.1f;
constexpr float QDELAY_TREND_TH=0.2f;
constexpr uint32_t MIN_CWND=3000; // bytes
constexpr float MAX_BYTES_IN_FLIGHT_HEAD_ROOM=1.1f;
constexpr float GAIN=1.0f;
constexpr float BETA_LOSS=0.9f;
constexpr float BETA_ECN=0.9f;
constexpr float BETA_R=0.9f;
constexpr uint32_t MSS=1024;
constexpr float RATE_ADJUST_INTERVAL=0.2f;
constexpr uint32_t TARGET_BITRATE_MIN=50*1024; // bps
constexpr uint32_t TARGET_BITRATE_MAX=500*1024; // bps
constexpr uint32_t RAMP_UP_SPEED=1024*1024;//200000; // bps/s
constexpr float PRE_CONGESTION_GUARD=0.1f;
constexpr float TX_QUEUE_SIZE_FACTOR=1.0f;
constexpr float RTP_QDELAY_TH=0.02f; // seconds
constexpr float TARGET_RATE_SCALE_RTP_QDELAY=0.95f;
constexpr float QDELAY_TREND_LO=0.2f;
constexpr float T_RESUME_FAST_INCREASE=5.0f; // seconds
constexpr uint32_t RATE_PACE_MIN=50000; // bps
}
ScreamCongestionController::ScreamCongestionController() : qdelayTarget(QDELAY_TARGET_LO), cwnd(MIN_CWND) {
@ -71,7 +71,7 @@ void ScreamCongestionController::UpdateCWnd(float qdelay){
inFastIncrease=false;
}else{
if((float)bytesInFlight*1.5f+bytesNewlyAcked>cwnd){
LOGD("HERE");
//LOGD("HERE");
cwnd+=bytesNewlyAcked;
}
return;

View File

@ -94,6 +94,7 @@ void VideoPacketSender::SetSource(VideoSource *source){
if(!source)
return;
sourceChangeTime=lastVideoResolutionChangeTime=VoIPController::GetCurrentTime();
uint32_t bitrate=videoCongestionControl.GetBitrate();
currentVideoBitrate=bitrate;
source->SetBitrate(bitrate);
@ -102,9 +103,10 @@ void VideoPacketSender::SetSource(VideoSource *source){
source->SetCallback(std::bind(&VideoPacketSender::SendFrame, this, placeholders::_1, placeholders::_2, placeholders::_3));
source->SetStreamStateCallback([this](bool paused){
stm->paused=paused;
SendStreamFlags(*stm);
GetMessageThread().Post([this]{
SendStreamFlags(*stm);
});
});
lastVideoResolutionChangeTime=VoIPController::GetCurrentTime();
}
void VideoPacketSender::SendFrame(const Buffer &_frame, uint32_t flags, uint32_t rotation){
@ -125,7 +127,7 @@ void VideoPacketSender::SendFrame(const Buffer &_frame, uint32_t flags, uint32_t
source->SetBitrate(bitrate);
}
int resolutionFromBitrate=GetVideoResolutionForCurrentBitrate();
if(resolutionFromBitrate!=stm->resolution && currentTime-lastVideoResolutionChangeTime>3.0){
if(resolutionFromBitrate!=stm->resolution && currentTime-lastVideoResolutionChangeTime>3.0 && currentTime-sourceChangeTime>10.0){
LOGI("Changing video resolution: %d -> %d", stm->resolution, resolutionFromBitrate);
stm->resolution=resolutionFromBitrate;
GetMessageThread().Post([this, resolutionFromBitrate]{
@ -291,33 +293,33 @@ void VideoPacketSender::SendFrame(const Buffer &_frame, uint32_t flags, uint32_t
int VideoPacketSender::GetVideoResolutionForCurrentBitrate(){
int peerMaxVideoResolution=GetProtocolInfo().maxVideoResolution;
int resolutionFromBitrate=INIT_VIDEO_RES_1080;
// TODO: probably move this to server config
if(stm->codec==CODEC_AVC || stm->codec==CODEC_VP8){
if(currentVideoBitrate>400000){
resolutionFromBitrate=INIT_VIDEO_RES_720;
}else if(currentVideoBitrate>250000){
resolutionFromBitrate=INIT_VIDEO_RES_480;
}else{
resolutionFromBitrate=INIT_VIDEO_RES_360;
if(VoIPController::GetCurrentTime()-sourceChangeTime<10.0){
// TODO: probably move this to server config
if(stm->codec==CODEC_AVC || stm->codec==CODEC_VP8){
if(currentVideoBitrate>400000){
resolutionFromBitrate=INIT_VIDEO_RES_720;
}else if(currentVideoBitrate>250000){
resolutionFromBitrate=INIT_VIDEO_RES_480;
}else{
resolutionFromBitrate=INIT_VIDEO_RES_360;
}
}else if(stm->codec==CODEC_HEVC || stm->codec==CODEC_VP9){
if(currentVideoBitrate>400000){
resolutionFromBitrate=INIT_VIDEO_RES_1080;
}else if(currentVideoBitrate>250000){
resolutionFromBitrate=INIT_VIDEO_RES_720;
}else if(currentVideoBitrate>100000){
resolutionFromBitrate=INIT_VIDEO_RES_480;
}else{
resolutionFromBitrate=INIT_VIDEO_RES_360;
}
}
}else if(stm->codec==CODEC_HEVC || stm->codec==CODEC_VP9){
if(currentVideoBitrate>400000){
}else{
if(stm->codec==CODEC_AVC || stm->codec==CODEC_VP8)
resolutionFromBitrate=INIT_VIDEO_RES_720;
else if(stm->codec==CODEC_HEVC || stm->codec==CODEC_VP9)
resolutionFromBitrate=INIT_VIDEO_RES_1080;
}else if(currentVideoBitrate>250000){
resolutionFromBitrate=INIT_VIDEO_RES_720;
}else if(currentVideoBitrate>100000){
resolutionFromBitrate=INIT_VIDEO_RES_480;
}else{
resolutionFromBitrate=INIT_VIDEO_RES_360;
}
}
return std::min(peerMaxVideoResolution, resolutionFromBitrate);
}
void VideoPacketSender::SendStreamCSD(){
assert(stm->csdIsValid);
//SendExtra(buf, EXTRA_TYPE_STREAM_CSD);
}

View File

@ -42,7 +42,6 @@ namespace tgvoip{
void SendFrame(const Buffer& frame, uint32_t flags, uint32_t rotation);
int GetVideoResolutionForCurrentBitrate();
void SendStreamCSD();
VideoSource* source=NULL;
std::shared_ptr<VoIPController::Stream> stm;
@ -55,6 +54,7 @@ namespace tgvoip{
uint32_t videoPacketLossCount=0;
uint32_t currentVideoBitrate=0;
double lastVideoResolutionChangeTime=0.0;
double sourceChangeTime=0.0;
std::vector<Buffer> packetsForFEC;
size_t fecFrameCount=0;