mirror of
https://github.com/FunKey-Project/RetroFE.git
synced 2026-01-20 14:54:46 +01:00
Video instance is now a singleton. Allocate new buffer when a video of largest size being played. Keeping pipeline open when changing videos.
This commit is contained in:
parent
76032584ac
commit
4dd2c97fd6
@ -41,7 +41,6 @@ RetroFE::RetroFE(CollectionDatabase &db, Configuration &c)
|
|||||||
, Input(Config)
|
, Input(Config)
|
||||||
, KeyInputDisable(0)
|
, KeyInputDisable(0)
|
||||||
, CurrentTime(0)
|
, CurrentTime(0)
|
||||||
, VideoInst(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,8 +82,6 @@ bool RetroFE::Initialize()
|
|||||||
|
|
||||||
VideoFactory::SetEnabled(videoEnable);
|
VideoFactory::SetEnabled(videoEnable);
|
||||||
VideoFactory::SetNumLoops(videoLoop);
|
VideoFactory::SetNumLoops(videoLoop);
|
||||||
VideoFactory vf;
|
|
||||||
VideoInst = vf.CreateVideo();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -153,12 +150,6 @@ bool RetroFE::DeInitialize()
|
|||||||
PageChain.pop_back();
|
PageChain.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VideoInst)
|
|
||||||
{
|
|
||||||
delete VideoInst;
|
|
||||||
VideoInst = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo: handle video deallocation
|
//todo: handle video deallocation
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,6 @@ private:
|
|||||||
float CurrentTime;
|
float CurrentTime;
|
||||||
Item *NextPageItem;
|
Item *NextPageItem;
|
||||||
FontCache FC;
|
FontCache FC;
|
||||||
IVideo *VideoInst;
|
|
||||||
AttractMode Attract;
|
AttractMode Attract;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -49,6 +49,7 @@ GStreamerVideo::GStreamerVideo()
|
|||||||
, Height(0)
|
, Height(0)
|
||||||
, Width(0)
|
, Width(0)
|
||||||
, VideoBuffer(NULL)
|
, VideoBuffer(NULL)
|
||||||
|
, VideoBufferSize(0)
|
||||||
, FrameReady(false)
|
, FrameReady(false)
|
||||||
, IsPlaying(false)
|
, IsPlaying(false)
|
||||||
, PlayCount(0)
|
, PlayCount(0)
|
||||||
@ -58,6 +59,15 @@ GStreamerVideo::GStreamerVideo()
|
|||||||
GStreamerVideo::~GStreamerVideo()
|
GStreamerVideo::~GStreamerVideo()
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
|
if(VideoBuffer)
|
||||||
|
{
|
||||||
|
delete[] VideoBuffer;
|
||||||
|
VideoBuffer = NULL;
|
||||||
|
VideoBufferSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GStreamerVideo::SetNumLoops(int n)
|
void GStreamerVideo::SetNumLoops(int n)
|
||||||
@ -89,10 +99,18 @@ void GStreamerVideo::ProcessNewBuffer (GstElement *fakesink, GstBuffer *buf, Gst
|
|||||||
|
|
||||||
if(video->Height && video->Width)
|
if(video->Height && video->Width)
|
||||||
{
|
{
|
||||||
if(!video->VideoBuffer)
|
// keep the largest video buffer allocated to avoid the penalty of reallocating and deallocating
|
||||||
|
if(!video->VideoBuffer || video->VideoBufferSize < map.size)
|
||||||
{
|
{
|
||||||
|
if(video->VideoBuffer)
|
||||||
|
{
|
||||||
|
delete[] video->VideoBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
video->VideoBuffer = new char[map.size];
|
video->VideoBuffer = new char[map.size];
|
||||||
|
video->VideoBufferSize = map.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(video->VideoBuffer, map.data, map.size);
|
memcpy(video->VideoBuffer, map.data, map.size);
|
||||||
gst_buffer_unmap(buf, &map);
|
gst_buffer_unmap(buf, &map);
|
||||||
video->FrameReady = true;
|
video->FrameReady = true;
|
||||||
@ -108,8 +126,11 @@ bool GStreamerVideo::Initialize()
|
|||||||
|
|
||||||
std::string path = Configuration::GetAbsolutePath() + "/Core";
|
std::string path = Configuration::GetAbsolutePath() + "/Core";
|
||||||
gst_init(NULL, NULL);
|
gst_init(NULL, NULL);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
GstRegistry *registry = gst_registry_get();
|
GstRegistry *registry = gst_registry_get();
|
||||||
gst_registry_scan_path(registry, path.c_str());
|
gst_registry_scan_path(registry, path.c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
|
|
||||||
@ -141,7 +162,7 @@ bool GStreamerVideo::Stop()
|
|||||||
(void)gst_element_set_state(Playbin, GST_STATE_NULL);
|
(void)gst_element_set_state(Playbin, GST_STATE_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeElements();
|
// FreeElements();
|
||||||
|
|
||||||
IsPlaying = false;
|
IsPlaying = false;
|
||||||
|
|
||||||
@ -155,11 +176,6 @@ bool GStreamerVideo::Stop()
|
|||||||
Width = 0;
|
Width = 0;
|
||||||
FrameReady = false;
|
FrameReady = false;
|
||||||
|
|
||||||
if(VideoBuffer)
|
|
||||||
{
|
|
||||||
delete VideoBuffer;
|
|
||||||
VideoBuffer = NULL;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,67 +200,67 @@ bool GStreamerVideo::Play(std::string file)
|
|||||||
Configuration::ConvertToAbsolutePath(Configuration::GetAbsolutePath(), file);
|
Configuration::ConvertToAbsolutePath(Configuration::GetAbsolutePath(), file);
|
||||||
file = uriFile;
|
file = uriFile;
|
||||||
|
|
||||||
// Pipeline = gst_pipeline_new("pipeline");
|
|
||||||
Playbin = gst_element_factory_make("playbin", "player");
|
|
||||||
VideoBin = gst_bin_new("SinkBin");
|
|
||||||
VideoSink = gst_element_factory_make("fakesink", "video_sink");
|
|
||||||
VideoConvert = gst_element_factory_make("capsfilter", "video_convert");
|
|
||||||
VideoConvertCaps = gst_caps_from_string("video/x-raw,format=(string)YUY2");
|
|
||||||
Height = 0;
|
|
||||||
Width = 0;
|
|
||||||
if(!Playbin)
|
if(!Playbin)
|
||||||
{
|
{
|
||||||
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not create playbin");
|
Playbin = gst_element_factory_make("playbin", "player");
|
||||||
FreeElements();
|
VideoBin = gst_bin_new("SinkBin");
|
||||||
return false;
|
VideoSink = gst_element_factory_make("fakesink", "video_sink");
|
||||||
}
|
VideoConvert = gst_element_factory_make("capsfilter", "video_convert");
|
||||||
if(!VideoSink)
|
VideoConvertCaps = gst_caps_from_string("video/x-raw,format=(string)YUY2");
|
||||||
{
|
Height = 0;
|
||||||
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not create video sink");
|
Width = 0;
|
||||||
FreeElements();
|
if(!Playbin)
|
||||||
return false;
|
{
|
||||||
}
|
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not create playbin");
|
||||||
if(!VideoConvert)
|
FreeElements();
|
||||||
{
|
return false;
|
||||||
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not create video converter");
|
}
|
||||||
FreeElements();
|
if(!VideoSink)
|
||||||
return false;
|
{
|
||||||
}
|
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not create video sink");
|
||||||
if(!VideoConvertCaps)
|
FreeElements();
|
||||||
{
|
return false;
|
||||||
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not create video caps");
|
}
|
||||||
FreeElements();
|
if(!VideoConvert)
|
||||||
return false;
|
{
|
||||||
}
|
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not create video converter");
|
||||||
|
FreeElements();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!VideoConvertCaps)
|
||||||
|
{
|
||||||
|
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not create video caps");
|
||||||
|
FreeElements();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
gst_bin_add_many(GST_BIN(VideoBin), VideoConvert, VideoSink, NULL);
|
gst_bin_add_many(GST_BIN(VideoBin), VideoConvert, VideoSink, NULL);
|
||||||
gst_element_link_filtered(VideoConvert, VideoSink, VideoConvertCaps);
|
gst_element_link_filtered(VideoConvert, VideoSink, VideoConvertCaps);
|
||||||
GstPad *videoConvertSinkPad = gst_element_get_static_pad(VideoConvert, "sink");
|
GstPad *videoConvertSinkPad = gst_element_get_static_pad(VideoConvert, "sink");
|
||||||
|
|
||||||
if(!videoConvertSinkPad)
|
if(!videoConvertSinkPad)
|
||||||
{
|
{
|
||||||
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not get video convert sink pad");
|
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not get video convert sink pad");
|
||||||
FreeElements();
|
FreeElements();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_object_set(G_OBJECT(VideoSink), "sync", TRUE, "qos", FALSE, NULL);
|
||||||
|
|
||||||
g_object_set(G_OBJECT(VideoSink), "sync", TRUE, "qos", FALSE, NULL);
|
GstPad *videoSinkPad = gst_ghost_pad_new("sink", videoConvertSinkPad);
|
||||||
|
if(!videoSinkPad)
|
||||||
|
{
|
||||||
|
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not get video bin sink pad");
|
||||||
|
FreeElements();
|
||||||
|
gst_object_unref(videoConvertSinkPad);
|
||||||
|
videoConvertSinkPad = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GstPad *videoSinkPad = gst_ghost_pad_new("sink", videoConvertSinkPad);
|
gst_element_add_pad(VideoBin, videoSinkPad);
|
||||||
if(!videoSinkPad)
|
|
||||||
{
|
|
||||||
Logger::Write(Logger::ZONE_DEBUG, "Video", "Could not get video bin sink pad");
|
|
||||||
FreeElements();
|
|
||||||
gst_object_unref(videoConvertSinkPad);
|
gst_object_unref(videoConvertSinkPad);
|
||||||
videoConvertSinkPad = NULL;
|
videoConvertSinkPad = NULL;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_element_add_pad(VideoBin, videoSinkPad);
|
|
||||||
gst_object_unref(videoConvertSinkPad);
|
|
||||||
videoConvertSinkPad = NULL;
|
|
||||||
|
|
||||||
g_object_set(G_OBJECT(Playbin), "uri", file.c_str(), "video-sink", VideoBin, NULL);
|
g_object_set(G_OBJECT(Playbin), "uri", file.c_str(), "video-sink", VideoBin, NULL);
|
||||||
|
|
||||||
IsPlaying = true;
|
IsPlaying = true;
|
||||||
@ -337,8 +353,6 @@ void GStreamerVideo::Update(float dt)
|
|||||||
{
|
{
|
||||||
if(GST_MESSAGE_TYPE(msg) == GST_MESSAGE_EOS)
|
if(GST_MESSAGE_TYPE(msg) == GST_MESSAGE_EOS)
|
||||||
{
|
{
|
||||||
Logger::Write(Logger::ZONE_ERROR, "Video", "EOS!");
|
|
||||||
|
|
||||||
PlayCount++;
|
PlayCount++;
|
||||||
|
|
||||||
//todo: nesting hazard
|
//todo: nesting hazard
|
||||||
|
|||||||
@ -41,6 +41,7 @@ private:
|
|||||||
gint Height;
|
gint Height;
|
||||||
gint Width;
|
gint Width;
|
||||||
char *VideoBuffer;
|
char *VideoBuffer;
|
||||||
|
gsize VideoBufferSize;
|
||||||
bool FrameReady;
|
bool FrameReady;
|
||||||
bool IsPlaying;
|
bool IsPlaying;
|
||||||
static bool Initialized;
|
static bool Initialized;
|
||||||
|
|||||||
@ -20,19 +20,19 @@
|
|||||||
|
|
||||||
bool VideoFactory::Enabled = true;
|
bool VideoFactory::Enabled = true;
|
||||||
int VideoFactory::NumLoops = 0;
|
int VideoFactory::NumLoops = 0;
|
||||||
|
IVideo *VideoFactory::Instance = NULL;
|
||||||
|
|
||||||
IVideo *VideoFactory::CreateVideo()
|
IVideo *VideoFactory::CreateVideo()
|
||||||
{
|
{
|
||||||
IVideo *instance = NULL;
|
|
||||||
|
|
||||||
if(Enabled)
|
if(Enabled)
|
||||||
{
|
{
|
||||||
instance = new GStreamerVideo();
|
Instance = new GStreamerVideo();
|
||||||
instance->Initialize();
|
Instance->Initialize();
|
||||||
((GStreamerVideo *)(instance))->SetNumLoops(NumLoops);
|
((GStreamerVideo *)(Instance))->SetNumLoops(NumLoops);
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance;
|
return Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoFactory::SetEnabled(bool enabled)
|
void VideoFactory::SetEnabled(bool enabled)
|
||||||
|
|||||||
@ -15,4 +15,5 @@ public:
|
|||||||
private:
|
private:
|
||||||
static bool Enabled;
|
static bool Enabled;
|
||||||
static int NumLoops;
|
static int NumLoops;
|
||||||
|
static IVideo *Instance;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user