Skip to content
Snippets Groups Projects
Commit d0744b32 authored by Sébastien Blin's avatar Sébastien Blin
Browse files

video_input: handle EBUSY error from ffmpeg

This solves some bugs:
+ If we have two calls and the client is holding one of these till the other
is creating, the camera will start for the second call
+ If another process is using the camera, Jami will retry to open the camera
till the call ends
+ If one video input runs cleanup() and the other one createDecoder(), the
shmPath_ is set back correctly

Change-Id: Id6b02e453dffbe0b231884c2942786407af5eac3
parent f3f3b69b
No related branches found
No related tags found
No related merge requests found
...@@ -66,6 +66,7 @@ VideoInput::VideoInput() ...@@ -66,6 +66,7 @@ VideoInput::VideoInput()
VideoInput::~VideoInput() VideoInput::~VideoInput()
{ {
isStopped_ = true;
#if VIDEO_CLIENT_INPUT #if VIDEO_CLIENT_INPUT
emitSignal<DRing::VideoSignal::StopCapture>(); emitSignal<DRing::VideoSignal::StopCapture>();
capturing_ = false; capturing_ = false;
...@@ -210,10 +211,26 @@ VideoInput::createDecoder() ...@@ -210,10 +211,26 @@ VideoInput::createDecoder()
[](void* data) -> int { return not static_cast<VideoInput*>(data)->isCapturing(); }, [](void* data) -> int { return not static_cast<VideoInput*>(data)->isCapturing(); },
this); this);
if (decoder->openInput(decOpts_) < 0) { bool ready = false, restartSink = false;
JAMI_ERR("Could not open input \"%s\"", decOpts_.input.c_str()); while (!ready && !isStopped_) {
// Retry to open the video till the input is opened
auto ret = decoder->openInput(decOpts_);
ready = ret >= 0;
if (ret < 0 && -ret != EBUSY) {
JAMI_ERR("Could not open input \"%s\" with status %i", decOpts_.input.c_str(), ret);
foundDecOpts(decOpts_); foundDecOpts(decOpts_);
return; return;
} else if (-ret == EBUSY) {
// If the device is busy, this means that it can be used by another call.
// If this is the case, cleanup() can occurs and this will erase shmPath_
// So, be sure to regenerate a correct shmPath for clients.
restartSink = true;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
if (restartSink && !isStopped_) {
sink_->start();
} }
/* Data available, finish the decoding */ /* Data available, finish the decoding */
......
...@@ -85,6 +85,7 @@ private: ...@@ -85,6 +85,7 @@ private:
std::string currentResource_; std::string currentResource_;
std::atomic<bool> switchPending_ = {false}; std::atomic<bool> switchPending_ = {false};
std::atomic_bool isStopped_ = {false};
DeviceParams decOpts_; DeviceParams decOpts_;
std::promise<DeviceParams> foundDecOpts_; std::promise<DeviceParams> foundDecOpts_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment