add interface to send keyevents (#5)

* explicitly send keyevent to input device; style cleanup

* more style updates

* more style conformity
This commit is contained in:
Robert Stanley Judka 2020-06-22 15:59:33 -05:00 committed by GitHub
parent 5b0543ac10
commit c806b15b61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 102 additions and 61 deletions

View File

@ -35,6 +35,7 @@ find_package(Protobuf REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(rtaudio REQUIRED)
find_package(GObject)
if(WIN32)
set(WINSOCK2_LIBRARIES "ws2_32")
endif(WIN32)
@ -49,7 +50,8 @@ endif(RPI_BUILD AND NOT GST_BUILD)
if(GST_BUILD)
find_package(Qt5GStreamer)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GST REQUIRED gstreamer-1.0>=1.4
pkg_check_modules(GST REQUIRED
gstreamer-1.0>=1.4
gstreamer-sdp-1.0>=1.4
gstreamer-video-1.0>=1.4
gstreamer-app-1.0>=1.4)
@ -96,6 +98,7 @@ file(GLOB_RECURSE autoapp_lib_source_files ${autoapp_sources_directory}/App.cpp
file(GLOB_RECURSE autoapp_lib_inlcude_files ${autoapp_include_directory}/App.hpp ${autoapp_include_directory}/Configuration/*.hpp ${autoapp_include_directory}/Projection/*.hpp ${autoapp_include_directory}/Service/*.hpp)
add_library(auto SHARED ${autoapp_lib_source_files} ${autoapp_lib_inlcude_files})
message(STATUS "${GST_LIBRARIES}")
target_link_libraries(autoapp
${GST_LIBRARIES}
${Boost_LIBRARIES}

View File

@ -15,14 +15,16 @@
* You should have received a copy of the GNU General Public License
* along with openauto. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_GST
#ifdef USE_GST
#pragma once
#include <mutex>
#include <condition_variable>
#include <functional>
#include <thread>
#include <boost/circular_buffer.hpp>
#include <boost/noncopyable.hpp>
#include <f1x/openauto/autoapp/Projection/VideoOutput.hpp>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
@ -65,20 +67,23 @@ public:
void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) override;
void stop() override;
void resize();
signals:
void startPlayback();
void stopPlayback();
protected slots:
void onStartPlayback();
void onStopPlayback();
private:
static GstPadProbeReturn convert_probe(GstPad* pad, GstPadProbeInfo* info, void* user_data);
static gboolean bus_callback(GstBus* bus, GstMessage* message, gpointer* ptr);
static GstPadProbeReturn convertProbe(GstPad* pad, GstPadProbeInfo* info, void*);
static gboolean busCallback(GstBus*, GstMessage* message, gpointer*);
QGst::ElementPtr videoSink_;
QQuickWidget* videoWidget_;
GstElement* vidPipeline_ = nullptr;
GstAppSrc* vidSrc_ = nullptr;
GstElement* vidPipeline_;
GstAppSrc* vidSrc_;
QWidget* videoContainer_;
QGst::Quick::VideoSurface* surface_;
std::function<void(bool)> activeCallback_;

View File

@ -23,7 +23,6 @@
#include <f1x/openauto/autoapp/Projection/InputDevice.hpp>
#include <f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp>
#include <f1x/openauto/autoapp/Projection/GSTVideoOutput.hpp>
#include <QGst/Quick/VideoSurface>
#include <f1x/openauto/autoapp/Projection/QtVideoOutput.hpp>
#include <f1x/openauto/autoapp/Service/SensorService.hpp>
@ -44,6 +43,7 @@ public:
void setOpacity(unsigned int alpha);
void resize();
void setNightMode(bool nightMode);
void sendKeyEvent(QKeyEvent* event);
static QRect mapActiveAreaToGlobal(QWidget* activeArea);
#ifdef USE_OMX
static projection::DestRect QRectToDestRect(QRect rect);
@ -61,7 +61,7 @@ private:
QRect screenGeometry_;
std::function<void(bool)> activeCallback_;
std::shared_ptr<projection::InputDevice> inputDevice_;
#ifdef USE_OMX
#if defined USE_OMX
std::shared_ptr<projection::OMXVideoOutput> omxVideoOutput_;
#elif defined USE_GST
std::shared_ptr<projection::GSTVideoOutput> gstVideoOutput_;

View File

@ -45,13 +45,9 @@ GSTVideoOutput::GSTVideoOutput(configuration::IConfiguration::Pointer configurat
videoWidget_->setResizeMode(QQuickWidget::SizeRootObjectToView);
videoSink_ = surface_->videoSink();
GstBus* bus;
GError* error = NULL;
const char* vidLaunchStr = "appsrc name=mysrc is-live=true block=false max-latency=100 do-timestamp=true stream-type=stream ! "
"queue ! "
"h264parse ! "
GError* error = nullptr;
const char* vidLaunchStr = "appsrc name=mysrc is-live=true block=false max-latency=100 do-timestamp=true stream-type=stream ! queue ! h264parse ! "
#ifdef RPI
#ifdef PI4
"v4l2h264dec ! "
@ -72,15 +68,15 @@ GSTVideoOutput::GSTVideoOutput(configuration::IConfiguration::Pointer configurat
#endif
vidPipeline_ = gst_parse_launch(vidLaunchStr, &error);
bus = gst_pipeline_get_bus(GST_PIPELINE(vidPipeline_));
gst_bus_add_watch(bus, (GstBusFunc)GSTVideoOutput::bus_callback, this);
GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(vidPipeline_));
gst_bus_add_watch(bus, (GstBusFunc)&GSTVideoOutput::busCallback, this);
gst_object_unref(bus);
GstElement* sink = QGlib::RefPointer<QGst::Element>(videoSink_);
g_object_set(sink, "force-aspect-ratio", false, nullptr);
g_object_set(sink, "sync", false, nullptr);
g_object_set(sink, "async", false, nullptr);
GstElement* capsFilter = gst_bin_get_by_name(GST_BIN(vidPipeline_), "mycapsfilter");
gst_bin_add(GST_BIN(vidPipeline_), GST_ELEMENT(sink));
gst_element_link(capsFilter, GST_ELEMENT(sink));
@ -92,14 +88,13 @@ GSTVideoOutput::GSTVideoOutput(configuration::IConfiguration::Pointer configurat
connect(this, &GSTVideoOutput::stopPlayback, this, &GSTVideoOutput::onStopPlayback, Qt::QueuedConnection);
}
GSTVideoOutput::~GSTVideoOutput()
{
gst_object_unref(vidPipeline_);
gst_object_unref(vidSrc_);
}
gboolean GSTVideoOutput::bus_callback(GstBus* /* unused*/, GstMessage* message, gpointer* ptr)
gboolean GSTVideoOutput::busCallback(GstBus*, GstMessage* message, gpointer*)
{
gchar* debug;
GError* err;
@ -117,7 +112,7 @@ gboolean GSTVideoOutput::bus_callback(GstBus* /* unused*/, GstMessage* message,
gst_message_parse_warning(message, &err, &debug);
OPENAUTO_LOG(info) << "[GSTVideoOutput] Warning " << err->message << " | Debug " << debug;
name = (gchar*)GST_MESSAGE_SRC_NAME(message);
OPENAUTO_LOG(info) << "[GSTVideoOutput] Name of src " << name ? name : "nil";
OPENAUTO_LOG(info) << "[GSTVideoOutput] Name of src " << (name ? name : "nil");
g_error_free(err);
g_free(debug);
break;
@ -125,7 +120,6 @@ gboolean GSTVideoOutput::bus_callback(GstBus* /* unused*/, GstMessage* message,
OPENAUTO_LOG(info) << "[GSTVideoOutput] End of stream";
break;
case GST_MESSAGE_STATE_CHANGED:
break;
default:
break;
}
@ -137,29 +131,32 @@ bool GSTVideoOutput::open()
{
GstElement* capsFilter = gst_bin_get_by_name(GST_BIN(vidPipeline_), "mycapsfilter");
GstPad* convertPad = gst_element_get_static_pad(capsFilter, "sink");
gst_pad_add_probe (convertPad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, convert_probe, this, NULL);
gst_pad_add_probe(convertPad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, &GSTVideoOutput::convertProbe, this, nullptr);
gst_element_set_state(vidPipeline_, GST_STATE_PLAYING);
return true;
}
GstPadProbeReturn GSTVideoOutput::convert_probe(GstPad* pad, GstPadProbeInfo* info, void* user_data)
GstPadProbeReturn GSTVideoOutput::convertProbe(GstPad* pad, GstPadProbeInfo* info, void*)
{
GstEvent* event = GST_PAD_PROBE_INFO_EVENT(info);
if(GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
if(GST_EVENT_TYPE(event) == GST_EVENT_SEGMENT) {
if(GST_PAD_PROBE_INFO_TYPE(info) & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM)
{
if(GST_EVENT_TYPE(event) == GST_EVENT_SEGMENT)
{
GstCaps* caps = gst_pad_get_current_caps(pad);
if(caps != NULL)
if(caps != nullptr)
{
GstVideoInfo* vinfo = gst_video_info_new();
gst_video_info_from_caps(vinfo, caps);
OPENAUTO_LOG(info) << "[GSTVideoOutput] Video Width: " << vinfo->width;
OPENAUTO_LOG(info) << "[GSTVideoOutput] Video Height: " << vinfo->height;
}
return GST_PAD_PROBE_REMOVE;
}
}
return GST_PAD_PROBE_OK;
}
@ -167,6 +164,7 @@ bool GSTVideoOutput::init()
{
OPENAUTO_LOG(info) << "[GSTVideoOutput] init";
emit startPlayback();
return true;
}
@ -187,6 +185,7 @@ void GSTVideoOutput::onStartPlayback()
{
activeCallback_(true);
}
if(videoContainer_ == nullptr)
{
OPENAUTO_LOG(info) << "[GSTVideoOutput] No video container, setting projection fullscreen";
@ -213,6 +212,7 @@ void GSTVideoOutput::onStopPlayback()
{
activeCallback_(false);
}
OPENAUTO_LOG(info) << "[GSTVideoOutput] stop.";
gst_element_set_state(vidPipeline_, GST_STATE_PAUSED);
videoWidget_->hide();
@ -222,7 +222,10 @@ void GSTVideoOutput::resize()
{
OPENAUTO_LOG(info) << "[GSTVideoOutput] Got resize request to "<< videoContainer_->width() << "x" << videoContainer_->height();
if(videoWidget_ != nullptr && videoContainer_ != nullptr) videoWidget_->resize(videoContainer_->size());
if(videoWidget_ != nullptr && videoContainer_ != nullptr)
{
videoWidget_->resize(videoContainer_->size());
}
}
}

View File

@ -144,7 +144,7 @@ bool OMXVideoOutput::setupDisplayRegion()
displayRegion.noaspect = OMX_TRUE;
displayRegion.set = static_cast<OMX_DISPLAYSETTYPE >(OMX_DISPLAY_SET_FULLSCREEN | OMX_DISPLAY_SET_NOASPECT | OMX_DISPLAY_SET_LAYER);
if (destRect_.fullscreen == OMX_FALSE)
if(displayRegion.fullscreen == OMX_FALSE)
{
displayRegion.alpha = alpha_;
displayRegion.dest_rect.x_offset = destRect_.xOffset;

View File

@ -71,7 +71,10 @@ void QtVideoOutput::write(uint64_t, const aasdk::common::DataConstBuffer& buffer
void QtVideoOutput::resize()
{
if (videoWidget_ != nullptr && videoContainer_ != nullptr) videoWidget_->resize(videoContainer_->size());
if(videoWidget_ != nullptr && videoContainer_ != nullptr)
{
videoWidget_->resize(videoContainer_->size());
}
}
void QtVideoOutput::onStartPlayback()

View File

@ -56,7 +56,7 @@ ServiceFactory::ServiceFactory(boost::asio::io_service& ioService, configuration
, activeArea_(activeArea)
, screenGeometry_(this->mapActiveAreaToGlobal(activeArea_))
, activeCallback_(activeCallback)
#ifdef USE_OMX
#if defined USE_OMX
, omxVideoOutput_(std::make_shared<projection::OMXVideoOutput>(configuration_, this->QRectToDestRect(screenGeometry_), activeCallback_))
#elif defined USE_GST
, gstVideoOutput_((QGst::init(nullptr, nullptr), std::make_shared<projection::GSTVideoOutput>(configuration_, activeArea_, activeCallback_)))
@ -89,13 +89,14 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng
IService::Pointer ServiceFactory::createVideoService(aasdk::messenger::IMessenger::Pointer messenger)
{
#ifdef USE_OMX
#if defined USE_OMX
auto videoOutput(omxVideoOutput_);
#elif defined USE_GST
auto videoOutput(gstVideoOutput_);
#else
qtVideoOutput_ = new projection::QtVideoOutput(configuration_, activeArea_);
if (activeCallback_ != nullptr) {
if(activeCallback_ != nullptr)
{
QObject::connect(qtVideoOutput_, &projection::QtVideoOutput::startPlayback, [callback = activeCallback_]() { callback(true); });
QObject::connect(qtVideoOutput_, &projection::QtVideoOutput::stopPlayback, [this]() {
activeCallback_(false);
@ -183,27 +184,53 @@ void ServiceFactory::createAudioServices(ServiceList& serviceList, aasdk::messen
void ServiceFactory::setOpacity(unsigned int alpha)
{
#ifdef USE_OMX
if (omxVideoOutput_ != nullptr) omxVideoOutput_->setOpacity(alpha);
if(omxVideoOutput_ != nullptr)
{
omxVideoOutput_->setOpacity(alpha);
}
#endif
}
void ServiceFactory::resize()
{
screenGeometry_ = this->mapActiveAreaToGlobal(activeArea_);
if (inputDevice_ != nullptr) inputDevice_->setTouchscreenGeometry(screenGeometry_);
#ifdef USE_OMX
if (omxVideoOutput_ != nullptr) omxVideoOutput_->setDestRect(this->QRectToDestRect(screenGeometry_));
if(inputDevice_ != nullptr)
{
inputDevice_->setTouchscreenGeometry(screenGeometry_);
}
#if defined USE_OMX
if(omxVideoOutput_ != nullptr)
{
omxVideoOutput_->setDestRect(this->QRectToDestRect(screenGeometry_));
}
#elif defined USE_GST
if (gstVideoOutput_ != nullptr) gstVideoOutput_->resize();
if(gstVideoOutput_ != nullptr)
{
gstVideoOutput_->resize();
}
#else
if (qtVideoOutput_ != nullptr) qtVideoOutput_->resize();
if(qtVideoOutput_ != nullptr)
{
qtVideoOutput_->resize();
}
#endif
}
void ServiceFactory::setNightMode(bool nightMode)
{
nightMode_ = nightMode;
if (std::shared_ptr<SensorService> sensorService = sensorService_.lock()) sensorService->setNightMode(nightMode_);
if(std::shared_ptr<SensorService> sensorService = sensorService_.lock())
{
sensorService->setNightMode(nightMode_);
}
}
void ServiceFactory::sendKeyEvent(QKeyEvent* event)
{
if(inputDevice_ != nullptr)
{
inputDevice_->eventFilter(activeArea_, event);
}
}
QRect ServiceFactory::mapActiveAreaToGlobal(QWidget* activeArea)