updates to make things work (stolen from other people); modifying interfaces for qt support

This commit is contained in:
Robert Judka 2020-03-06 13:43:39 -06:00
parent 7513d99929
commit ae5a21a75e
11 changed files with 167 additions and 21 deletions

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
# Add any directories, files, or patterns you don't want to be tracked by version control
.vscode/
lib/
bin/
CMakeLists.txt.user

View File

@ -38,13 +38,13 @@ if(WIN32)
set(WINSOCK2_LIBRARIES "ws2_32")
endif(WIN32)
if(RPI3_BUILD)
add_definitions(-DUSE_OMX -DOMX_SKIP64BIT -DRASPBERRYPI3)
if(RPI_BUILD)
add_definitions(-DUSE_OMX -DOMX_SKIP64BIT)
set(BCM_HOST_LIBRARIES "/opt/vc/lib/libbcm_host.so")
set(BCM_HOST_INCLUDE_DIRS "/opt/vc/include")
set(ILCLIENT_INCLUDE_DIRS "/opt/vc/src/hello_pi/libs/ilclient")
set(ILCLIENT_LIBRARIES "/opt/vc/src/hello_pi/libs/ilclient/libilclient.a;/opt/vc/lib/libvcos.so;/opt/vc/lib/libvcilcs.a;/opt/vc/lib/libvchiq_arm.so")
endif(RPI3_BUILD)
endif(RPI_BUILD)
include_directories(${CMAKE_CURRENT_BINARY_DIR}
${Qt5Multimedia_INCLUDE_DIRS}
@ -72,6 +72,10 @@ file(GLOB_RECURSE autoapp_source_files ${autoapp_sources_directory}/*.ui ${autoa
add_executable(autoapp ${autoapp_source_files})
file(GLOB_RECURSE autoapp_lib_source_files ${autoapp_sources_directory}/App.cpp ${autoapp_sources_directory}/Configuration/*.cpp ${autoapp_sources_directory}/Projection/*.cpp ${autoapp_sources_directory}/Service/*.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})
target_link_libraries(autoapp
${Boost_LIBRARIES}
${Qt5Multimedia_LIBRARIES}

View File

@ -26,6 +26,7 @@ extern "C"
#include <mutex>
#include <condition_variable>
#include <functional>
#include <thread>
#include <boost/circular_buffer.hpp>
#include <f1x/openauto/autoapp/Projection/VideoOutput.hpp>
@ -39,15 +40,28 @@ namespace autoapp
namespace projection
{
struct DestRect
{
DestRect();
DestRect(OMX_S16 xOffset, OMX_S16 yOffset, OMX_S16 width, OMX_S16 height);
OMX_BOOL fullscreen;
OMX_S16 xOffset;
OMX_S16 yOffset;
OMX_S16 width;
OMX_S16 height;
};
class OMXVideoOutput: public VideoOutput
{
public:
OMXVideoOutput(configuration::IConfiguration::Pointer configuration);
OMXVideoOutput(configuration::IConfiguration::Pointer configuration, DestRect destRect=DestRect(), std::function<void(bool)> activeCallback=nullptr);
bool open() override;
bool init() override;
void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) override;
void stop() override;
void setOpacity(OMX_U32 alpha);
private:
bool createComponents();
@ -62,6 +76,9 @@ private:
ILCLIENT_T* client_;
COMPONENT_T* components_[5];
TUNNEL_T tunnels_[4];
DestRect destRect_;
OMX_U32 alpha_;
std::function<void(bool)> activeCallback_;
};
}

View File

@ -38,7 +38,7 @@ class QtVideoOutput: public QObject, public VideoOutput, boost::noncopyable
Q_OBJECT
public:
QtVideoOutput(configuration::IConfiguration::Pointer configuration);
QtVideoOutput(configuration::IConfiguration::Pointer configuration, QWidget* videoContainer=nullptr);
bool open() override;
bool init() override;
void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) override;
@ -57,6 +57,7 @@ private:
SequentialBuffer videoBuffer_;
std::unique_ptr<QVideoWidget> videoWidget_;
std::unique_ptr<QMediaPlayer> mediaPlayer_;
QWidget* videoContainer_;
};
}

View File

@ -20,6 +20,7 @@
#include <f1x/openauto/autoapp/Service/IServiceFactory.hpp>
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
#include <f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp>
namespace f1x
{
@ -33,8 +34,13 @@ namespace service
class ServiceFactory: public IServiceFactory
{
public:
ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration);
ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration, QWidget* activeArea=nullptr, std::function<void(bool)> activeCallback=nullptr);
ServiceList create(aasdk::messenger::IMessenger::Pointer messenger) override;
void setOpacity(unsigned int alpha);
static QRect mapActiveAreaToGlobal(QWidget* activeArea);
#ifdef USE_OMX
static projection::DestRect QRectToDestRect(QRect rect);
#endif
private:
IService::Pointer createVideoService(aasdk::messenger::IMessenger::Pointer messenger);
@ -44,6 +50,12 @@ private:
boost::asio::io_service& ioService_;
configuration::IConfiguration::Pointer configuration_;
QWidget* activeArea_;
QRect screenGeometry_;
std::function<void(bool)> activeCallback_;
#ifdef USE_OMX
std::shared_ptr<projection::OMXVideoOutput> omxVideoOutput_;
#endif
};
}

View File

@ -46,6 +46,7 @@ public:
void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override;
void onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) override;
void onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication) override;
void onAVChannelStopIndication(const aasdk::proto::messages::AVChannelStopIndication& indication) override;
void onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) override;
void onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) override;
void onVideoFocusRequest(const aasdk::proto::messages::VideoFocusRequest& request) override;

View File

@ -36,6 +36,22 @@ namespace autoapp
namespace projection
{
DestRect::DestRect()
: fullscreen(OMX_TRUE)
{
}
DestRect::DestRect(OMX_S16 _xOffset, OMX_S16 _yOffset, OMX_S16 _width, OMX_S16 _height)
: fullscreen(OMX_FALSE)
, xOffset(_xOffset)
, yOffset(_yOffset)
, width(_width)
, height(_height)
{
}
namespace VideoComponent
{
static constexpr uint32_t DECODER = 0;
@ -44,11 +60,14 @@ namespace VideoComponent
static constexpr uint32_t SCHEDULER = 3;
}
OMXVideoOutput::OMXVideoOutput(configuration::IConfiguration::Pointer configuration)
OMXVideoOutput::OMXVideoOutput(configuration::IConfiguration::Pointer configuration, DestRect destRect, std::function<void(bool)> activeCallback)
: VideoOutput(std::move(configuration))
, isActive_(false)
, portSettingsChanged_(false)
, client_(nullptr)
, destRect_(destRect)
, alpha_(255)
, activeCallback_(activeCallback)
{
memset(components_, 0, sizeof(components_));
memset(tunnels_, 0, sizeof(tunnels_));
@ -95,6 +114,10 @@ bool OMXVideoOutput::open()
}
isActive_ = true;
if(this->activeCallback_ != nullptr)
{
this->activeCallback_(isActive_);
}
return true;
}
@ -115,10 +138,20 @@ bool OMXVideoOutput::setupDisplayRegion()
displayRegion.nVersion.nVersion = OMX_VERSION;
displayRegion.nPortIndex = 90;
displayRegion.layer = static_cast<OMX_S32>(configuration_->getOMXLayerIndex());
displayRegion.fullscreen = OMX_TRUE;
displayRegion.fullscreen = destRect_.fullscreen;
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)
{
displayRegion.alpha = alpha_;
displayRegion.dest_rect.x_offset = destRect_.xOffset;
displayRegion.dest_rect.y_offset = destRect_.yOffset;
displayRegion.dest_rect.width = destRect_.width;
displayRegion.dest_rect.height = destRect_.height;
displayRegion.set = static_cast<OMX_DISPLAYSETTYPE >(displayRegion.set | OMX_DISPLAY_SET_ALPHA | OMX_DISPLAY_SET_DEST_RECT);
}
return OMX_SetConfig(ilclient_get_handle(components_[VideoComponent::RENDERER]), OMX_IndexConfigDisplayRegion, &displayRegion) == OMX_ErrorNone;
}
@ -186,6 +219,10 @@ void OMXVideoOutput::stop()
if(isActive_)
{
isActive_ = false;
if(this->activeCallback_ != nullptr)
{
this->activeCallback_(isActive_);
}
ilclient_disable_tunnel(&tunnels_[0]);
ilclient_disable_tunnel(&tunnels_[1]);
@ -199,6 +236,27 @@ void OMXVideoOutput::stop()
ilclient_cleanup_components(components_);
OMX_Deinit();
ilclient_destroy(client_);
client_ = nullptr;
portSettingsChanged_ = false;
}
}
void OMXVideoOutput::setOpacity(OMX_U32 alpha)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
alpha_ = alpha;
if(isActive_)
{
OMX_CONFIG_DISPLAYREGIONTYPE displayRegion;
displayRegion.nSize = sizeof(OMX_CONFIG_DISPLAYREGIONTYPE);
displayRegion.nVersion.nVersion = OMX_VERSION;
displayRegion.nPortIndex = 90;
displayRegion.alpha = alpha_;
displayRegion.set = static_cast<OMX_DISPLAYSETTYPE >(OMX_DISPLAY_SET_ALPHA);
OMX_SetConfig(ilclient_get_handle(components_[VideoComponent::RENDERER]), OMX_IndexConfigDisplayRegion, &displayRegion) == OMX_ErrorNone;
}
}

View File

@ -29,8 +29,9 @@ namespace autoapp
namespace projection
{
QtVideoOutput::QtVideoOutput(configuration::IConfiguration::Pointer configuration)
QtVideoOutput::QtVideoOutput(configuration::IConfiguration::Pointer configuration, QWidget* videoContainer)
: VideoOutput(std::move(configuration))
, videoContainer_(videoContainer)
{
this->moveToThread(QApplication::instance()->thread());
connect(this, &QtVideoOutput::startPlayback, this, &QtVideoOutput::onStartPlayback, Qt::QueuedConnection);
@ -42,7 +43,7 @@ QtVideoOutput::QtVideoOutput(configuration::IConfiguration::Pointer configuratio
void QtVideoOutput::createVideoOutput()
{
OPENAUTO_LOG(debug) << "[QtVideoOutput] create.";
videoWidget_ = std::make_unique<QVideoWidget>();
videoWidget_ = std::make_unique<QVideoWidget>(videoContainer_);
mediaPlayer_ = std::make_unique<QMediaPlayer>(nullptr, QMediaPlayer::StreamPlayback);
}
@ -70,10 +71,17 @@ void QtVideoOutput::write(uint64_t, const aasdk::common::DataConstBuffer& buffer
void QtVideoOutput::onStartPlayback()
{
videoWidget_->setAspectRatioMode(Qt::IgnoreAspectRatio);
videoWidget_->setFocus();
videoWidget_->setWindowFlags(Qt::WindowStaysOnTopHint);
videoWidget_->setFullScreen(true);
if (videoContainer_ == nullptr)
{
videoWidget_->setAspectRatioMode(Qt::IgnoreAspectRatio);
videoWidget_->setFocus();
videoWidget_->setWindowFlags(Qt::WindowStaysOnTopHint);
videoWidget_->setFullScreen(true);
}
else
{
videoWidget_->resize(videoContainer_->size());
}
videoWidget_->show();
mediaPlayer_->setVideoOutput(videoWidget_.get());

View File

@ -272,6 +272,8 @@ void AndroidAutoEntity::sendPing()
promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
aasdk::proto::messages::PingRequest request;
auto timestamp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
request.set_timestamp(timestamp.count());
controlServiceChannel_->sendPingRequest(request, std::move(promise));
}

View File

@ -49,9 +49,15 @@ namespace autoapp
namespace service
{
ServiceFactory::ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration)
ServiceFactory::ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration, QWidget *activeArea, std::function<void(bool)> activeCallback)
: ioService_(ioService)
, configuration_(std::move(configuration))
, activeArea_(activeArea)
, screenGeometry_(this->mapActiveAreaToGlobal(activeArea_))
, activeCallback_(activeCallback)
#ifdef USE_OMX
, omxVideoOutput_(std::make_shared<projection::OMXVideoOutput>(configuration_, this->QRectToDestRect(screenGeometry_), activeCallback_))
#endif
{
}
@ -74,9 +80,10 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng
IService::Pointer ServiceFactory::createVideoService(aasdk::messenger::IMessenger::Pointer messenger)
{
#ifdef USE_OMX
auto videoOutput(std::make_shared<projection::OMXVideoOutput>(configuration_));
auto videoOutput(omxVideoOutput_);
#else
projection::IVideoOutput::Pointer videoOutput(new projection::QtVideoOutput(configuration_), std::bind(&QObject::deleteLater, std::placeholders::_1));
auto qtVideoOutput = new projection::QtVideoOutput(configuration_, activeArea_);
projection::IVideoOutput::Pointer videoOutput(qtVideoOutput, std::bind(&QObject::deleteLater, std::placeholders::_1));
#endif
return std::make_shared<VideoService>(ioService_, messenger, std::move(videoOutput));
}
@ -120,9 +127,8 @@ IService::Pointer ServiceFactory::createInputService(aasdk::messenger::IMessenge
break;
}
QScreen* screen = QGuiApplication::primaryScreen();
QRect screenGeometry = screen == nullptr ? QRect(0, 0, 1, 1) : screen->geometry();
projection::IInputDevice::Pointer inputDevice(std::make_shared<projection::InputDevice>(*QApplication::instance(), configuration_, std::move(screenGeometry), std::move(videoGeometry)));
QObject* inputObject = activeArea_ == nullptr ? qobject_cast<QObject*>(QApplication::instance()) : qobject_cast<QObject*>(activeArea_);
projection::IInputDevice::Pointer inputDevice(std::make_shared<projection::InputDevice>(*inputObject, configuration_, std::move(screenGeometry_), std::move(videoGeometry)));
return std::make_shared<InputService>(ioService_, messenger, std::move(inputDevice));
}
@ -154,6 +160,34 @@ void ServiceFactory::createAudioServices(ServiceList& serviceList, aasdk::messen
serviceList.emplace_back(std::make_shared<SystemAudioService>(ioService_, messenger, std::move(systemAudioOutput)));
}
void ServiceFactory::setOpacity(unsigned int alpha)
{
#ifdef USE_OMX
omxVideoOutput_->setOpacity(alpha);
#endif
}
QRect ServiceFactory::mapActiveAreaToGlobal(QWidget* activeArea)
{
if (activeArea == nullptr)
{
QScreen* screen = QGuiApplication::primaryScreen();
return screen == nullptr ? QRect(0, 0, 1, 1) : screen->geometry();
}
QRect g = activeArea->geometry();
QPoint p = activeArea->mapToGlobal(g.topLeft());
return QRect(p.x(), p.y(), g.width(), g.height());
}
#ifdef USE_OMX
projection::DestRect ServiceFactory::QRectToDestRect(QRect rect)
{
return projection::DestRect(rect.x(), rect.y(), rect.width(), rect.height());
}
#endif
}
}
}

View File

@ -95,6 +95,13 @@ void VideoService::onAVChannelStartIndication(const aasdk::proto::messages::AVCh
channel_->receive(this->shared_from_this());
}
void VideoService::onAVChannelStopIndication(const aasdk::proto::messages::AVChannelStopIndication& indication)
{
OPENAUTO_LOG(info) << "[VideoService] stop indication";
channel_->receive(this->shared_from_this());
}
void VideoService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer)
{
videoOutput_->write(timestamp, buffer);