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:
parent
5b0543ac10
commit
c806b15b61
@ -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}
|
||||
|
@ -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_;
|
||||
|
@ -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_;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user