WiiFlow_Lite/source/gui/WiiMovie.cpp
fix94.1 bbf0091922 -plugin videos now need to be in subfolders if you have "coverFolder" for the ini set
-plugins now also play videos which have the magic number as name if no specific video was found
-switched from libjpeg to the turbojpeg wrapper from libjpeg-turbo to simplify the whole jpeg decoding code by alot
-heavly optimized the video decoding code
2014-03-22 21:32:40 +00:00

175 lines
3.9 KiB
C++

/***************************************************************************
* Copyright (C) 2010 by Dimok
* (C) 2014 by FIX94
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* WiiMovie.cpp
*
* for WiiXplorer 2010
***************************************************************************/
#include <unistd.h>
#include "memory/mem2.hpp"
#include "WiiMovie.hpp"
#include "gecko/gecko.hpp"
WiiMovie movie;
void WiiMovie::Init(const char *filepath)
{
Frame = NULL;
BufferPos = 0;
Buffer[0].thread = false;
Buffer[1].thread = false;
VideoFrameCount = 0;
fps = 0.0f;
ExitRequested = false;
Playing = false;
ThreadStack = NULL;
//gprintf("Opening video '%s'\n", filepath);
ReadThread = LWP_THREAD_NULL;
vFile = fopen(filepath, "rb");
if(!vFile)
{
//gprintf("Open video failed\n");
ExitRequested = true;
return;
}
if(Video.Init(vFile) == false)
{
//gprintf("Memory Allocation failed\n");
ExitRequested = true;
return;
}
fps = Video.getFps();
inited = true;
}
void WiiMovie::DeInit()
{
if(inited == false)
return;
inited = false;
//gprintf("Destructing WiiMovie object\n");
Playing = false;
ExitRequested = true;
Stop();
if(ReadThread != LWP_THREAD_NULL)
{
LWP_ResumeThread(ReadThread);
LWP_JoinThread(ReadThread, NULL);
}
if(ThreadStack != NULL)
{
MEM2_lo_free(ThreadStack);
ThreadStack = NULL;
}
Video.DeInit();
if(vFile != NULL)
fclose(vFile);
VideoF.dealloc();
vFile = NULL;
Frame = NULL;
TexHandle.Cleanup(Buffer[0]);
TexHandle.Cleanup(Buffer[1]);
Buffer[0].thread = false;
Buffer[1].thread = false;
BufferPos = 0;
}
bool WiiMovie::Play(bool loop)
{
if(!vFile)
return false;
ThreadStack = (u8*)MEM2_lo_alloc(32768);
if(!ThreadStack)
return false;
//gprintf("Start playing video\n");
Video.loop = loop;
PlayTime.reset();
Playing = true;
Buffer[0].thread = false;
Buffer[1].thread = false;
LWP_CreateThread(&ReadThread, UpdateThread, this, ThreadStack, 32768, 63);
//gprintf("Reading frames thread started\n");
return true;
}
void WiiMovie::Stop()
{
//gprintf("Stopping WiiMovie video\n");
ExitRequested = true;
}
void * WiiMovie::UpdateThread(void *arg)
{
WiiMovie *movie = static_cast<WiiMovie *>(arg);
while(!movie->ExitRequested)
{
movie->ReadNextFrame();
if(movie->Buffer[movie->BufferPos].thread == false)
movie->LoadNextFrame();
else if(movie->Frame->thread == false)
{
movie->Frame = &movie->Buffer[movie->BufferPos];
movie->BufferPos ^= 1;
}
}
return NULL;
}
void WiiMovie::ReadNextFrame()
{
for(u32 FramesNeeded = (u32)(PlayTime.elapsed()*fps); VideoFrameCount <= FramesNeeded; ++VideoFrameCount)
{
if(VideoFrameCount == FramesNeeded)
Playing = Video.loadNextFrame();
else
Video.loadNextFrame(true);
}
}
void WiiMovie::LoadNextFrame()
{
if(!vFile || !Playing)
return;
Video.getCurrentFrame(VideoF);
if(!VideoF.data)
return;
TexData *CurFrame = &Buffer[BufferPos];
if(TexHandle.fromTHP(CurFrame, VideoF.data, VideoF.getWidth(), VideoF.getHeight()) == TE_OK)
{
CurFrame->thread = true;
Frame = CurFrame;
BufferPos ^= 1;
}
}
bool WiiMovie::Continue()
{
if(!vFile || !Playing)
return false;
return true;
}