Skip to content

Commit

Permalink
Attend to screen orientation (issue webcamoid#661).
Browse files Browse the repository at this point in the history
  • Loading branch information
hipersayanX committed Dec 15, 2023
1 parent 07c0991 commit 6f51154
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 21 deletions.
19 changes: 8 additions & 11 deletions libAvKys/Plugins/DesktopCapture/src/ffmpeg/src/ffmpegdev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,19 @@
#include <QMutex>
#include <ak.h>
#include <akcaps.h>
#include <akelement.h>
#include <akfrac.h>
#include <akpacket.h>
#include <akpluginmanager.h>
#include <akvideopacket.h>

extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}

#include "ffmpegdev.h"
Expand All @@ -57,6 +59,7 @@ class FFmpegDevPrivate
AVDictionary *m_codecOptions {nullptr};
AVStream *m_stream {nullptr};
SwsContext *m_scaleContext {nullptr};
AkElementPtr m_rotateFilter {akPluginManager->create<AkElement>("VideoFilter/Rotate")};
AkFrac m_fps {30000, 1001};
bool m_showCursor {false};
qint64 m_id {-1};
Expand All @@ -71,7 +74,6 @@ class FFmpegDevPrivate
QStringList listAVFoundationDevices() const;
QSize screenSize(const QString &format, const QString &input) const;
void setupGeometrySignals();
void setupOrientationSignals();
AkFrac fps() const;
AkFrac timeBase() const;
AkVideoPacket convert(AVFrame *iFrame);
Expand Down Expand Up @@ -506,11 +508,6 @@ void FFmpegDevPrivate::setupGeometrySignals()
}
}

void FFmpegDevPrivate::setupOrientationSignals()
{

}

AkFrac FFmpegDevPrivate::fps() const
{
if (!this->m_stream)
Expand Down
14 changes: 11 additions & 3 deletions libAvKys/Plugins/DesktopCapture/src/qtscreen/src/qtscreendev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
#include <QtConcurrent>
#include <ak.h>
#include <akcaps.h>
#include <akelement.h>
#include <akfrac.h>
#include <akpacket.h>
#include <akpluginmanager.h>
#include <akvideopacket.h>

#include "qtscreendev.h"
Expand Down Expand Up @@ -60,6 +62,7 @@ class QtScreenDevPrivate
MediaCaptureSessionPtr m_captureSession;
QVideoSink m_videoSink;
QVideoFrame m_curFrame;
AkElementPtr m_rotateFilter {akPluginManager->create<AkElement>("VideoFilter/Rotate")};
QList<QSize> m_availableSizes;
QString m_iconsPath {":/Webcamoid/share/themes/WebcamoidTheme/icons"};
QString m_themeName {"hicolor"};
Expand All @@ -73,7 +76,7 @@ class QtScreenDevPrivate
QImage cursorImage(const QSize &requestedSize) const;
QImage cursorImage(QSize *size, const QSize &requestedSize) const;
void setupGeometrySignals();
void setupOrientationSignals();
qreal screenRotation() const;
void frameReady(const QVideoFrame &frame);
void sendFrame(const QVideoFrame &frame);
void updateDevices();
Expand Down Expand Up @@ -411,9 +414,10 @@ void QtScreenDevPrivate::setupGeometrySignals()
}
}

void QtScreenDevPrivate::setupOrientationSignals()
qreal QtScreenDevPrivate::screenRotation() const
{

return this->m_curScreen->angleBetween(this->m_curScreen->primaryOrientation(),
this->m_curScreen->orientation());
}

void QtScreenDevPrivate::frameReady(const QVideoFrame &frame)
Expand Down Expand Up @@ -471,6 +475,10 @@ void QtScreenDevPrivate::sendFrame(const QVideoFrame &frame)
memcpy(dstLine, srcLine, lineSize);
}

auto angle = -this->screenRotation();
this->m_rotateFilter->setProperty("angle", angle);
videoPacket = this->m_rotateFilter->iStream(videoPacket);

emit self->oStream(videoPacket);
}

Expand Down
46 changes: 39 additions & 7 deletions libAvKys/Plugins/DesktopCapture/src/xlib/src/xlibdev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
#include <QMutex>
#include <ak.h>
#include <akcaps.h>
#include <akelement.h>
#include <akfrac.h>
#include <akpacket.h>
#include <akpluginmanager.h>
#include <akvideopacket.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
Expand Down Expand Up @@ -64,18 +66,21 @@ class XlibDevPrivate
QTimer m_timer;
QMutex m_mutex;
Display *m_display {nullptr};
int m_screen {0};
Window m_rootWindow {0};
XWindowAttributes m_windowAttributes;
#ifdef HAVE_XEXT_SUPPORT
XShmSegmentInfo m_shmInfo;
#endif
XImage *m_xImage {nullptr};
AkElementPtr m_rotateFilter {akPluginManager->create<AkElement>("VideoFilter/Rotate")};
bool m_haveShmExtension {false};
bool m_showCursor {false};
bool m_followCursor {false};

explicit XlibDevPrivate(XlibDev *self);
AkVideoCaps::PixelFormat pixelFormat(int depth, int bpp) const;
qreal screenRotation() const;
void readFrame();
void updateDevices();
};
Expand Down Expand Up @@ -104,13 +109,6 @@ XlibDev::~XlibDev()
if (this->d->m_display)
XCloseDisplay(this->d->m_display);

// https://www.linuxquestions.org/questions/programming-9/c-current-screen-rotation-value-xrandr-xrr-functions-929831/
RR_Rotate_0;
RR_Rotate_90;
RR_Rotate_180;
RR_Rotate_270;
XRRRotations();

delete this->d;
}

Expand Down Expand Up @@ -350,6 +348,7 @@ bool XlibDev::init()
}
#endif

this->d->m_screen = screen;
this->d->m_id = Ak::id();
this->d->m_timer.setInterval(qRound(1.e3 *
this->d->m_fps.invert().value()));
Expand Down Expand Up @@ -397,6 +396,33 @@ AkVideoCaps::PixelFormat XlibDevPrivate::pixelFormat(int depth, int bpp) const
return AkVideoCaps::Format_none;
}

qreal XlibDevPrivate::screenRotation() const
{
#ifdef HAVE_XRANDR_SUPPORT
Rotation rotation = 0;
XRRRotations(this->m_display, this->m_screen, &rotation);

switch (rotation) {
case RR_Rotate_0:
return 0.0;

case RR_Rotate_90:
return 90.0;

case RR_Rotate_180:
return 180.0;

case RR_Rotate_270:
return 270.0;

default:
break;
}
#endif

return 0.0;
}

void XlibDevPrivate::readFrame()
{
XImage *image = nullptr;
Expand Down Expand Up @@ -530,6 +556,12 @@ void XlibDevPrivate::readFrame()
XDestroyImage(image);
#endif

#ifdef HAVE_XRANDR_SUPPORT
auto angle = -this->screenRotation();
this->m_rotateFilter->setProperty("angle", angle);
videoPacket = this->m_rotateFilter->iStream(videoPacket);
#endif

emit self->oStream(videoPacket);
}

Expand Down

0 comments on commit 6f51154

Please sign in to comment.