Commit d0744b32 authored by Sébastien Blin's avatar Sébastien Blin

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
......@@ -66,6 +66,7 @@ VideoInput::VideoInput()
isStopped_ = true;
capturing_ = false;
......@@ -210,10 +211,26 @@ VideoInput::createDecoder()
[](void* data) -> int { return not static_cast<VideoInput*>(data)->isCapturing(); },
if (decoder->openInput(decOpts_) < 0) {
JAMI_ERR("Could not open input \"%s\"", decOpts_.input.c_str());
bool ready = false, restartSink = false;
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);
} 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;
if (restartSink && !isStopped_) {
/* Data available, finish the decoding */
......@@ -85,6 +85,7 @@ private:
std::string currentResource_;
std::atomic<bool> switchPending_ = {false};
std::atomic_bool isStopped_ = {false};
DeviceParams decOpts_;
std::promise<DeviceParams> foundDecOpts_;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment