Don't discard frames which are decoded before the video display becomes visible

Originally committed to SVN as r6950.
This commit is contained in:
Thomas Goyne 2012-07-29 03:23:24 +00:00
parent 8c42f09235
commit ffe41cdf20
2 changed files with 19 additions and 10 deletions

View File

@ -69,6 +69,7 @@
#include "utils.h" #include "utils.h"
#include "video_out_gl.h" #include "video_out_gl.h"
#include "video_context.h" #include "video_context.h"
#include "video_frame.h"
#include "visual_tool.h" #include "visual_tool.h"
/// Attribute list for gl canvases; set the canvases to doublebuffered rgba with an 8 bit stencil buffer /// Attribute list for gl canvases; set the canvases to doublebuffered rgba with an 8 bit stencil buffer
@ -158,11 +159,14 @@ bool VideoDisplay::InitContext() {
} }
void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) { void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) {
if (!InitContext()) { pending_frame = evt.frame;
evt.Skip(); Render();
return;
} }
void VideoDisplay::Render() try {
if (!con->videoController->IsLoaded() || !InitContext() || (!videoOut && !pending_frame))
return;
if (!videoOut) if (!videoOut)
videoOut.reset(new VideoOutGL); videoOut.reset(new VideoOutGL);
@ -170,7 +174,10 @@ void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) {
cmd::call("video/tool/cross", con); cmd::call("video/tool/cross", con);
try { try {
videoOut->UploadFrameData(*evt.frame); if (pending_frame) {
videoOut->UploadFrameData(*pending_frame);
pending_frame.reset();
}
} }
catch (const VideoOutInitException& err) { catch (const VideoOutInitException& err) {
wxLogError( wxLogError(
@ -179,19 +186,15 @@ void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) {
"Error message reported: %s", "Error message reported: %s",
err.GetMessage()); err.GetMessage());
con->videoController->SetVideo(""); con->videoController->SetVideo("");
return;
} }
catch (const VideoOutRenderException& err) { catch (const VideoOutRenderException& err) {
wxLogError( wxLogError(
"Could not upload video frame to graphics card.\n" "Could not upload video frame to graphics card.\n"
"Error message reported: %s", "Error message reported: %s",
err.GetMessage()); err.GetMessage());
}
Render();
}
void VideoDisplay::Render() try {
if (!con->videoController->IsLoaded() || !videoOut || !InitContext() )
return; return;
}
if (!viewport_height || !viewport_width) if (!viewport_height || !viewport_width)
PositionVideo(); PositionVideo();
@ -428,6 +431,7 @@ void VideoDisplay::Unload() {
glContext.reset(); glContext.reset();
videoOut.reset(); videoOut.reset();
tool.reset(); tool.reset();
pending_frame.reset();
} }
void VideoDisplay::OnSubtitlesSave() { void VideoDisplay::OnSubtitlesSave() {

View File

@ -37,6 +37,7 @@
#ifndef AGI_PRE #ifndef AGI_PRE
#include <list> #include <list>
#include <tr1/memory>
#include <wx/glcanvas.h> #include <wx/glcanvas.h>
#endif #endif
@ -49,6 +50,7 @@
#include "vector2d.h" #include "vector2d.h"
// Prototypes // Prototypes
class AegiVideoFrame;
class FrameReadyEvent; class FrameReadyEvent;
class VideoContext; class VideoContext;
class VideoOutGL; class VideoOutGL;
@ -114,6 +116,9 @@ class VideoDisplay : public wxGLCanvas {
/// Whether the display can be freely resized by the user /// Whether the display can be freely resized by the user
bool freeSize; bool freeSize;
/// Frame which will replace the currently visible frame on the next render
std::tr1::shared_ptr<AegiVideoFrame> pending_frame;
/// @brief Draw an overscan mask /// @brief Draw an overscan mask
/// @param horizontal_percent The percent of the video reserved horizontally /// @param horizontal_percent The percent of the video reserved horizontally
/// @param vertical_percent The percent of the video reserved vertically /// @param vertical_percent The percent of the video reserved vertically