mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 00:28:42 +00:00
Enable RLV for QT6 Video Window (#4609)
Overview widgets are enabled too for Windows and Linux, like they were when using VLC, macOS needs more testing.
This commit is contained in:
@@ -84,6 +84,10 @@
|
||||
#include "TrainDB.h"
|
||||
#include "Library.h"
|
||||
|
||||
#if defined(GC_HAVE_VLC)||defined(GC_VIDEO_QT6) // RLV currently only support for VLC
|
||||
#define USE_RLV
|
||||
#endif
|
||||
|
||||
TrainSidebar::TrainSidebar(Context *context) : GcWindow(context), context(context),
|
||||
bicycle(context)
|
||||
{
|
||||
@@ -149,7 +153,7 @@ TrainSidebar::TrainSidebar(Context *context) : GcWindow(context), context(contex
|
||||
mediaTree->verticalScrollBar()->setStyle(cde);
|
||||
#endif
|
||||
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncModel = trainDB->getVideoSyncModel();
|
||||
|
||||
vssortModel = new QSortFilterProxyModel(this);
|
||||
@@ -186,7 +190,7 @@ TrainSidebar::TrainSidebar(Context *context) : GcWindow(context), context(contex
|
||||
videosyncTree->verticalScrollBar()->setStyle(cdevideosync);
|
||||
#endif
|
||||
|
||||
#endif //GC_HAVE_VLC
|
||||
#endif //USE_RLV
|
||||
|
||||
#endif //GC_VIDEO_NONE
|
||||
|
||||
@@ -320,7 +324,7 @@ TrainSidebar::TrainSidebar(Context *context) : GcWindow(context), context(contex
|
||||
mediaTree->setWhatsThis(helpMediaTree->getWhatsThisText(HelpWhatsThis::SideBarTrainView_Media));
|
||||
trainSplitter->addWidget(mediaItem);
|
||||
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncItem = new GcSplitterItem(tr("VideoSync"), iconFromPNG(":images/sidebar/sync.png"), this);
|
||||
QAction *moreVideoSyncAct = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this);
|
||||
videosyncItem->addAction(moreVideoSyncAct);
|
||||
@@ -329,7 +333,7 @@ TrainSidebar::TrainSidebar(Context *context) : GcWindow(context), context(contex
|
||||
HelpWhatsThis *helpVideosyncTree = new HelpWhatsThis(videosyncTree);
|
||||
videosyncTree->setWhatsThis(helpVideosyncTree->getWhatsThisText(HelpWhatsThis::SideBarTrainView_VideoSync));
|
||||
trainSplitter->addWidget(videosyncItem);
|
||||
#endif //GC_HAVE_VLC
|
||||
#endif //USE_RLV
|
||||
#endif //GC_VIDEO_NONE
|
||||
trainSplitter->prepare(context->athlete->cyclist, "train");
|
||||
|
||||
@@ -354,11 +358,11 @@ TrainSidebar::TrainSidebar(Context *context) : GcWindow(context), context(contex
|
||||
connect(mediaTree->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||
this, SLOT(mediaTreeWidgetSelectionChanged()));
|
||||
connect(context, SIGNAL(selectMedia(QString)), this, SLOT(selectVideo(QString)));
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
connect(videosyncTree->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||
this, SLOT(videosyncTreeWidgetSelectionChanged()));
|
||||
connect(context, SIGNAL(selectVideoSync(QString)), this, SLOT(selectVideoSync(QString)));
|
||||
#endif //GC_HAVE_VLC
|
||||
#endif //USE_RLV
|
||||
#endif //GC_VIDEO_NONE
|
||||
connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32)));
|
||||
connect(context, SIGNAL(selectWorkout(QString)), this, SLOT(selectWorkout(QString)));
|
||||
@@ -438,7 +442,7 @@ TrainSidebar::~TrainSidebar
|
||||
if (videoModel != nullptr) {
|
||||
delete videoModel;
|
||||
}
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
if (videosyncModel != nullptr) {
|
||||
delete videosyncModel;
|
||||
}
|
||||
@@ -459,7 +463,7 @@ TrainSidebar::refresh()
|
||||
row = mediaTree->currentIndex().row();
|
||||
QString videoPath = mediaTree->model()->data(mediaTree->model()->index(row, TdbVideoModelIdx::filepath)).toString();
|
||||
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
// refresh data
|
||||
QAbstractTableModel *oldVideoModel = videoModel;
|
||||
videoModel = trainDB->getVideoModel();
|
||||
@@ -471,7 +475,7 @@ TrainSidebar::refresh()
|
||||
// restore selection
|
||||
selectVideo(videoPath);
|
||||
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
// remember selection
|
||||
row = videosyncTree->currentIndex().row();
|
||||
QString videosyncPath = videosyncTree->model()->data(videosyncTree->model()->index(row, TdbVideosyncModelIdx::filepath)).toString();
|
||||
@@ -485,7 +489,7 @@ TrainSidebar::refresh()
|
||||
|
||||
// restore selection
|
||||
selectVideoSync(videosyncPath);
|
||||
#endif // GC_HAVE_VLC
|
||||
#endif // USE_RLV
|
||||
|
||||
#endif // GC_VIDEO_NONE
|
||||
|
||||
@@ -695,7 +699,7 @@ TrainSidebar::configChanged(qint32 why)
|
||||
setProperty("color", GColor(CTRAINPLOTBACKGROUND));
|
||||
#if !defined GC_VIDEO_NONE
|
||||
mediaTree->setStyleSheet(GCColor::stylesheet(true));
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncTree->setStyleSheet(GCColor::stylesheet(true));
|
||||
#endif
|
||||
#endif
|
||||
@@ -931,7 +935,7 @@ TrainSidebar::workoutTreeWidgetSelectionChanged()
|
||||
QString workoutName = QFileInfo(filename).baseName();
|
||||
mediaTree->setFocus();
|
||||
mediaTree->keyboardSearch(workoutName);
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncTree->setFocus();
|
||||
videosyncTree->keyboardSearch(workoutName);
|
||||
#endif
|
||||
@@ -1302,7 +1306,7 @@ void TrainSidebar::Start() // when start button is pressed
|
||||
|
||||
#if !defined GC_VIDEO_NONE
|
||||
mediaTree->setEnabled(false);
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncTree->setEnabled(false);
|
||||
#endif
|
||||
#endif
|
||||
@@ -1329,7 +1333,7 @@ void TrainSidebar::Start() // when start button is pressed
|
||||
#if !defined GC_VIDEO_NONE
|
||||
// enable media tree so we can change movie - mid workout
|
||||
mediaTree->setEnabled(true);
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncTree->setEnabled(true);
|
||||
#endif
|
||||
#endif
|
||||
@@ -1367,7 +1371,7 @@ void TrainSidebar::Start() // when start button is pressed
|
||||
// media or workouts whilst a workout is in progress
|
||||
#if !defined GC_VIDEO_NONE
|
||||
mediaTree->setEnabled(false);
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncTree->setEnabled(false);
|
||||
#endif
|
||||
#endif
|
||||
@@ -1490,7 +1494,7 @@ void TrainSidebar::Pause() // pause capture to recalibrate
|
||||
|
||||
#if !defined GC_VIDEO_NONE
|
||||
mediaTree->setEnabled(false);
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncTree->setEnabled(false);
|
||||
#endif
|
||||
#endif
|
||||
@@ -1511,7 +1515,7 @@ void TrainSidebar::Pause() // pause capture to recalibrate
|
||||
// enable media tree so we can change movie
|
||||
#if !defined GC_VIDEO_NONE
|
||||
mediaTree->setEnabled(true);
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncTree->setEnabled(true);
|
||||
#endif
|
||||
#endif
|
||||
@@ -1536,7 +1540,7 @@ void TrainSidebar::Stop(int deviceStatus) // when stop button is pressed
|
||||
// media or workouts whilst a workout is in progress
|
||||
#if !defined GC_VIDEO_NONE
|
||||
mediaTree->setEnabled(true);
|
||||
#ifdef GC_HAVE_VLC // RLV currently only support for VLC
|
||||
#ifdef USE_RLV
|
||||
videosyncTree->setEnabled(true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
#include "VideoLayoutParser.h"
|
||||
#include "HelpWhatsThis.h"
|
||||
|
||||
#if defined(GC_VIDEO_QT5)||defined(GC_VIDEO_QT6)
|
||||
#include <QMediaMetaData>
|
||||
#endif
|
||||
|
||||
class Lock
|
||||
{
|
||||
QRecursiveMutex& mutex;
|
||||
@@ -37,7 +41,7 @@ public:
|
||||
};
|
||||
|
||||
VideoWindow::VideoWindow(Context *context) :
|
||||
GcChartWindow(context), context(context), m_MediaChanged(false), layoutSelector(NULL)
|
||||
GcChartWindow(context), context(context), m_MediaChanged(false), layoutSelector(NULL), container(nullptr)
|
||||
{
|
||||
HelpWhatsThis *helpContents = new HelpWhatsThis(this);
|
||||
this->setWhatsThis(helpContents->getWhatsThisText(HelpWhatsThis::ChartTrain_VideoPlayer));
|
||||
@@ -101,9 +105,30 @@ VideoWindow::VideoWindow(Context *context) :
|
||||
libvlc_media_player_set_xwindow (mp, container->winId());
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(Q_OS_LINUX)
|
||||
} else {
|
||||
// something went wrong !
|
||||
init = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read the video layouts just to list the names for the layout selector
|
||||
#if defined(GC_VIDEO_QT5)||defined(GC_VIDEO_QT6)
|
||||
// USE QT VIDEO PLAYER
|
||||
wd = new QVideoWidget(this);
|
||||
wd->show();
|
||||
|
||||
mp = new QMediaPlayer(this);
|
||||
mp->setVideoOutput(wd);
|
||||
|
||||
#if defined(GC_VIDEO_QT6)
|
||||
mp->setAudioOutput(new QAudioOutput);
|
||||
#endif
|
||||
container = wd;
|
||||
layout->addWidget(container);
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(Q_OS_LINUX)
|
||||
if (init) {
|
||||
// Read the video layouts just to list the names for the layout selector
|
||||
readVideoLayout(-1);
|
||||
|
||||
// Create the layout selector form
|
||||
@@ -134,25 +159,9 @@ VideoWindow::VideoWindow(Context *context) :
|
||||
|
||||
// Instantiate a layout as initial default
|
||||
layoutChanged();
|
||||
#endif
|
||||
} else {
|
||||
|
||||
// something went wrong !
|
||||
init = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GC_VIDEO_QT5)||defined(GC_VIDEO_QT6)
|
||||
// USE QT VIDEO PLAYER
|
||||
wd = new QVideoWidget(this);
|
||||
wd->show();
|
||||
|
||||
mp = new QMediaPlayer(this);
|
||||
mp->setVideoOutput(wd);
|
||||
|
||||
layout->addWidget(wd);
|
||||
#endif
|
||||
|
||||
setControls(c);
|
||||
|
||||
if (init) {
|
||||
@@ -196,6 +205,8 @@ VideoWindow::~VideoWindow()
|
||||
vlcDispatch.AsyncCall([capture_inst]() {libvlc_release(capture_inst); });
|
||||
|
||||
vlcDispatch.Drain();
|
||||
|
||||
delete container;
|
||||
#endif
|
||||
|
||||
#if defined(GC_VIDEO_QT5)||defined(GC_VIDEO_QT6)
|
||||
@@ -346,8 +357,15 @@ void VideoWindow::startPlayback()
|
||||
m_MediaChanged = false;
|
||||
#endif
|
||||
|
||||
#if defined(GC_VIDEO_QT5)||defined(GC_VIDEO_QT6)
|
||||
#ifdef GC_VIDEO_QT5
|
||||
mp->play();
|
||||
#endif
|
||||
#ifdef GC_VIDEO_QT6
|
||||
// open the media object
|
||||
float rate = 1.0f;
|
||||
if (context->currentVideoSyncFile() && context->currentVideoSyncFile()->Points.count() > 1)
|
||||
rate = 0.1f;
|
||||
mp->setPlaybackRate(rate);
|
||||
mp->play();
|
||||
#endif
|
||||
|
||||
@@ -403,12 +421,28 @@ void VideoWindow::startPlayback()
|
||||
}
|
||||
#endif
|
||||
#if defined(GC_VIDEO_QT5)||defined(GC_VIDEO_QT6)
|
||||
// QT doesn't expose media frame rate so make due with duration.
|
||||
double videoSyncDuration = currentVideoSyncFile->duration();
|
||||
if (videoSyncDuration > 0) {
|
||||
double mediaDuration = (double)mp->duration();
|
||||
if (mediaDuration > 0) {
|
||||
videoSyncTimeAdjustFactor = mediaDuration / videoSyncDuration;
|
||||
double videoSyncFrameRate = currentVideoSyncFile->videoFrameRate();
|
||||
if (videoSyncFrameRate > 0.) {
|
||||
bool ok=false;
|
||||
#ifdef GC_VIDEO_QT6
|
||||
auto md = mp->metaData();
|
||||
auto rate = md.value(QMediaMetaData::VideoFrameRate);
|
||||
|
||||
double mediaFrameRate = rate.toReal(&ok);
|
||||
if (mediaFrameRate > 0.) {
|
||||
videoSyncTimeAdjustFactor = videoSyncFrameRate / mediaFrameRate;
|
||||
}
|
||||
#endif
|
||||
if (!ok) //fallback to duration
|
||||
{
|
||||
// QT5 doesn't expose media frame rate so make due with duration.
|
||||
double videoSyncDuration = currentVideoSyncFile->duration();
|
||||
if (videoSyncDuration > 0) {
|
||||
double mediaDuration = (double)mp->duration();
|
||||
if (mediaDuration > 0) {
|
||||
videoSyncTimeAdjustFactor = mediaDuration / videoSyncDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -515,7 +549,7 @@ void VideoWindow::telemetryUpdate(RealtimeData rtd)
|
||||
Lock lock(stateLock);
|
||||
if (!hasActiveVideo())
|
||||
return;
|
||||
|
||||
|
||||
bool metric = GlobalContext::context()->useMetricUnits;
|
||||
|
||||
foreach(MeterWidget* p_meterWidget , m_metersWidget)
|
||||
@@ -705,7 +739,7 @@ void VideoWindow::telemetryUpdate(RealtimeData rtd)
|
||||
Q_UNUSED(rtd)
|
||||
#endif
|
||||
|
||||
#ifdef GC_VIDEO_VLC
|
||||
#if defined (GC_VIDEO_VLC) || defined (GC_VIDEO_QT6)
|
||||
if (PlaybackState::Playing != state)
|
||||
return;
|
||||
|
||||
@@ -773,8 +807,12 @@ void VideoWindow::telemetryUpdate(RealtimeData rtd)
|
||||
float rate;
|
||||
float video_time_shift_ms;
|
||||
|
||||
#ifdef GC_VIDEO_VLC
|
||||
libvlc_media_player_t* capture_mp = this->mp;
|
||||
video_time_shift_ms = (rfp.secs * 1000.0 - vlcDispatch.SyncCall<double>([capture_mp]{ return libvlc_media_player_get_time(capture_mp); }));
|
||||
#else
|
||||
video_time_shift_ms = (rfp.secs * 1000.0 - mp->position() );
|
||||
#endif
|
||||
if (rfp.kph == 0.0)
|
||||
rate = 1.0;
|
||||
else
|
||||
@@ -784,25 +822,40 @@ void VideoWindow::telemetryUpdate(RealtimeData rtd)
|
||||
if (fabs(video_time_shift_ms) > 5000)
|
||||
{
|
||||
double rfp_secs = rfp.secs;
|
||||
#ifdef GC_VIDEO_VLC
|
||||
vlcDispatch.AsyncCall([capture_mp, rfp_secs]{ libvlc_media_player_set_time(capture_mp, (libvlc_time_t)(rfp_secs * 1000.0)); });
|
||||
#else
|
||||
mp->setPosition(rfp_secs * 1000.0);
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
// otherwise add "small" empiric corrective parameter to get video back to ghost position:
|
||||
rate *= 1.0 + (video_time_shift_ms / 10000.0);
|
||||
}
|
||||
|
||||
#ifdef GC_VIDEO_VLC
|
||||
vlcDispatch.AsyncCall([capture_mp, rate]{ libvlc_media_player_set_pause(capture_mp, (rate < 0.01)); });
|
||||
|
||||
#else
|
||||
if (rate < 0.01)
|
||||
mp->pause();
|
||||
else
|
||||
mp->play();
|
||||
#endif
|
||||
// change video rate but only if there is a significant change
|
||||
if ((rate != 0.0) && (fabs((rate - currentVideoRate) / rate) > 0.05))
|
||||
{
|
||||
#ifdef GC_VIDEO_VLC
|
||||
vlcDispatch.AsyncCall([capture_mp, rate]{ libvlc_media_player_set_rate(capture_mp, rate); });
|
||||
#else
|
||||
mp->setPlaybackRate(rate);
|
||||
#endif
|
||||
currentVideoRate = rate;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GC_VIDEO_QT5)||defined(GC_VIDEO_QT6)
|
||||
#ifdef GC_VIDEO_QT5
|
||||
//TODO
|
||||
// // seek to ms position in current file
|
||||
// mp->setPosition(ms);
|
||||
@@ -821,7 +874,8 @@ void VideoWindow::seekPlayback(long ms)
|
||||
|
||||
#ifdef GC_VIDEO_VLC
|
||||
if (!m) return;
|
||||
|
||||
#endif
|
||||
|
||||
// when we selected a videosync file in training mode (rlv...)
|
||||
if (context->currentVideoSyncFile())
|
||||
{
|
||||
@@ -829,18 +883,18 @@ void VideoWindow::seekPlayback(long ms)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GC_VIDEO_VLC
|
||||
// seek to ms position in current file
|
||||
libvlc_media_player_t* capture_mp = this->mp;
|
||||
vlcDispatch.AsyncCall([capture_mp, ms]{ libvlc_media_player_set_time(capture_mp, (libvlc_time_t)ms); });
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if defined(GC_VIDEO_QT5)||defined(GC_VIDEO_QT6)
|
||||
Q_UNUSED(ms)
|
||||
//TODO
|
||||
// // seek to ms position in current file
|
||||
// mp->setPosition(ms);
|
||||
mp->setPosition(ms);
|
||||
#else
|
||||
Q_UNUSED(ms)
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWindow::mediaSelected(QString filename)
|
||||
@@ -898,7 +952,9 @@ void VideoWindow::mediaSelected(QString filename)
|
||||
#endif
|
||||
#ifdef GC_VIDEO_QT6
|
||||
// QT MEDIA
|
||||
mp->setSource(QUrl::fromLocalFile(filename));
|
||||
if (filename != "")
|
||||
mp->setSource(QUrl::fromLocalFile(filename));
|
||||
|
||||
#endif
|
||||
if(context->isRunning) startPlayback();
|
||||
}
|
||||
@@ -923,7 +979,6 @@ MediaHelper::MediaHelper()
|
||||
supported << ".MXF";
|
||||
supported << ".VOB";
|
||||
supported << ".WMV";
|
||||
|
||||
}
|
||||
|
||||
MediaHelper::~MediaHelper()
|
||||
|
||||
@@ -107,7 +107,9 @@ extern "C" {
|
||||
#include <QVideoWidget>
|
||||
#include <QMediaPlayer>
|
||||
#endif
|
||||
|
||||
#ifdef GC_VIDEO_QT6
|
||||
#include <QAudioOutput>
|
||||
#endif
|
||||
#ifdef GC_VIDEO_QT5
|
||||
#include <QMediaContent>
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user