Skip to content
Snippets Groups Projects
Commit 9838b089 authored by Kateryna Kostiuk's avatar Kateryna Kostiuk
Browse files

video: fix incoming video for iOS

During incoming calls to iOS, video input failed to open sometimes.
It happens for two reasons:
1. Stopped by interrupt callback.
2. Keyframe callback was set two late.

This patch:
1. Completes decoder configuration after video loop start running.
2. Sets keyframe callback for video session before starting.

Change-Id: I00e1ace06a78ab2ec2fb3ce6fe6a5991c6593318
parent 0d704562
No related branches found
No related tags found
No related merge requests found
...@@ -52,6 +52,7 @@ VideoReceiveThread::VideoReceiveThread(const std::string& id, ...@@ -52,6 +52,7 @@ VideoReceiveThread::VideoReceiveThread(const std::string& id,
, stream_(sdp) , stream_(sdp)
, sdpContext_(stream_.str().size(), false, &readFunction, 0, 0, this) , sdpContext_(stream_.str().size(), false, &readFunction, 0, 0, this)
, sink_ {Manager::instance().createSinkClient(id)} , sink_ {Manager::instance().createSinkClient(id)}
, isVideoConfigured_(false)
, mtu_(mtu) , mtu_(mtu)
, rotation_(0) , rotation_(0)
, loop_(std::bind(&VideoReceiveThread::setup, this), , loop_(std::bind(&VideoReceiveThread::setup, this),
...@@ -119,36 +120,6 @@ bool VideoReceiveThread::setup() ...@@ -119,36 +120,6 @@ bool VideoReceiveThread::setup()
// Now replace our custom AVIOContext with one that will read packets // Now replace our custom AVIOContext with one that will read packets
videoDecoder_->setIOContext(demuxContext_.get()); videoDecoder_->setIOContext(demuxContext_.get());
} }
if (videoDecoder_->setupVideo()) {
JAMI_ERR("decoder IO startup failed");
return false;
}
// Default size from input video
if (dstWidth_ == 0 and dstHeight_ == 0) {
dstWidth_ = videoDecoder_->getWidth();
dstHeight_ = videoDecoder_->getHeight();
}
if (not sink_->start()) {
JAMI_ERR("RX: sink startup failed");
return false;
}
auto conf = Manager::instance().getConferenceFromCallID(id_);
if (!conf)
exitConference();
// Send remote video codec in SmartInfo
Smartools::getInstance().setRemoteVideoCodec(videoDecoder_->getDecoderName(), id_);
// Send the resolution in smartInfo
Smartools::getInstance().setResolution(id_, dstWidth_, dstHeight_);
if (onSetupSuccess_)
onSetupSuccess_(MEDIA_VIDEO);
return true; return true;
} }
...@@ -187,6 +158,9 @@ void VideoReceiveThread::addIOContext(SocketPair& socketPair) ...@@ -187,6 +158,9 @@ void VideoReceiveThread::addIOContext(SocketPair& socketPair)
void VideoReceiveThread::decodeFrame() void VideoReceiveThread::decodeFrame()
{ {
if (!configureVideoOutput()) {
return;
}
auto status = videoDecoder_->decode(); auto status = videoDecoder_->decode();
if (status == MediaDemuxer::Status::EndOfFile || if (status == MediaDemuxer::Status::EndOfFile ||
status == MediaDemuxer::Status::ReadError) { status == MediaDemuxer::Status::ReadError) {
...@@ -198,6 +172,48 @@ void VideoReceiveThread::decodeFrame() ...@@ -198,6 +172,48 @@ void VideoReceiveThread::decodeFrame()
} }
} }
bool VideoReceiveThread::configureVideoOutput()
{
if (isVideoConfigured_) {
return true;
}
if (!loop_.isRunning()) {
return false;
}
if (videoDecoder_->setupVideo()) {
JAMI_ERR("decoder IO startup failed");
loop_.stop();
return false;
}
// Default size from input video
if (dstWidth_ == 0 and dstHeight_ == 0) {
dstWidth_ = videoDecoder_->getWidth();
dstHeight_ = videoDecoder_->getHeight();
}
if (not sink_->start()) {
JAMI_ERR("RX: sink startup failed");
loop_.stop();
return false;
}
auto conf = Manager::instance().getConferenceFromCallID(id_);
if (!conf)
exitConference();
// Send remote video codec in SmartInfo
Smartools::getInstance().setRemoteVideoCodec(videoDecoder_->getDecoderName(), id_);
// Send the resolution in smartInfo
Smartools::getInstance().setResolution(id_, dstWidth_, dstHeight_);
if (onSetupSuccess_)
onSetupSuccess_(MEDIA_VIDEO);
isVideoConfigured_ = true;
return true;
}
void VideoReceiveThread::enterConference() void VideoReceiveThread::enterConference()
{ {
if (!loop_.isRunning()) if (!loop_.isRunning())
......
...@@ -91,6 +91,7 @@ private: ...@@ -91,6 +91,7 @@ private:
std::unique_ptr<MediaIOHandle> demuxContext_; std::unique_ptr<MediaIOHandle> demuxContext_;
std::shared_ptr<SinkClient> sink_; std::shared_ptr<SinkClient> sink_;
bool isReset_; bool isReset_;
bool isVideoConfigured_;
uint16_t mtu_; uint16_t mtu_;
int rotation_; int rotation_;
std::shared_ptr<AVBufferRef> displayMatrix_; std::shared_ptr<AVBufferRef> displayMatrix_;
...@@ -99,6 +100,7 @@ private: ...@@ -99,6 +100,7 @@ private:
void decodeFrame(); void decodeFrame();
static int interruptCb(void *ctx); static int interruptCb(void *ctx);
static int readFunction(void *opaque, uint8_t *buf, int buf_size); static int readFunction(void *opaque, uint8_t *buf, int buf_size);
bool configureVideoOutput();
std::function<void(MediaType)> onSetupSuccess_; std::function<void(MediaType)> onSetupSuccess_;
......
...@@ -982,6 +982,15 @@ SIPCall::startAllMedia() ...@@ -982,6 +982,15 @@ SIPCall::startAllMedia()
rtp->setSuccessfulSetupCb([this](MediaType type){ rtpSetupSuccess(type); }); rtp->setSuccessfulSetupCb([this](MediaType type){ rtpSetupSuccess(type); });
#ifdef ENABLE_VIDEO
videortp_->setRequestKeyFrameCallback([wthis = weak()] {
runOnMainThread([wthis] {
if (auto this_ = wthis.lock())
this_->requestKeyframe();
});
});
#endif
// Not restarting media loop on hold as it's a huge waste of CPU ressources // Not restarting media loop on hold as it's a huge waste of CPU ressources
// because of the audio loop // because of the audio loop
if (getState() != CallState::HOLD) { if (getState() != CallState::HOLD) {
...@@ -1006,15 +1015,6 @@ SIPCall::startAllMedia() ...@@ -1006,15 +1015,6 @@ SIPCall::startAllMedia()
} }
} }
#ifdef ENABLE_VIDEO
videortp_->setRequestKeyFrameCallback([wthis = weak()] {
runOnMainThread([wthis] {
if (auto this_ = wthis.lock())
this_->requestKeyframe();
});
});
#endif
if (not isSubcall() and peerHolding_ != peer_holding) { if (not isSubcall() and peerHolding_ != peer_holding) {
peerHolding_ = peer_holding; peerHolding_ = peer_holding;
emitSignal<DRing::CallSignal::PeerHold>(getCallId(), peerHolding_); emitSignal<DRing::CallSignal::PeerHold>(getCallId(), peerHolding_);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment