Added support for a <video> tag. This tag works similar to the <image> tag, but has an additional numLoops attribute to indicate the number of times the video should be looped. The default value is numLoops="1", and you can use numLoops="0" for infinite looping.

This commit is contained in:
Pieter Hulshoff 2016-06-26 14:02:25 +02:00
parent ed07075360
commit efe9e323cc
13 changed files with 255 additions and 5 deletions

View File

@ -119,6 +119,7 @@ set(RETROFE_HEADERS
"${RETROFE_DIR}/Source/Graphics/Component/Text.h"
"${RETROFE_DIR}/Source/Graphics/Component/VideoComponent.h"
"${RETROFE_DIR}/Source/Graphics/Component/VideoBuilder.h"
"${RETROFE_DIR}/Source/Graphics/Component/Video.h"
"${RETROFE_DIR}/Source/Graphics/Font.h"
"${RETROFE_DIR}/Source/Graphics/FontCache.h"
"${RETROFE_DIR}/Source/Graphics/PageBuilder.h"
@ -173,6 +174,7 @@ set(RETROFE_SOURCES
"${RETROFE_DIR}/Source/Graphics/Component/ScrollingList.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/VideoBuilder.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/VideoComponent.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/Video.cpp"
"${RETROFE_DIR}/Source/Sound/Sound.cpp"
"${RETROFE_DIR}/Source/Utility/Log.cpp"
"${RETROFE_DIR}/Source/Utility/Utils.cpp"

View File

@ -329,3 +329,9 @@ bool Component::animate()
return completeDone;
}
bool Component::isPlaying()
{
return false;
}

View File

@ -43,6 +43,7 @@ public:
virtual void update(float dt);
virtual void draw();
void setTweens(AnimationEvents *set);
virtual bool isPlaying();
ViewInfo baseViewInfo;
std::string collectionName;

View File

@ -0,0 +1,131 @@
/* This file is part of RetroFE.
*
* RetroFE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RetroFE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Video.h"
#include "VideoComponent.h"
#include "VideoBuilder.h"
#include "../../Video/IVideo.h"
#include "../../Video/GStreamerVideo.h"
#include "../../Utility/Log.h"
#include "../../SDL.h"
Video::Video(std::string file, std::string altFile, int numLoops, Page &p, float scaleX, float scaleY)
: Component(p)
, video_(NULL)
, file_(file)
, altFile_(altFile)
, numLoops_(numLoops)
, scaleX_(scaleX)
, scaleY_(scaleY)
{
allocateGraphicsMemory( );
}
Video::~Video( )
{
if (video_ != NULL)
{
delete video_;
}
}
void Video::update(float dt)
{
if(video_)
{
// video needs to run a frame to start getting size info
if(baseViewInfo.ImageHeight == 0 && baseViewInfo.ImageWidth == 0)
{
baseViewInfo.ImageWidth = video_->baseViewInfo.ImageWidth;
baseViewInfo.ImageHeight = video_->baseViewInfo.ImageHeight;
}
video_->update(dt);
}
Component::update(dt);
}
void Video::freeGraphicsMemory( )
{
Component::freeGraphicsMemory( );
if(video_)
{
video_->freeGraphicsMemory( );
}
}
void Video::allocateGraphicsMemory( )
{
Component::allocateGraphicsMemory( );
if (!video_)
{
std::string file = "";
std::ifstream f(altFile_.c_str( ));
if (f.good( ))
file = altFile_;
std::ifstream g(file_.c_str( ));
if (g.good( ))
file = file_;
if (file != "")
{
IVideo *video = new GStreamerVideo();
video->initialize();
((GStreamerVideo *)(video))->setNumLoops(numLoops_);
video_ = new VideoComponent( video, page, file, scaleX_, scaleY_ );
}
}
if (video_)
video_->allocateGraphicsMemory();
}
void Video::draw( )
{
Component::draw( );
if(video_)
{
baseViewInfo.ImageHeight = video_->baseViewInfo.ImageHeight;
baseViewInfo.ImageWidth = video_->baseViewInfo.ImageWidth;
video_->baseViewInfo = baseViewInfo;
video_->draw( );
}
}
bool Video::isPlaying( )
{
if (video_)
{
return video_->isPlaying( );
}
else
{
return false;
}
}

View File

@ -0,0 +1,40 @@
/* This file is part of RetroFE.
*
* RetroFE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RetroFE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Component.h"
#include "../../Video/IVideo.h"
#include <SDL2/SDL.h>
#include <string>
class Video : public Component
{
public:
Video( std::string file, std::string altFile, int numLoops, Page &page, float scaleX, float scaleY );
virtual ~Video( );
void update(float dt);
void freeGraphicsMemory( );
void allocateGraphicsMemory( );
void draw( );
virtual bool isPlaying( );
protected:
Component *video_;
std::string file_;
std::string altFile_;
int numLoops_;
float scaleX_;
float scaleY_;
};

View File

@ -18,6 +18,7 @@
#include "../ViewInfo.h"
#include "../../Database/Configuration.h"
#include "../../Utility/Log.h"
#include "../../Video/GStreamerVideo.h"
#include "../../SDL.h"
VideoComponent::VideoComponent(IVideo *videoInst, Page &p, std::string videoFile, float scaleX, float scaleY)
@ -43,6 +44,10 @@ VideoComponent::~VideoComponent()
void VideoComponent::update(float dt)
{
if (videoInst_)
{
isPlaying_ = ((GStreamerVideo *)(videoInst_))->isPlaying();
}
if(isPlaying_)
{
videoInst_->update(dt);
@ -103,3 +108,8 @@ void VideoComponent::draw()
SDL::renderCopy(texture, baseViewInfo.Alpha, NULL, &rect, static_cast<int>(baseViewInfo.Angle), baseViewInfo.Reflection, baseViewInfo.ReflectionDistance, baseViewInfo.ReflectionScale, baseViewInfo.ReflectionAlpha);
}
}
bool VideoComponent::isPlaying()
{
return isPlaying_;
}

View File

@ -33,6 +33,7 @@ public:
void allocateGraphicsMemory();
void launchEnter();
void launchExit();
virtual bool isPlaying();
private:
std::string videoFile_;

View File

@ -787,3 +787,18 @@ bool Page::isMenuScrolling()
{
return scrollActive_;
}
bool Page::isPlaying()
{
bool retVal = false;
for(std::vector<Component *>::iterator it = LayerComponents.begin(); it != LayerComponents.end(); ++it)
{
retVal |= (*it)->isPlaying();
}
return retVal;
}

View File

@ -91,6 +91,7 @@ public:
void removePlaylist();
void reallocateMenuSpritePoints();
bool isMenuScrolling();
bool isPlaying();
private:
void playlistChange();

View File

@ -23,6 +23,7 @@
#include "Component/ReloadableText.h"
#include "Component/ReloadableMedia.h"
#include "Component/ScrollingList.h"
#include "Component/Video.h"
#include "Animate/AnimationEvents.h"
#include "Animate/TweenTypes.h"
#include "../Sound/Sound.h"
@ -366,6 +367,33 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page)
}
for(xml_node<> *componentXml = layout->first_node("video"); componentXml; componentXml = componentXml->next_sibling("video"))
{
xml_attribute<> *srcXml = componentXml->first_attribute("src");
xml_attribute<> *numLoopsXml = componentXml->first_attribute("numLoops");
if (!srcXml)
{
Logger::write(Logger::ZONE_ERROR, "Layout", "Video component in layout does not specify a source video file");
}
else
{
std::string videoPath;
videoPath = Utils::combinePath(Configuration::convertToAbsolutePath(layoutPath, videoPath), std::string(srcXml->value()));
std::string layoutName;
config_.getProperty("layout", layoutName);
std::string altVideoPath;
altVideoPath = Utils::combinePath(Configuration::absolutePath, "layouts", layoutName, std::string(srcXml->value()));
int numLoops = numLoopsXml ? Utils::convertInt(numLoopsXml->value()) : 1;
Video *c = new Video(videoPath, altVideoPath, numLoops, *page, scaleX_, scaleY_);
buildViewInfo(componentXml, c->baseViewInfo);
loadTweens(c, componentXml);
page->addComponent(c);
}
}
for(xml_node<> *componentXml = layout->first_node("text"); componentXml; componentXml = componentXml->next_sibling("text"))
{
xml_attribute<> *value = componentXml->first_attribute("value");

View File

@ -238,9 +238,10 @@ void RetroFE::run()
int initializeStatus = 0;
// load the initial splash screen, unload it once it is complete
currentPage_ = loadSplashPage();
state = RETROFE_ENTER;
bool splashMode = true;
currentPage_ = loadSplashPage();
state = RETROFE_ENTER;
bool splashMode = true;
bool exitSplashMode = false;
Launcher l(*this, config_);
preloadTime = static_cast<float>(SDL_GetTicks()) / 1000;
@ -254,6 +255,7 @@ void RetroFE::run()
{
if(input_.update(e))
{
exitSplashMode = true;
attract_.reset();
}
}
@ -278,7 +280,7 @@ void RetroFE::run()
}
}
if((initialized || initializeError) && splashMode && currentPage_->getMinShowTime() <= (currentTime_ - preloadTime))
if((initialized || initializeError) && splashMode && (exitSplashMode || (currentPage_->getMinShowTime() <= (currentTime_ - preloadTime) && !(currentPage_->isPlaying()))))
{
SDL_WaitThread(initializeThread, &initializeStatus);
@ -516,7 +518,10 @@ void RetroFE::run()
if(currentPage_)
{
attract_.update(deltaTime, *currentPage_);
if (!splashMode)
{
attract_.update(deltaTime, *currentPage_);
}
currentPage_->update(deltaTime);
}

View File

@ -390,6 +390,10 @@ void GStreamerVideo::update(float /* dt */)
GST_SEEK_TYPE_NONE,
GST_CLOCK_TIME_NONE);
}
else
{
isPlaying_ = false;
}
}
gst_message_unref(msg);
@ -397,3 +401,8 @@ void GStreamerVideo::update(float /* dt */)
}
}
bool GStreamerVideo::isPlaying()
{
return isPlaying_;
}

View File

@ -40,6 +40,7 @@ public:
void freeElements();
int getHeight();
int getWidth();
bool isPlaying();
private:
static void processNewBuffer (GstElement *fakesink, GstBuffer *buf, GstPad *pad, gpointer data);