Skip to content
Snippets Groups Projects
Commit 9d76cf5c authored by Aline Gondim Santos's avatar Aline Gondim Santos
Browse files

windows: replace gdigrab with dxgigrab ffmpeg device

Gdigrab window sharing is limited to the applications that
do not depend on accelerated rendering. If one tries to share
a window such as Google Chrome or VisualStudio Code with this
ffmpeg device, all that is received are black frames. The Dxgigrab
device uses the D3D11 Windows API which enables the correct
sharing of the mentioned applications and other ones.

GitLab: jami-project#1294
GitLab: jami-client-qt#481

Change-Id: I5509ed1b8d47a86367869e52127b17f671c61f77
parent 33e6ac43
No related branches found
No related tags found
No related merge requests found
......@@ -16,7 +16,8 @@
"libopusdec-enable-FEC.patch",
"windows-configure.patch",
"windows-configure-ffnvcodec.patch",
"windows-configure-libmfx.patch"
"windows-configure-libmfx.patch",
"windows-dxgi-support.patch"
],
"win_patches": [
],
......
......@@ -145,7 +145,7 @@ if [ "$1" == "uwp" ]; then
OUTDIR=Output/Windows10/x86
fi
elif [ "$1" == "win32" ]; then
EXTRACFLAGS='-MD -D_WINDLL -I../../../../../msvc/include -I../../../../../msvc/include/opus -I../../../../../msvc/include/vpx -I../../../../../msvc/include/ffnvcodec -I../../../../../msvc/include/mfx'
EXTRACFLAGS='-MD -D_WINDLL -I../../../../../msvc/include -I../../../../../msvc/include/opus -I../../../../../msvc/include/vpx -I../../../../../msvc/include/ffnvcodec -I../../../../../msvc/include/mfx -D_WIN32_WINNT=0x0A00'
FFMPEGCONF+='
--enable-libvpx
--enable-encoder=libvpx_vp8
......@@ -154,7 +154,8 @@ elif [ "$1" == "win32" ]; then
FFMPEGCONF+='
--enable-indev=dshow
--enable-indev=gdigrab
--enable-dxva2'
--enable-dxva2
--enable-indev=dxgigrab'
FFMPEGCONF+='
--enable-ffnvcodec
--enable-cuvid
......@@ -199,6 +200,6 @@ pwd
FFMPEGCONF=$(echo $FFMPEGCONF | sed -e "s/[[:space:]]\+/ /g")
set -x
set -e
../../../configure $FFMPEGCONF --extra-cflags="${EXTRACFLAGS}" --extra-ldflags="${EXTRALDFLAGS}" --prefix="${PREFIX}"
../../../configure $FFMPEGCONF --extra-cflags="${EXTRACFLAGS}" --extra-ldflags="${EXTRALDFLAGS}" --prefix="${PREFIX}" --extra-cxxflags="-std:c++17"
make -j8 install
cd ../../..
This diff is collapsed.
......@@ -350,7 +350,7 @@ MediaDemuxer::decode()
av_packet_free(
&p);
});
if (inputParams_.format == "x11grab") {
if (inputParams_.format == "x11grab" || inputParams_.format == "dxgigrab") {
auto ret = inputCtx_->iformat->read_header(inputCtx_);
if (ret == AVERROR_EXTERNAL) {
JAMI_ERR("Couldn't read frame: %s\n", libav_utils::getError(ret).c_str());
......
......@@ -285,7 +285,7 @@ VideoInput::createDecoder()
[](void* data) -> int { return not static_cast<VideoInput*>(data)->isCapturing(); }, this);
bool ready = false, restartSink = false;
if (decOpts_.format == "x11grab" && !decOpts_.is_area) {
if ((decOpts_.format == "x11grab" || decOpts_.format == "dxgigrab") && !decOpts_.is_area) {
decOpts_.width = 0;
decOpts_.height = 0;
}
......@@ -417,7 +417,6 @@ VideoInput::initX11(const std::string& display)
p.input = display.substr(1, space);
if (p.window_id.empty()) {
p.input = display.substr(0, space);
JAMI_INFO() << "p.window_id.empty()";
auto splits = jami::split_string_to_unsigned(display.substr(space + 1), 'x');
// round to 8 pixel block
p.width = round2pow(splits[0], 3);
......@@ -469,31 +468,61 @@ VideoInput::initAVFoundation(const std::string& display)
return true;
}
#ifdef WIN32
bool
VideoInput::initGdiGrab(const std::string& params)
VideoInput::initWindowsGrab(const std::string& display)
{
size_t space = params.find(' ');
clearOptions();
decOpts_ = jami::getVideoDeviceMonitor().getDeviceParams(DEVICE_DESKTOP);
if (space != std::string::npos) {
std::istringstream iss(params.substr(space + 1));
char sep;
unsigned w, h;
iss >> w >> sep >> h;
decOpts_.width = round2pow(w, 3);
decOpts_.height = round2pow(h, 3);
// Patterns
// full screen sharing : :1+0,0 2560x1440 - SCREEN 1, POSITION 0X0, RESOLUTION 2560X1440
// area sharing : :1+882,211 1532x779 - SCREEN 1, POSITION 882x211, RESOLUTION 1532x779
// window sharing : :+1,0 0x0 window-id:TITLE - POSITION 0X0
size_t space = display.find(' ');
std::string windowIdStr = "window-id:";
size_t winIdPos = display.find(windowIdStr);
size_t plus = params.find('+');
std::istringstream dss(params.substr(plus + 1, space - plus));
dss >> decOpts_.offset_x >> sep >> decOpts_.offset_y;
DeviceParams p = jami::getVideoDeviceMonitor().getDeviceParams(DEVICE_DESKTOP);
if (winIdPos != std::string::npos) {
p.input = display.substr(winIdPos + windowIdStr.size()); // "TITLE";
p.name = display.substr(winIdPos + windowIdStr.size()); // "TITLE";
p.is_area = 0;
} else {
decOpts_.width = default_grab_width;
decOpts_.height = default_grab_height;
p.input = display.substr(1);
p.name = display.substr(1);
p.is_area = 1;
if (space != std::string::npos) {
auto splits = jami::split_string_to_unsigned(display.substr(space + 1), 'x');
if (splits.size() != 2)
return false;
// round to 8 pixel block
p.width = splits[0];
p.height = splits[1];
size_t plus = display.find('+');
auto position = display.substr(plus + 1, space - plus - 1);
splits = jami::split_string_to_unsigned(position, ',');
if (splits.size() != 2)
return false;
p.offset_x = splits[0];
p.offset_y = splits[1];
} else {
p.width = default_grab_width;
p.height = default_grab_height;
}
}
auto dec = std::make_unique<MediaDecoder>();
if (dec->openInput(p) < 0 || dec->setupVideo() < 0)
return initCamera(jami::getVideoDeviceMonitor().getDefaultDevice());
clearOptions();
decOpts_ = p;
decOpts_.width = dec->getStream().width;
decOpts_.height = dec->getStream().height;
return true;
}
#endif
bool
VideoInput::initFile(std::string path)
......@@ -588,8 +617,8 @@ VideoInput::switchInput(const std::string& resource)
/* X11 display name */
#ifdef __APPLE__
ready = initAVFoundation(suffix);
#elif defined(_WIN32)
ready = initGdiGrab(suffix);
#elif defined(WIN32)
ready = initWindowsGrab(suffix);
#else
ready = initX11(suffix);
#endif
......
......@@ -135,7 +135,9 @@ private:
bool initX11(const std::string& display);
bool initAVFoundation(const std::string& display);
bool initFile(std::string path);
bool initGdiGrab(const std::string& params);
#ifdef WIN32
bool initWindowsGrab(const std::string& display);
#endif
bool isCapturing() const noexcept;
void startLoop();
......
......@@ -166,7 +166,7 @@ VideoRtpSession::startSender()
// Current implementation does not handle resolution change
// (needed by window sharing feature) with HW codecs, so HW
// codecs will be disabled for now.
bool allowHwAccel = (localVideoParams_.format != "x11grab");
bool allowHwAccel = (localVideoParams_.format != "x11grab" && localVideoParams_.format != "dxgigrab");
if (socketPair_)
initSeqVal_ = socketPair_->lastSeqValOut();
......
......@@ -281,7 +281,7 @@ VideoDeviceImpl::getDeviceParams() const
params.unique_id = id;
params.input = id;
if (id == DEVICE_DESKTOP) {
params.format = "gdigrab";
params.format = "dxgigrab";
params.framerate = desktopFrameRate_;
return params;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment