Skip to content

Commit

Permalink
Fix destruction of the video player
Browse files Browse the repository at this point in the history
  • Loading branch information
mplucinski committed Jun 2, 2018
1 parent 0ccf976 commit b1acef2
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/engine/BaseEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ BaseEngine::~BaseEngine()
{
getRootUIView().removeChild(m_pHUD);
delete m_AudioEngine;
delete m_VideoPlayer;
delete m_pHUD;
delete m_pFontCache;
}
Expand Down
58 changes: 39 additions & 19 deletions src/media/Video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ extern "C" {

namespace {

const float playbackRatio = 1.0; // for testing only, usually should be set to 1.0

struct deleteAVCodecContext
{
void operator()(AVCodecContext *ptr)
Expand Down Expand Up @@ -69,8 +71,8 @@ namespace Media {
class Video
{
public:
Video(VideoPlayer &player, Engine::BaseEngine &engine, const std::string &fileName)
: player{player}, engine{engine}, fileName{fileName}
Video(VideoPlayer &player, Engine::BaseEngine &engine, const std::string &fileName_)
: player{player}, engine{engine}, fileName{Utils::getCaseSensitivePath("/_work/data/video/" + fileName_, engine.getEngineArgs().gameBaseDirectory)}
{
av_register_all();

Expand All @@ -81,12 +83,17 @@ namespace Media {

engine->getRootUIView().addChild(view);
}).wait();

if (!Utils::fileExists(fileName))
LogWarn() << "Failed to find the video file at: " << fileName;

}

~Video()
{
engine.getJobManager().executeInMainThread<void>([this](Engine::BaseEngine *engine) {
view->setHidden(true);
engine->getRootUIView().removeChild(view);
}).wait();
}

Expand All @@ -96,18 +103,15 @@ namespace Media {
packet.data = nullptr;
packet.size = 0;

std::string filePath = "/_work/data/video/" + fileName;
std::string fileFullPath = Utils::getCaseSensitivePath(filePath, engine.getEngineArgs().gameBaseDirectory);

if (!Utils::fileExists(fileFullPath))
if (!Utils::fileExists(fileName))
{
LogError() << "Failed to find the video file at: " << fileFullPath;
LogError() << "Failed to find the video file at: " << fileName;
return false;
}

AVFormatContext *formatContextPtr = nullptr;
if (avformat_open_input(&formatContextPtr, fileFullPath.c_str(), nullptr, nullptr) < 0) {
LogWarn() << "Could not open file: " << fileFullPath;
if (avformat_open_input(&formatContextPtr, fileName.c_str(), nullptr, nullptr) < 0) {
LogWarn() << "Could not open file: " << fileName;
return false;
}
formatContext.reset(formatContextPtr);
Expand All @@ -127,7 +131,7 @@ namespace Media {
return false;
}

av_dump_format(formatContext.get(), 0, fileFullPath.c_str(), 0); // TODO: dump to logger
av_dump_format(formatContext.get(), 0, fileName.c_str(), 0); // TODO: dump to logger

if (videoCodecContext->pix_fmt != AV_PIX_FMT_YUV420P) {
LogWarn() << "Unknown pixel format";
Expand Down Expand Up @@ -223,7 +227,6 @@ namespace Media {
}

std::cout << "video frame: " << videoCodecContext->frame_number << ", pts: " << frame->pts << std::endl;

videoFrames.push(std::move(frame));
}
return Outcome::FrameVideo;
Expand Down Expand Up @@ -299,12 +302,13 @@ namespace Media {
}).wait();
}

public:
public:
bool update(double dt)
{
currentTime += dt/videoTimeBase;
currentTime += dt/videoTimeBase*playbackRatio;
assert(!videoFrames.empty());
assert(videoFrames.front());

if (currentTime >= videoFrames.front()->pts) {
AVFrameRefPtr frame;
videoFrames.front().swap(frame);
Expand All @@ -313,8 +317,13 @@ namespace Media {

displayVideoFrame(frame);

if (nextVideoFrame() != Outcome::FrameVideo)
return false;
while (videoFrames.empty() || currentTime >= videoFrames.front()->pts) {
if (!videoFrames.empty())
videoFrames.pop();

if(nextVideoFrame() != Outcome::FrameVideo)
return false;
}
}
return true;
}
Expand All @@ -328,11 +337,11 @@ namespace Media {
const std::string fileName;
bool initialized_ = false;
AVFormatContextPtr formatContext;
int videoStreamIndex, audioStreamIndex;
int videoStreamIndex = 0, audioStreamIndex = 0;
AVCodecContextPtr videoCodecContext, audioCodecContext;
std::queue<AVFrameRefPtr> videoFrames;
double videoTimeBase = 0, audioTimeBase = 0, currentTime = 0;
AVPacket packet;
AVPacket packet = {};
Handle::TextureHandle texture;
UI::ImageView *view;
};
Expand All @@ -343,18 +352,29 @@ Media::VideoPlayer::VideoPlayer(Engine::BaseEngine &engine): engine{engine}
{
}

Media::VideoPlayer::~VideoPlayer() {}
Media::VideoPlayer::~VideoPlayer()
{
stop();
}

void Media::VideoPlayer::play(const std::string &fileName)
void Media::VideoPlayer::play(std::string fileName)
{
std::cout << "playVideo(" << fileName << ")" << std::endl;
#ifdef RE_ENABLE_FFMPEG
if (!Utils::endsWith(Utils::toUpper(fileName), ".BIK"))
fileName += ".bik";

currentVideo = std::make_unique<Video>(*this, engine, fileName);
#else
LogWarn() << "No libavcodec support compiled, won't play" << fileName;
#endif
}

void Media::VideoPlayer::stop()
{
currentVideo = nullptr;
}

void Media::VideoPlayer::frameUpdate(double dt, uint16_t width, uint16_t height)
{
#ifdef RE_ENABLE_FFMPEG
Expand Down
3 changes: 2 additions & 1 deletion src/media/Video.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ namespace Media {
public:
VideoPlayer(Engine::BaseEngine &engine);
~VideoPlayer();
void play(const std::string &fileName);
void play(std::string fileName);
void stop();
void frameUpdate(double dt, uint16_t width, uint16_t height);
bool active();

Expand Down

0 comments on commit b1acef2

Please sign in to comment.