mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 15:45:38 +00:00
Added 'iterationCount' and 'onIterationsDone' properties to the video element
This commit is contained in:
parent
89d94bc1b0
commit
c15aa73de2
|
@ -88,7 +88,7 @@ bool MediaViewer::startMediaViewer(FileData* game)
|
||||||
void MediaViewer::stopMediaViewer()
|
void MediaViewer::stopMediaViewer()
|
||||||
{
|
{
|
||||||
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
ViewController::getInstance()->stopViewVideos();
|
ViewController::getInstance()->startViewVideos();
|
||||||
|
|
||||||
mVideoFile = "";
|
mVideoFile = "";
|
||||||
mVideo.reset();
|
mVideo.reset();
|
||||||
|
|
|
@ -48,7 +48,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
LOG(LogError) << "Couldn't find PDF conversion binary es-pdf-convert";
|
LOG(LogError) << "Couldn't find PDF conversion binary es-pdf-convert";
|
||||||
#endif
|
#endif
|
||||||
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
ViewController::getInstance()->stopViewVideos();
|
ViewController::getInstance()->startViewVideos();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
if (!Utils::FileSystem::exists(mManualPath)) {
|
if (!Utils::FileSystem::exists(mManualPath)) {
|
||||||
LOG(LogError) << "No PDF manual found for game \"" << mGame->getName() << "\"";
|
LOG(LogError) << "No PDF manual found for game \"" << mGame->getName() << "\"";
|
||||||
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
ViewController::getInstance()->stopViewVideos();
|
ViewController::getInstance()->startViewVideos();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
|
|
||||||
if (!getDocumentInfo()) {
|
if (!getDocumentInfo()) {
|
||||||
LOG(LogError) << "PDFViewer: Couldn't load file \"" << mManualPath << "\"";
|
LOG(LogError) << "PDFViewer: Couldn't load file \"" << mManualPath << "\"";
|
||||||
ViewController::getInstance()->stopViewVideos();
|
ViewController::getInstance()->startViewVideos();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
for (int i {1}; i <= mPageCount; ++i) {
|
for (int i {1}; i <= mPageCount; ++i) {
|
||||||
if (mPages.find(i) == mPages.end()) {
|
if (mPages.find(i) == mPages.end()) {
|
||||||
LOG(LogError) << "Couldn't read information for page " << i << ", invalid PDF file?";
|
LOG(LogError) << "Couldn't read information for page " << i << ", invalid PDF file?";
|
||||||
ViewController::getInstance()->stopViewVideos();
|
ViewController::getInstance()->startViewVideos();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
void PDFViewer::stopPDFViewer()
|
void PDFViewer::stopPDFViewer()
|
||||||
{
|
{
|
||||||
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
ViewController::getInstance()->stopViewVideos();
|
ViewController::getInstance()->startViewVideos();
|
||||||
|
|
||||||
mPages.clear();
|
mPages.clear();
|
||||||
mPageImage.reset();
|
mPageImage.reset();
|
||||||
|
|
|
@ -305,6 +305,8 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
||||||
{"metadataElement", BOOLEAN},
|
{"metadataElement", BOOLEAN},
|
||||||
{"gameselector", STRING},
|
{"gameselector", STRING},
|
||||||
{"gameselectorEntry", UNSIGNED_INTEGER},
|
{"gameselectorEntry", UNSIGNED_INTEGER},
|
||||||
|
{"iterationCount", UNSIGNED_INTEGER},
|
||||||
|
{"onIterationsDone", STRING},
|
||||||
{"audio", BOOLEAN},
|
{"audio", BOOLEAN},
|
||||||
{"interpolation", STRING},
|
{"interpolation", STRING},
|
||||||
{"color", COLOR},
|
{"color", COLOR},
|
||||||
|
|
|
@ -31,6 +31,7 @@ VideoComponent::VideoComponent()
|
||||||
, mTopLeftCrop {0.0f, 0.0f}
|
, mTopLeftCrop {0.0f, 0.0f}
|
||||||
, mBottomRightCrop {1.0f, 1.0f}
|
, mBottomRightCrop {1.0f, 1.0f}
|
||||||
, mPillarboxThreshold {0.85f, 0.90f}
|
, mPillarboxThreshold {0.85f, 0.90f}
|
||||||
|
, mOnIterationsDone {OnIterationsDone::NOTHING}
|
||||||
, mStartTime {0}
|
, mStartTime {0}
|
||||||
, mIsPlaying {false}
|
, mIsPlaying {false}
|
||||||
, mIsActuallyPlaying {false}
|
, mIsActuallyPlaying {false}
|
||||||
|
@ -46,6 +47,8 @@ VideoComponent::VideoComponent()
|
||||||
, mGeneralFade {false}
|
, mGeneralFade {false}
|
||||||
, mFadeIn {1.0f}
|
, mFadeIn {1.0f}
|
||||||
, mFadeInTime {1000.0f}
|
, mFadeInTime {1000.0f}
|
||||||
|
, mIterationCount {0}
|
||||||
|
, mPlayCount {0}
|
||||||
{
|
{
|
||||||
// Setup default configuration.
|
// Setup default configuration.
|
||||||
mConfig.showStaticImageDelay = false;
|
mConfig.showStaticImageDelay = false;
|
||||||
|
@ -186,6 +189,23 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
|
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
|
||||||
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
|
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
|
||||||
|
|
||||||
|
if (elem->has("iterationCount")) {
|
||||||
|
mIterationCount = glm::clamp(elem->get<unsigned int>("iterationCount"), 0u, 10u);
|
||||||
|
|
||||||
|
if (properties && elem->has("onIterationsDone")) {
|
||||||
|
const std::string& onIterationsDone {elem->get<std::string>("onIterationsDone")};
|
||||||
|
if (onIterationsDone == "nothing")
|
||||||
|
mOnIterationsDone = OnIterationsDone::NOTHING;
|
||||||
|
else if (onIterationsDone == "image")
|
||||||
|
mOnIterationsDone = OnIterationsDone::IMAGE;
|
||||||
|
else
|
||||||
|
LOG(LogWarning) << "VideoComponent: Invalid theme configuration, property "
|
||||||
|
"\"onIterationsDone\" for element \""
|
||||||
|
<< element.substr(6) << "\" defined as \"" << onIterationsDone
|
||||||
|
<< "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (elem->has("audio"))
|
if (elem->has("audio"))
|
||||||
mPlayAudio = elem->get<bool>("audio");
|
mPlayAudio = elem->get<bool>("audio");
|
||||||
|
|
||||||
|
@ -343,6 +363,9 @@ std::vector<HelpPrompt> VideoComponent::getHelpPrompts()
|
||||||
|
|
||||||
void VideoComponent::update(int deltaTime)
|
void VideoComponent::update(int deltaTime)
|
||||||
{
|
{
|
||||||
|
if (mIterationCount != 0 && mPlayCount == mIterationCount)
|
||||||
|
return;
|
||||||
|
|
||||||
// A deltaTime value of 0 would lead to mFadeIn being an invalid number which would prevent
|
// A deltaTime value of 0 would lead to mFadeIn being an invalid number which would prevent
|
||||||
// the video from being rendered. This can happen on application startup in some instances.
|
// the video from being rendered. This can happen on application startup in some instances.
|
||||||
if (deltaTime == 0)
|
if (deltaTime == 0)
|
||||||
|
@ -397,6 +420,8 @@ void VideoComponent::update(int deltaTime)
|
||||||
|
|
||||||
void VideoComponent::startVideoPlayer()
|
void VideoComponent::startVideoPlayer()
|
||||||
{
|
{
|
||||||
|
mPlayCount = 0;
|
||||||
|
|
||||||
if (mIsPlaying)
|
if (mIsPlaying)
|
||||||
stopVideoPlayer();
|
stopVideoPlayer();
|
||||||
|
|
||||||
|
@ -408,9 +433,9 @@ void VideoComponent::startVideoPlayer()
|
||||||
mPaused = false;
|
mPaused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoComponent::renderStaticImage(const glm::mat4& parentTrans)
|
void VideoComponent::renderStaticImage(const glm::mat4& parentTrans, bool forceRender)
|
||||||
{
|
{
|
||||||
if (mHasVideo && (!mConfig.showStaticImageDelay || mConfig.startDelay == 0))
|
if (mHasVideo && (!forceRender && (!mConfig.showStaticImageDelay || mConfig.startDelay == 0)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mStaticImagePath != "") {
|
if (mStaticImagePath != "") {
|
||||||
|
|
|
@ -92,7 +92,12 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void startVideoStream() {}
|
virtual void startVideoStream() {}
|
||||||
void renderStaticImage(const glm::mat4& parentTrans);
|
void renderStaticImage(const glm::mat4& parentTrans, bool forceRender);
|
||||||
|
|
||||||
|
enum class OnIterationsDone {
|
||||||
|
NOTHING,
|
||||||
|
IMAGE
|
||||||
|
};
|
||||||
|
|
||||||
ImageComponent mStaticImage;
|
ImageComponent mStaticImage;
|
||||||
|
|
||||||
|
@ -116,6 +121,7 @@ protected:
|
||||||
"cover", "backcover", "3dbox", "physicalmedia", "fanart"};
|
"cover", "backcover", "3dbox", "physicalmedia", "fanart"};
|
||||||
|
|
||||||
std::string mVideoPath;
|
std::string mVideoPath;
|
||||||
|
OnIterationsDone mOnIterationsDone;
|
||||||
unsigned mStartTime;
|
unsigned mStartTime;
|
||||||
std::atomic<bool> mIsPlaying;
|
std::atomic<bool> mIsPlaying;
|
||||||
std::atomic<bool> mIsActuallyPlaying;
|
std::atomic<bool> mIsActuallyPlaying;
|
||||||
|
@ -131,6 +137,8 @@ protected:
|
||||||
bool mGeneralFade;
|
bool mGeneralFade;
|
||||||
float mFadeIn;
|
float mFadeIn;
|
||||||
float mFadeInTime;
|
float mFadeInTime;
|
||||||
|
int mIterationCount;
|
||||||
|
int mPlayCount;
|
||||||
|
|
||||||
Configuration mConfig;
|
Configuration mConfig;
|
||||||
};
|
};
|
||||||
|
|
|
@ -165,6 +165,12 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
|
||||||
if (!mHasVideo && mStaticImagePath == "")
|
if (!mHasVideo && mStaticImagePath == "")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (mIterationCount != 0 && mPlayCount == mIterationCount) {
|
||||||
|
if (mOnIterationsDone == OnIterationsDone::IMAGE)
|
||||||
|
VideoComponent::renderStaticImage(parentTrans, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
glm::mat4 trans {parentTrans * getTransform()};
|
glm::mat4 trans {parentTrans * getTransform()};
|
||||||
GuiComponent::renderChildren(trans);
|
GuiComponent::renderChildren(trans);
|
||||||
|
|
||||||
|
@ -203,7 +209,7 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
|
||||||
vertices[3].color = mColorShiftEnd;
|
vertices[3].color = mColorShiftEnd;
|
||||||
|
|
||||||
// Round vertices.
|
// Round vertices.
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i {0}; i < 4; ++i)
|
||||||
vertices[i].position = glm::round(vertices[i].position);
|
vertices[i].position = glm::round(vertices[i].position);
|
||||||
|
|
||||||
if (mFadeIn < 1.0f || mThemeOpacity < 1.0f)
|
if (mFadeIn < 1.0f || mThemeOpacity < 1.0f)
|
||||||
|
@ -265,8 +271,7 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
|
||||||
Renderer::BlendFactor::ONE_MINUS_SRC_ALPHA);
|
Renderer::BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (mVisible)
|
VideoComponent::renderStaticImage(parentTrans, false);
|
||||||
VideoComponent::renderStaticImage(parentTrans);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,7 +652,7 @@ void VideoFFmpegComponent::readFrames()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mVideoCodecContext && mFormatContext) {
|
if (mVideoCodecContext && mFormatContext) {
|
||||||
for (int i = 0; i < readLoops; ++i) {
|
for (int i {0}; i < readLoops; ++i) {
|
||||||
if (static_cast<int>(mVideoFrameQueue.size()) < mVideoTargetQueueSize ||
|
if (static_cast<int>(mVideoFrameQueue.size()) < mVideoTargetQueueSize ||
|
||||||
(mAudioStreamIndex >= 0 &&
|
(mAudioStreamIndex >= 0 &&
|
||||||
static_cast<int>(mAudioFrameQueue.size()) < mAudioTargetQueueSize)) {
|
static_cast<int>(mAudioFrameQueue.size()) < mAudioTargetQueueSize)) {
|
||||||
|
@ -1152,7 +1157,7 @@ bool VideoFFmpegComponent::decoderInitHW()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 50 is just an arbitrary number so we don't potentially get stuck in an endless loop.
|
// 50 is just an arbitrary number so we don't potentially get stuck in an endless loop.
|
||||||
for (int i = 0; i < 50; ++i) {
|
for (int i {0}; i < 50; ++i) {
|
||||||
const AVCodecHWConfig* config {avcodec_get_hw_config(mHardwareCodec, i)};
|
const AVCodecHWConfig* config {avcodec_get_hw_config(mHardwareCodec, i)};
|
||||||
if (!config) {
|
if (!config) {
|
||||||
LOG(LogDebug) << "VideoFFmpegComponent::decoderInitHW(): Hardware decoder \""
|
LOG(LogDebug) << "VideoFFmpegComponent::decoderInitHW(): Hardware decoder \""
|
||||||
|
@ -1245,7 +1250,7 @@ bool VideoFFmpegComponent::decoderInitHW()
|
||||||
// For some videos we need to process at least one extra frame to verify
|
// For some videos we need to process at least one extra frame to verify
|
||||||
// that the hardware encoder can actually be used, otherwise the fallback
|
// that the hardware encoder can actually be used, otherwise the fallback
|
||||||
// to software decoding would take place when it's not necessary.
|
// to software decoding would take place when it's not necessary.
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i {0}; i < 3; ++i) {
|
||||||
if (avcodec_receive_frame(checkCodecContext, checkFrame) < 0) {
|
if (avcodec_receive_frame(checkCodecContext, checkFrame) < 0) {
|
||||||
av_packet_unref(checkPacket);
|
av_packet_unref(checkPacket);
|
||||||
while (av_read_frame(mFormatContext, checkPacket) == 0) {
|
while (av_read_frame(mFormatContext, checkPacket) == 0) {
|
||||||
|
@ -1611,13 +1616,14 @@ void VideoFFmpegComponent::pauseVideoPlayer()
|
||||||
void VideoFFmpegComponent::handleLooping()
|
void VideoFFmpegComponent::handleLooping()
|
||||||
{
|
{
|
||||||
if (mIsPlaying && mEndOfVideo) {
|
if (mIsPlaying && mEndOfVideo) {
|
||||||
|
++mPlayCount;
|
||||||
// If the screensaver video swap time is set to 0, it means we should
|
// If the screensaver video swap time is set to 0, it means we should
|
||||||
// skip to the next game when the video has finished playing.
|
// skip to the next game when the video has finished playing.
|
||||||
if (mScreensaverMode &&
|
if (mScreensaverMode &&
|
||||||
Settings::getInstance()->getInt("ScreensaverSwapVideoTimeout") == 0) {
|
Settings::getInstance()->getInt("ScreensaverSwapVideoTimeout") == 0) {
|
||||||
mWindow->screensaverTriggerNextGame();
|
mWindow->screensaverTriggerNextGame();
|
||||||
}
|
}
|
||||||
else {
|
else if (mIterationCount == 0 || mPlayCount < mIterationCount) {
|
||||||
stopVideoPlayer();
|
stopVideoPlayer();
|
||||||
startVideoStream();
|
startVideoStream();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue