Commit 6bb6e5bd authored by OyyoDams's avatar OyyoDams

feat(video): add video snaps

parent 6a7edb3f
FROM ubuntu:16.04 FROM ubuntu:18.04
ARG RB_VERSION='' ARG RB_VERSION=''
RUN apt-get update && apt-get install -y libsdl2-dev libsdl2-mixer-dev libboost-all-dev libfreeimage-dev libfreetype6-dev libeigen3-dev libcurl4-openssl-dev libasound2-dev libgl1-mesa-dev build-essential cmake gettext RUN apt-get update && apt-get install -y libsdl2-dev libsdl2-mixer-dev libboost-all-dev libfreeimage-dev libfreetype6-dev libeigen3-dev libcurl4-openssl-dev libasound2-dev libgl1-mesa-dev build-essential cmake gettext libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavresample-dev libavutil-dev libswresample-dev libswscale-dev libpostproc-dev
WORKDIR /src WORKDIR /src
......
...@@ -11,7 +11,7 @@ const std::string MetadataDescriptor::DefaultValueEmpty = ""; ...@@ -11,7 +11,7 @@ const std::string MetadataDescriptor::DefaultValueEmpty = "";
const std::string MetadataDescriptor::DefaultValueRating = "0.0"; const std::string MetadataDescriptor::DefaultValueRating = "0.0";
const std::string MetadataDescriptor::DefaultValuePlayers = "1"; const std::string MetadataDescriptor::DefaultValuePlayers = "1";
const std::string MetadataDescriptor::DefaultValuePlaycount = "0"; const std::string MetadataDescriptor::DefaultValuePlaycount = "0";
const std::string MetadataDescriptor::DefaultValueUnknown = "unknown"; //const std::string MetadataDescriptor::DefaultValueUnknown = "unknown";
const std::string MetadataDescriptor::DefaultValueFavorite = "false"; const std::string MetadataDescriptor::DefaultValueFavorite = "false";
const std::string MetadataDescriptor::DefaultValueHidden = "false"; const std::string MetadataDescriptor::DefaultValueHidden = "false";
...@@ -44,6 +44,7 @@ const MetadataFieldDescriptor* MetadataDescriptor::GetMetadataFieldDescriptors(I ...@@ -44,6 +44,7 @@ const MetadataFieldDescriptor* MetadataDescriptor::GetMetadataFieldDescriptors(I
MetadataFieldDescriptor("desc" , DefaultValueEmpty , _("Description") , _("enter description") , (int)offsetof(MetadataDescriptor, _Description), MetadataFieldDescriptor::DataType::Text , &MetadataDescriptor::IsDefaultDescription , &MetadataDescriptor::DescriptionAsString , &MetadataDescriptor::SetDescription , false, false), MetadataFieldDescriptor("desc" , DefaultValueEmpty , _("Description") , _("enter description") , (int)offsetof(MetadataDescriptor, _Description), MetadataFieldDescriptor::DataType::Text , &MetadataDescriptor::IsDefaultDescription , &MetadataDescriptor::DescriptionAsString , &MetadataDescriptor::SetDescription , false, false),
MetadataFieldDescriptor("image" , DefaultValueEmpty , _("Image") , _("enter path to image") , (int)offsetof(MetadataDescriptor, _Image) , MetadataFieldDescriptor::DataType::Path , &MetadataDescriptor::IsDefaultImage , &MetadataDescriptor::ImageAsString , &MetadataDescriptor::SetImagePath , false, false), MetadataFieldDescriptor("image" , DefaultValueEmpty , _("Image") , _("enter path to image") , (int)offsetof(MetadataDescriptor, _Image) , MetadataFieldDescriptor::DataType::Path , &MetadataDescriptor::IsDefaultImage , &MetadataDescriptor::ImageAsString , &MetadataDescriptor::SetImagePath , false, false),
MetadataFieldDescriptor("thumbnail" , DefaultValueEmpty , _("Thumbnail") , _("enter path to thumbnail") , (int)offsetof(MetadataDescriptor, _Thumbnail) , MetadataFieldDescriptor::DataType::PPath , &MetadataDescriptor::IsDefaultThumbnail , &MetadataDescriptor::ThumbnailAsString , &MetadataDescriptor::SetThumbnailPath , false, false), MetadataFieldDescriptor("thumbnail" , DefaultValueEmpty , _("Thumbnail") , _("enter path to thumbnail") , (int)offsetof(MetadataDescriptor, _Thumbnail) , MetadataFieldDescriptor::DataType::PPath , &MetadataDescriptor::IsDefaultThumbnail , &MetadataDescriptor::ThumbnailAsString , &MetadataDescriptor::SetThumbnailPath , false, false),
MetadataFieldDescriptor("video" , DefaultValueEmpty , _("Video") , _("enter path to video") , (int)offsetof(MetadataDescriptor, _Video) , MetadataFieldDescriptor::DataType::PPath , &MetadataDescriptor::IsDefaultVideo , &MetadataDescriptor::VideoAsString , &MetadataDescriptor::SetVideoPath , false, false),
MetadataFieldDescriptor("releasedate", DefaultValueEmpty , _("Release date"), _("enter release date") , (int)offsetof(MetadataDescriptor, _ReleaseDate), MetadataFieldDescriptor::DataType::Date , &MetadataDescriptor::IsDefaultReleaseDateEpoc, &MetadataDescriptor::ReleaseDateAsString , &MetadataDescriptor::SetReleaseDateAsString , false, false), MetadataFieldDescriptor("releasedate", DefaultValueEmpty , _("Release date"), _("enter release date") , (int)offsetof(MetadataDescriptor, _ReleaseDate), MetadataFieldDescriptor::DataType::Date , &MetadataDescriptor::IsDefaultReleaseDateEpoc, &MetadataDescriptor::ReleaseDateAsString , &MetadataDescriptor::SetReleaseDateAsString , false, false),
MetadataFieldDescriptor("developer" , DefaultValueEmpty , _("Developer") , _("enter game developer") , (int)offsetof(MetadataDescriptor, _Developer) , MetadataFieldDescriptor::DataType::String , &MetadataDescriptor::IsDefaultDeveloper , &MetadataDescriptor::DeveloperAsString , &MetadataDescriptor::SetDeveloper , false, false), MetadataFieldDescriptor("developer" , DefaultValueEmpty , _("Developer") , _("enter game developer") , (int)offsetof(MetadataDescriptor, _Developer) , MetadataFieldDescriptor::DataType::String , &MetadataDescriptor::IsDefaultDeveloper , &MetadataDescriptor::DeveloperAsString , &MetadataDescriptor::SetDeveloper , false, false),
MetadataFieldDescriptor("publisher" , DefaultValueEmpty , _("Publisher") , _("enter game publisher") , (int)offsetof(MetadataDescriptor, _Publisher) , MetadataFieldDescriptor::DataType::String , &MetadataDescriptor::IsDefaultPublisher , &MetadataDescriptor::PublisherAsString , &MetadataDescriptor::SetPublisher , false, false), MetadataFieldDescriptor("publisher" , DefaultValueEmpty , _("Publisher") , _("enter game publisher") , (int)offsetof(MetadataDescriptor, _Publisher) , MetadataFieldDescriptor::DataType::String , &MetadataDescriptor::IsDefaultPublisher , &MetadataDescriptor::PublisherAsString , &MetadataDescriptor::SetPublisher , false, false),
......
...@@ -30,7 +30,7 @@ class MetadataDescriptor ...@@ -30,7 +30,7 @@ class MetadataDescriptor
static const std::string DefaultValueRating; static const std::string DefaultValueRating;
static const std::string DefaultValuePlayers; static const std::string DefaultValuePlayers;
static const std::string DefaultValuePlaycount; static const std::string DefaultValuePlaycount;
static const std::string DefaultValueUnknown; //static const std::string DefaultValueUnknown;
static const std::string DefaultValueFavorite; static const std::string DefaultValueFavorite;
static const std::string DefaultValueHidden; static const std::string DefaultValueHidden;
...@@ -50,6 +50,7 @@ class MetadataDescriptor ...@@ -50,6 +50,7 @@ class MetadataDescriptor
std::string* _Core; //!< Specific core std::string* _Core; //!< Specific core
std::string* _Ratio; //!< Specific screen ratio std::string* _Ratio; //!< Specific screen ratio
std::string* _Thumbnail; //!< Thumbnail path std::string* _Thumbnail; //!< Thumbnail path
std::string* _Video; //!< Video path
std::string* _Region; //!< Rom/Game Region std::string* _Region; //!< Rom/Game Region
float _Rating; //!< Rating from 0.0 to 1.0 float _Rating; //!< Rating from 0.0 to 1.0
int _Players; //!< Players range: LSW:from - MSW:to (allow sorting by max players) int _Players; //!< Players range: LSW:from - MSW:to (allow sorting by max players)
...@@ -198,6 +199,7 @@ class MetadataDescriptor ...@@ -198,6 +199,7 @@ class MetadataDescriptor
_Core(nullptr), _Core(nullptr),
_Ratio(nullptr), _Ratio(nullptr),
_Thumbnail(nullptr), _Thumbnail(nullptr),
_Video(nullptr),
_Region(nullptr), _Region(nullptr),
_Rating(0.0f), _Rating(0.0f),
_Players((1<<16)+1), _Players((1<<16)+1),
...@@ -232,6 +234,7 @@ class MetadataDescriptor ...@@ -232,6 +234,7 @@ class MetadataDescriptor
_Core (source._Core ), _Core (source._Core ),
_Ratio (source._Ratio ), _Ratio (source._Ratio ),
_Thumbnail (source._Thumbnail ), _Thumbnail (source._Thumbnail ),
_Video (source._Video ),
_Region (source._Region ), _Region (source._Region ),
_Rating (source._Rating ), _Rating (source._Rating ),
_Players (source._Players ), _Players (source._Players ),
...@@ -266,6 +269,7 @@ class MetadataDescriptor ...@@ -266,6 +269,7 @@ class MetadataDescriptor
_Core ( source._Core ), _Core ( source._Core ),
_Ratio ( source._Ratio ), _Ratio ( source._Ratio ),
_Thumbnail ( source._Thumbnail ), _Thumbnail ( source._Thumbnail ),
_Video ( source._Video ),
_Region ( source._Region ), _Region ( source._Region ),
_Rating ( source._Rating ), _Rating ( source._Rating ),
_Players ( source._Players ), _Players ( source._Players ),
...@@ -314,6 +318,7 @@ class MetadataDescriptor ...@@ -314,6 +318,7 @@ class MetadataDescriptor
if (source._Core != nullptr) _Core = new std::string(*source._Core ); if (source._Core != nullptr) _Core = new std::string(*source._Core );
if (source._Ratio != nullptr) _Ratio = new std::string(*source._Ratio ); if (source._Ratio != nullptr) _Ratio = new std::string(*source._Ratio );
if (source._Thumbnail != nullptr) _Thumbnail = new std::string(*source._Thumbnail); if (source._Thumbnail != nullptr) _Thumbnail = new std::string(*source._Thumbnail);
if (source._Video != nullptr) _Video = new std::string(*source._Video );
if (source._Region != nullptr) _Region = new std::string(*source._Region ); if (source._Region != nullptr) _Region = new std::string(*source._Region );
_Rating = source._Rating ; _Rating = source._Rating ;
_Players = source._Players ; _Players = source._Players ;
...@@ -353,6 +358,7 @@ class MetadataDescriptor ...@@ -353,6 +358,7 @@ class MetadataDescriptor
_Description = std::move(source._Description); _Description = std::move(source._Description);
_Image = std::move(source._Image ); _Image = std::move(source._Image );
_Thumbnail = source._Thumbnail ; source._Thumbnail = nullptr; _Thumbnail = source._Thumbnail ; source._Thumbnail = nullptr;
_Video = source._Video ; source._Video = nullptr;
_Developer = std::move(source._Developer ); _Developer = std::move(source._Developer );
_Publisher = std::move(source._Publisher ); _Publisher = std::move(source._Publisher );
_Genre = std::move(source._Genre ); _Genre = std::move(source._Genre );
...@@ -412,6 +418,7 @@ class MetadataDescriptor ...@@ -412,6 +418,7 @@ class MetadataDescriptor
const std::string& Description() const { return _Description; } const std::string& Description() const { return _Description; }
const std::string& Image() const { return _Image; } const std::string& Image() const { return _Image; }
const std::string& Thumbnail() const { return ReadPString(_Thumbnail, DefaultValueEmpty); } const std::string& Thumbnail() const { return ReadPString(_Thumbnail, DefaultValueEmpty); }
const std::string& Video() const { return ReadPString(_Video, DefaultValueEmpty); }
const std::string& Developer() const { return _Developer; } const std::string& Developer() const { return _Developer; }
const std::string& Publisher() const { return _Publisher; } const std::string& Publisher() const { return _Publisher; }
const std::string& Genre() const { return _Genre; } const std::string& Genre() const { return _Genre; }
...@@ -441,6 +448,7 @@ class MetadataDescriptor ...@@ -441,6 +448,7 @@ class MetadataDescriptor
std::string DescriptionAsString() const { return _Description; } std::string DescriptionAsString() const { return _Description; }
std::string ImageAsString() const { return _Image; } std::string ImageAsString() const { return _Image; }
std::string ThumbnailAsString() const { return ReadPString(_Thumbnail, DefaultValueEmpty); } std::string ThumbnailAsString() const { return ReadPString(_Thumbnail, DefaultValueEmpty); }
std::string VideoAsString() const { return ReadPString(_Video, DefaultValueEmpty); }
std::string DeveloperAsString() const { return _Developer; } std::string DeveloperAsString() const { return _Developer; }
std::string PublisherAsString() const { return _Publisher; } std::string PublisherAsString() const { return _Publisher; }
std::string GenreAsString() const { return _Genre; } std::string GenreAsString() const { return _Genre; }
...@@ -466,6 +474,7 @@ class MetadataDescriptor ...@@ -466,6 +474,7 @@ class MetadataDescriptor
void SetDescription(const std::string& description) { _Description = description; _Dirty = true; } void SetDescription(const std::string& description) { _Description = description; _Dirty = true; }
void SetImagePath(const std::string& image) { _Image = image; _Dirty = true; } void SetImagePath(const std::string& image) { _Image = image; _Dirty = true; }
void SetThumbnailPath(const std::string& thumbnail) { AssignPString(_Thumbnail, thumbnail); _Dirty = true; } void SetThumbnailPath(const std::string& thumbnail) { AssignPString(_Thumbnail, thumbnail); _Dirty = true; }
void SetVideoPath(const std::string& video) { AssignPString(_Video, video); _Dirty = true; }
void SetReleaseDate(const DateTime& releasedate) { _ReleaseDate = (int)releasedate.ToEpochTime(); _Dirty = true; } void SetReleaseDate(const DateTime& releasedate) { _ReleaseDate = (int)releasedate.ToEpochTime(); _Dirty = true; }
void SetDeveloper(const std::string& developer) { _Developer = developer; _Dirty = true; } void SetDeveloper(const std::string& developer) { _Developer = developer; _Dirty = true; }
void SetPublisher(const std::string& publisher) { _Publisher = publisher; _Dirty = true; } void SetPublisher(const std::string& publisher) { _Publisher = publisher; _Dirty = true; }
...@@ -518,6 +527,7 @@ class MetadataDescriptor ...@@ -518,6 +527,7 @@ class MetadataDescriptor
bool IsDefaultDescription() const { return _Default._Description == _Description; } bool IsDefaultDescription() const { return _Default._Description == _Description; }
bool IsDefaultImage() const { return _Default._Image == _Image; } bool IsDefaultImage() const { return _Default._Image == _Image; }
bool IsDefaultThumbnail() const { return _Default.Thumbnail() == Thumbnail(); } bool IsDefaultThumbnail() const { return _Default.Thumbnail() == Thumbnail(); }
bool IsDefaultVideo() const { return _Default.Video() == Video(); }
bool IsDefaultDeveloper() const { return _Default._Developer == _Developer; } bool IsDefaultDeveloper() const { return _Default._Developer == _Developer; }
bool IsDefaultPublisher() const { return _Default._Publisher == _Publisher; } bool IsDefaultPublisher() const { return _Default._Publisher == _Publisher; }
bool IsDefaultGenre() const { return _Default._Genre == _Genre; } bool IsDefaultGenre() const { return _Default._Genre == _Genre; }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <RecalboxConf.h> #include <RecalboxConf.h>
#include <RootFolders.h> #include <RootFolders.h>
#include <recalbox/RecalboxSystem.h> #include <recalbox/RecalboxSystem.h>
#include <VideoEngine.h>
std::vector<SystemData *> SystemData::sSystemVector; std::vector<SystemData *> SystemData::sSystemVector;
...@@ -164,6 +165,7 @@ void SystemData::launchGame(Window* window, FileData* game, const std::string& n ...@@ -164,6 +165,7 @@ void SystemData::launchGame(Window* window, FileData* game, const std::string& n
LOG(LogInfo) << "Attempting to launch game..."; LOG(LogInfo) << "Attempting to launch game...";
VideoEngine::This().StopVideo();
AudioManager::getInstance()->deinit(); AudioManager::getInstance()->deinit();
VolumeControl::getInstance()->deinit(); VolumeControl::getInstance()->deinit();
...@@ -239,6 +241,7 @@ std::string SystemData::demoInitialize(Window& window) ...@@ -239,6 +241,7 @@ std::string SystemData::demoInitialize(Window& window)
std::string controlersConfig = InputManager::getInstance()->configureEmulators(); std::string controlersConfig = InputManager::getInstance()->configureEmulators();
LOG(LogInfo) << "Controllers config : " << controlersConfig; LOG(LogInfo) << "Controllers config : " << controlersConfig;
VideoEngine::This().StopVideo();
AudioManager::getInstance()->deinit(); AudioManager::getInstance()->deinit();
VolumeControl::getInstance()->deinit(); VolumeControl::getInstance()->deinit();
...@@ -343,7 +346,10 @@ SystemData *createSystem(const SystemData::Tree &system) ...@@ -343,7 +346,10 @@ SystemData *createSystem(const SystemData::Tree &system)
name = system.get("name", ""); name = system.get("name", "");
fullname = system.get("fullname", ""); fullname = system.get("fullname", "");
path = system.get("path", ""); path = system.get("path", "");
//#ifdef DEBUG
//strFindAndReplace(path, "roms", "romstest"); //strFindAndReplace(path, "roms", "romstest");
//#endif
// convert extensions list from a string into a vector of strings // convert extensions list from a string into a vector of strings
std::string extensions = system.get("extension", ""); std::string extensions = system.get("extension", "");
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <RootFolders.h> #include <RootFolders.h>
#include <VideoEngine.h>
#include "AudioManager.h" #include "AudioManager.h"
#include "CommandThread.h" #include "CommandThread.h"
...@@ -400,6 +401,9 @@ int main(int argc, char* argv[]) ...@@ -400,6 +401,9 @@ int main(int argc, char* argv[])
// Start the socket server // Start the socket server
CommandThread commandThread(&window); CommandThread commandThread(&window);
// Starts Video engine
VideoEngine::This().StartEngine();
// Allocate custom event types // Allocate custom event types
unsigned int NetPlayPopupEvent = SDL_RegisterEvents(2); unsigned int NetPlayPopupEvent = SDL_RegisterEvents(2);
unsigned int MusicStartEvent = NetPlayPopupEvent + 1; unsigned int MusicStartEvent = NetPlayPopupEvent + 1;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <fstream> #include <fstream>
#include <Locale.h> #include <Locale.h>
#include <VideoEngine.h>
RecalboxSystem::RecalboxSystem() { RecalboxSystem::RecalboxSystem() {
...@@ -53,6 +54,7 @@ void RecalboxSystem::NotifySystemAndGame(const SystemData* system, const FileDat ...@@ -53,6 +54,7 @@ void RecalboxSystem::NotifySystemAndGame(const SystemData* system, const FileDat
fwrite(output.c_str(), output.size(), 1, f); fwrite(output.c_str(), output.size(), 1, f);
fclose(f); fclose(f);
} }
VideoEngine::This().StopVideo();
} }
......
...@@ -42,7 +42,7 @@ DetailedGameListView::DetailedGameListView(Window* window, FolderData* root, Sys ...@@ -42,7 +42,7 @@ DetailedGameListView::DetailedGameListView(Window* window, FolderData* root, Sys
// folder components // folder components
for (int y = 0; y < 3; y++) { for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) { for (int x = 0; x < 3; x++) {
ImageComponent *img = new ImageComponent(window); auto *img = new ImageComponent(window);
addChild(img); // normalised functions required to be added first addChild(img); // normalised functions required to be added first
img->setOrigin(0.5f, 0.5f); img->setOrigin(0.5f, 0.5f);
img->setNormalisedMaxSize(0.4f, 0.4f); img->setNormalisedMaxSize(0.4f, 0.4f);
...@@ -370,6 +370,8 @@ void DetailedGameListView::setGameInfo(FileData* file) ...@@ -370,6 +370,8 @@ void DetailedGameListView::setGameInfo(FileData* file)
mFavorite.setValue(file->Metadata().FavoriteAsString()); mFavorite.setValue(file->Metadata().FavoriteAsString());
mImage.setImage(file->Metadata().Image()); mImage.setImage(file->Metadata().Image());
mImage.setVideo(file->Metadata().Video());
mImage.ResetAnimations();
mDescription.setText(file->Metadata().Description()); mDescription.setText(file->Metadata().Description());
mDescContainer.reset(); mDescContainer.reset();
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "components/ScrollableContainer.h" #include "components/ScrollableContainer.h"
#include "components/RatingComponent.h" #include "components/RatingComponent.h"
#include "components/DateTimeComponent.h" #include "components/DateTimeComponent.h"
#include "components/ImageVideoComponent.h"
#include "SystemData.h" #include "SystemData.h"
class DetailedGameListView : public BasicGameListView class DetailedGameListView : public BasicGameListView
...@@ -24,7 +25,7 @@ private: ...@@ -24,7 +25,7 @@ private:
void initMDLabels(); void initMDLabels();
void initMDValues(); void initMDValues();
ImageComponent mImage; ImageVideoComponent mImage;
std::vector<ImageComponent *> mFolderContent; std::vector<ImageComponent *> mFolderContent;
TextComponent mLblRating, mLblReleaseDate, mLblDeveloper, mLblPublisher, mLblGenre, mLblPlayers, mLblLastPlayed, mLblPlayCount, mLblFavorite; TextComponent mLblRating, mLblReleaseDate, mLblDeveloper, mLblPublisher, mLblGenre, mLblPlayers, mLblLastPlayed, mLblPlayCount, mLblFavorite;
......
...@@ -22,8 +22,14 @@ set(CORE_HEADERS ...@@ -22,8 +22,14 @@ set(CORE_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/RootFolders.h ${CMAKE_CURRENT_SOURCE_DIR}/src/RootFolders.h
${CMAKE_CURRENT_SOURCE_DIR}/src/MenuThemeData.h ${CMAKE_CURRENT_SOURCE_DIR}/src/MenuThemeData.h
${CMAKE_CURRENT_SOURCE_DIR}/src/Util.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Util.h
${CMAKE_CURRENT_SOURCE_DIR}/src/VideoEngine.h
${CMAKE_CURRENT_SOURCE_DIR}/src/Window.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Window.h
# Utils
${CMAKE_CURRENT_SOURCE_DIR}/src/util/Thread.h
${CMAKE_CURRENT_SOURCE_DIR}/src/util/Mutex.h
${CMAKE_CURRENT_SOURCE_DIR}/src/util/HighResolutionTimer.h
# Animations # Animations
${CMAKE_CURRENT_SOURCE_DIR}/src/animations/Animation.h ${CMAKE_CURRENT_SOURCE_DIR}/src/animations/Animation.h
${CMAKE_CURRENT_SOURCE_DIR}/src/animations/AnimationController.h ${CMAKE_CURRENT_SOURCE_DIR}/src/animations/AnimationController.h
...@@ -39,6 +45,7 @@ set(CORE_HEADERS ...@@ -39,6 +45,7 @@ set(CORE_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/components/HelpComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/HelpComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/IList.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/IList.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageVideoComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageGridComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageGridComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/MenuComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/MenuComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.h
...@@ -95,8 +102,13 @@ set(CORE_SOURCES ...@@ -95,8 +102,13 @@ set(CORE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/RootFolders.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RootFolders.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/MenuThemeData.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/MenuThemeData.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Util.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Util.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/VideoEngine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Window.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Window.cpp
# Utils
${CMAKE_CURRENT_SOURCE_DIR}/src/util/Thread.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/util/Mutex.cpp
# Animations # Animations
${CMAKE_CURRENT_SOURCE_DIR}/src/animations/AnimationController.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/animations/AnimationController.cpp
...@@ -109,6 +121,7 @@ set(CORE_SOURCES ...@@ -109,6 +121,7 @@ set(CORE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/components/DateTimeComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/DateTimeComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/HelpComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/HelpComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageVideoComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/MenuComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/MenuComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ScrollableContainer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/ScrollableContainer.cpp
...@@ -195,6 +208,9 @@ set(EMBEDDED_ASSET_SOURCES ...@@ -195,6 +208,9 @@ set(EMBEDDED_ASSET_SOURCES
list(APPEND CORE_SOURCES ${EMBEDDED_ASSET_SOURCES}) list(APPEND CORE_SOURCES ${EMBEDDED_ASSET_SOURCES})
set(FFMPEGLIBS avcodec avformat swresample avutil swscale avdevice)
include_directories(${COMMON_INCLUDE_DIRS}) include_directories(${COMMON_INCLUDE_DIRS})
add_library(es-core STATIC ${CORE_SOURCES} ${CORE_HEADERS} src/RecalboxConf.cpp src/RecalboxConf.h) add_library(es-core STATIC ${CORE_SOURCES} ${CORE_HEADERS} src/RecalboxConf.cpp src/RecalboxConf.h)
target_link_libraries(es-core ${COMMON_LIBRARIES}) target_link_libraries(es-core ${COMMON_LIBRARIES} ${FFMPEGLIBS})
This diff is collapsed.
//
// Created by bkg2k on 14/05/19.
//
#pragma once
#include <string>
#include <util/Thread.h>
#include <util/Mutex.h>
#include <SDL_system.h>
#include <resources/TextureData.h>
extern "C"
{
#include <libavfilter/avfilter.h> // libavfilter-dev
#include <libavformat/avformat.h> // libavformat-dev
#include <libavcodec/avcodec.h> // libavformat-dev
#include <libavdevice/avdevice.h> // libavdevice-dev
#include <libavutil/imgutils.h> // libavutil-dev
#include <libswresample/swresample.h> // libavformat-dev
#include <libswscale/swscale.h> // libavfilter-dev
}
class VideoEngine : Thread
{
public:
/*!
* @brief Curren tplayer state
*/
enum class PlayerState
{
Idle, // Do nothing, sleep
StartPending, // Initializing the video
Playing, // Currently playing
Paused, // Pause flag
StopPending, // Currently playing but must stop asap and return idle
};
private:
/*!
* @brief Small packet queue
*/
class AudioPacketQueue
{
private:
Mutex mMutex;
//! First paquet
AVPacketList* First;
//! Last paquet
AVPacketList* Last;
//! Packet count
int Count;
//! Packet size
int Size;
public:
/*!
* @brief Constructor
*/
AudioPacketQueue()
{
First = Last = nullptr;
Count = Size = 0;
}
void Reset()
{
AVPacket packet;
while(Dequeue(packet));
First = Last = nullptr;
Count = Size = 0;
}
/*!
* @brief Enqueue a new packet
* @param packet packet to enqueue
*/
void Enqueue(const AVPacket* packet);
/*!
* @brief Dequeue a packet or return nullptr of the queue is empty.
* This call is non blocking
* @param packet packet to dequeue
* @return True if the packet is valid
*/
bool Dequeue(AVPacket& pkt);
};
/*!
* @brief Internal context, all embedded in a POD object
*/
class PlayerContext
{
public:
//! Global audio/video context
AVFormatContext* AudioVideoContext;
//! Index of the first audio stream available in the file
int AudioStreamIndex;
//! Index of the first video stream available in the file
int VideoStreamIndex;
//! Audio codec
AVCodec* AudioCodec;
//! Video codec
AVCodec* VideoCodec;
//! Audio codec context
AVCodecContext* AudioCodecContext;
//! Video codec context
AVCodecContext* VideoCodecContext;
//! Rescaler context
SwrContext* ResamplerContext;
//! Color Space context
SwsContext* ColorsSpaceContext;
//! Audio packets
AudioPacketQueue AudioQueue;
//! Frame buffer
unsigned char* FrameBuffer;
//! Source video Frame in native pixel format
AVFrame* Frame;
//! Video Frame transcode to RGB
AVFrame* FrameRGB[2];
//! RGB frame access locker
Mutex FrammeRGBLocker[2];
//! Buffer in use by the decoder (0/1)
unsigned int FrameInUse;
//! Video width in pixel
int Width;
//!Video height in pixel
int Height;
//! Frame time in Nano-seconds
long long FrameTime;
//! Video duration in milliseconds
int TotalTime;
PlayerContext()
{
Reset();
}
void Reset()
{
AudioVideoContext = nullptr;
AudioCodec = VideoCodec = nullptr;
AudioCodecContext = VideoCodecContext = nullptr;
ResamplerContext = nullptr;
ColorsSpaceContext = nullptr;
AudioStreamIndex = VideoStreamIndex = -1;
FrameBuffer = nullptr;
Frame = FrameRGB[0] = FrameRGB[1] = nullptr;
Width = Height = 0;
FrameInUse = 0;
FrameTime = 0;
AudioQueue.Reset();
}
};
private:
//! Signal used to unlock the thread and actually run the video decoding
Mutex mSignal;
//! Video filename
std::string mFileName;
//! Video playing state
volatile PlayerState mState;
//! Global context
PlayerContext mContext;
//! Textures to render
TextureData mTexture;
static constexpr int SDL_AUDIO_BUFFER_SIZE = 4096;
private:
/*!
* Thread main loop
*/
void Run() override;
/*!
* @brief Unlock the thread on exit
*/
void Break() override
{
mSignal.Signal();
}
static void AudioCallback(void *userdata, unsigned char* stream, int len)
{
((VideoEngine*)userdata)->DecodeAudioFrameOnDemand(stream, len);
}
bool InitializeDecoder();
void DecodeAudioFrameOnDemand(unsigned char * stream, int len);
int DecodeAudioFrame(AVCodecContext& audioContext, unsigned char* buffer, int size);
void DecodeFrames();
void FinalizeDecoder();
/*!
* @brief Default constructor
*/
VideoEngine();
public:
/*!
* @brief Destructor
*/
~VideoEngine() override { Thread::Stop(); }
/*!
* @brief Start playing a video file
* If a video is already playing, a call to stop is performed playing the new video
* @param videopath Path to the video file ot play
*/
void PlayVideo(const std::string& videopath);
/*!
* @brief Stop the currently playing video file.
* Does nothing if no file is actually playing
*/
void StopVideo(bool waitforstop = false);
/*!
* @brief Get current image of the current playing video
* This must be called fr
* @return TextureData containing last image
*/
TextureData& GetDisplayableFrame();
/*!
* @brief Get Instance
* @return Instance
*/
static VideoEngine& This();
/*!
* @brief Return true if the player is actually playing a video
* @return True if a video is playing, false otherwise
*/
bool IsPlaying() { return ((mState == PlayerState::Playing) || (mState == PlayerState::StopPending)); }
/*!
* @brief Return true if the engine is in idle state
* @return True if in idle state, false otherwise
*/
bool IsIdle() { return (mState == PlayerState::Idle); }
int GetVideoDurationMs() { return IsPlaying() ? mContext.TotalTime : 0; }
/*!
* @brief Start the video engine. After calling this method, the player is ready to play video
*/
void StartEngine() { Thread::Start("VideoEngine"); }
/*!
* Pause the engine if it's actually playing a video. Otherwise do nothing.
*/
void PauseEngine() { if (mState == PlayerState::Playing) mState = PlayerState::Paused; }
/*!
* Resume the engine if it's actually paused. Otherwise do nothing.
*/
void ResumeEngine() { if (mState == PlayerState::Paused) mState = PlayerState::Playing; }
};
This diff is collapsed.
//
// Created by bkg2k on 16/05/19.
//
#pragma once