Clean up DummyVideoProvider a bit

Originally committed to SVN as r6443.
This commit is contained in:
Thomas Goyne 2012-02-07 01:21:37 +00:00
parent f48ccc0640
commit 68c9989c89
2 changed files with 91 additions and 175 deletions

View file

@ -36,183 +36,91 @@
#include "config.h" #include "config.h"
#include "video_provider_dummy.h"
#ifndef AGI_PRE #ifndef AGI_PRE
#include <wx/colour.h>
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
#endif #endif
#include "colorspace.h" #include "colorspace.h"
#include "video_provider_dummy.h"
/// @brief Constructor void DummyVideoProvider::Create(double fps, int frames, int width, int height, unsigned char red, unsigned char green, unsigned char blue, bool pattern) {
/// @param _fps this->framecount = frames;
/// @param frames this->fps = fps;
/// @param _width this->width = width;
/// @param _height this->height = height;
/// @param colour this->frame = AegiVideoFrame(width, height);
/// @param pattern
///
void DummyVideoProvider::Create(double _fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) {
lastFrame = -1;
framecount = frames;
fps = _fps;
width = _width;
height = _height;
frame = AegiVideoFrame(width,height);
unsigned char *dst = frame.data; unsigned char *dst = frame.data;
unsigned char r = colour.Red(), g = colour.Green(), b = colour.Blue(); unsigned char colors[2][4] = {
blue, green, red, 0,
unsigned char h, s, l, lr, lg, lb; // light variants 0, 0, 0, 0
rgb_to_hsl(r, g, b, &h, &s, &l); };
l += 24;
if (l < 24) l -= 48;
hsl_to_rgb(h, s, l, &lr, &lg, &lb);
if (pattern) { if (pattern) {
// Generate light version
unsigned char h, s, l;
rgb_to_hsl(red, blue, green, &h, &s, &l);
l += 24;
if (l < 24) l -= 48;
hsl_to_rgb(h, s, l, &colors[1][2], &colors[1][1], &colors[1][0]);
// Divide into a 8x8 grid and use light colours when row % 2 != col % 2
int ppitch = frame.pitch / frame.GetBpp(); int ppitch = frame.pitch / frame.GetBpp();
for (unsigned int y = 0; y < frame.h; ++y) { for (unsigned int y = 0; y < frame.h; ++y) {
if ((y / 8) & 1) { for (int x = 0; x < ppitch; ++x) {
for (int x = 0; x < ppitch; ++x) { memcpy(dst, colors[((y / 8) & 1) != ((x / 8) & 1)], 4);
if ((x / 8) & 1) { dst += 4;
*dst++ = b;
*dst++ = g;
*dst++ = r;
*dst++ = 0;
}
else {
*dst++ = lb;
*dst++ = lg;
*dst++ = lr;
*dst++ = 0;
}
}
}
else {
for (int x = 0; x < ppitch; ++x) {
if ((x / 8) & 1) {
*dst++ = lb;
*dst++ = lg;
*dst++ = lr;
*dst++ = 0;
}
else {
*dst++ = b;
*dst++ = g;
*dst++ = r;
*dst++ = 0;
}
}
} }
} }
} }
else { else {
for (int i=frame.pitch*frame.h/frame.GetBpp();--i>=0;) { for (int i = frame.pitch * frame.h / frame.GetBpp() - 1; i >= 0; --i)
*dst++ = b; memcpy(dst + i * 4, colors[0], 4);
*dst++ = g;
*dst++ = r;
*dst++ = 0;
}
} }
} }
/// @brief Parsing constructor static long get_long(wxStringTokenizer &t, const char *err) {
/// @param filename long ret;
/// if (!t.GetNextToken().ToLong(&ret))
DummyVideoProvider::DummyVideoProvider(wxString filename) throw VideoOpenError(err);
{ return ret;
}
DummyVideoProvider::DummyVideoProvider(wxString const& filename) {
wxString params; wxString params;
if (!filename.StartsWith("?dummy:", &params)) { if (!filename.StartsWith("?dummy:", &params))
throw agi::FileNotFoundError("Attempted creating dummy video provider with non-dummy filename"); throw agi::FileNotFoundError("Attempted creating dummy video provider with non-dummy filename");
}
wxStringTokenizer t(params, ":"); wxStringTokenizer t(params, ":");
if (t.CountTokens() < 7) { if (t.CountTokens() < 7)
throw VideoOpenError("Too few fields in dummy video parameter list"); throw VideoOpenError("Too few fields in dummy video parameter list");
}
double fps; double fps;
long _frames, _width, _height, red, green, blue; if (!t.GetNextToken().ToDouble(&fps))
bool pattern = false;
wxString field = t.GetNextToken();
if (!field.ToDouble(&fps)) {
throw VideoOpenError("Unable to parse fps field in dummy video parameter list"); throw VideoOpenError("Unable to parse fps field in dummy video parameter list");
}
field = t.GetNextToken(); long frames = get_long(t, "Unable to parse framecount field in dummy video parameter list");
if (!field.ToLong(&_frames)) { long width = get_long(t, "Unable to parse width field in dummy video parameter list");
throw VideoOpenError("Unable to parse framecount field in dummy video parameter list"); long height = get_long(t, "Unable to parse height field in dummy video parameter list");
} long red = get_long(t, "Unable to parse red colour field in dummy video parameter list");
long green = get_long(t, "Unable to parse green colour field in dummy video parameter list");
long blue = get_long(t, "Unable to parse blue colour field in dummy video parameter list");
field = t.GetNextToken(); bool pattern = t.GetNextToken() == "c";
if (!field.ToLong(&_width)) {
throw VideoOpenError("Unable to parse width field in dummy video parameter list");
}
field = t.GetNextToken(); Create(fps, frames, width, height, red, green, blue, pattern);
if (!field.ToLong(&_height)) {
throw VideoOpenError("Unable to parse height field in dummy video parameter list");
}
field = t.GetNextToken();
if (!field.ToLong(&red)) {
throw VideoOpenError("Unable to parse red colour field in dummy video parameter list");
}
field = t.GetNextToken();
if (!field.ToLong(&green)) {
throw VideoOpenError("Unable to parse green colour field in dummy video parameter list");
}
field = t.GetNextToken();
if (!field.ToLong(&blue)) {
throw VideoOpenError("Unable to parse blue colour field in dummy video parameter list");
}
field = t.GetNextToken();
if (field == "c") {
pattern = true;
}
Create(fps, _frames, _width, _height, wxColour(red, green, blue), pattern);
} }
/// @brief Direct constructor DummyVideoProvider::DummyVideoProvider(double fps, int frames, int width, int height, const wxColour &colour, bool pattern) {
/// @param _fps Create(fps, frames, width, height, colour.Red(), colour.Green(), colour.Blue(), pattern);
/// @param frames
/// @param _width
/// @param _height
/// @param colour
/// @param pattern
///
DummyVideoProvider::DummyVideoProvider(double _fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) {
Create(_fps, frames, _width, _height, colour, pattern);
} }
/// @brief Destructor
///
DummyVideoProvider::~DummyVideoProvider() { DummyVideoProvider::~DummyVideoProvider() {
frame.Clear(); frame.Clear();
} }
/// @brief Construct a fake filename describing the video wxString DummyVideoProvider::MakeFilename(double fps, int frames, int width, int height, const wxColour &colour, bool pattern) {
/// @param fps return wxString::Format("?dummy:%f:%d:%d:%d:%d:%d:%d:%s", fps, frames, width, height, colour.Red(), colour.Green(), colour.Blue(), pattern ? "c" : "");
/// @param frames
/// @param _width
/// @param _height
/// @param colour
/// @param pattern
/// @return
///
wxString DummyVideoProvider::MakeFilename(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) {
return wxString::Format("?dummy:%f:%d:%d:%d:%d:%d:%d:%s", fps, frames, _width, _height, colour.Red(), colour.Green(), colour.Blue(), pattern?"c":"");
}
/// @brief Get frame
/// @param n
/// @return
///
const AegiVideoFrame DummyVideoProvider::GetFrame(int n) {
lastFrame = n;
return frame;
} }

View file

@ -34,53 +34,61 @@
/// @ingroup video_input /// @ingroup video_input
/// ///
// The dummy video provider needs a header, since it needs to be created directly as a special case
#ifndef AGI_PRE
#include <wx/colour.h>
#endif
#include "include/aegisub/video_provider.h" #include "include/aegisub/video_provider.h"
#include "video_frame.h" #include "video_frame.h"
/// DOCME class wxColour;
/// @class DummyVideoProvider /// @class DummyVideoProvider
/// @brief DOCME /// @brief A dummy video provider for when opening a file is just too much effort
/// ///
/// DOCME /// This simply returns a single constant frame, which can either be a flat
/// color or a checkerboard pattern
class DummyVideoProvider : public VideoProvider { class DummyVideoProvider : public VideoProvider {
/// DOCME int framecount; ///< Length of the dummy video in frames
int lastFrame; agi::vfr::Framerate fps; ///< Frame rate to use
int width; ///< Width in pixels
int height; ///< Height in pixels
/// DOCME /// The single image which is returned for all frames
int framecount;
/// DOCME
agi::vfr::Framerate fps;
/// DOCME
int width;
/// DOCME
int height;
/// DOCME
AegiVideoFrame frame; AegiVideoFrame frame;
void Create(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); /// Create the dummy frame from the given parameters
/// @param fps Frame rate of the dummy video
/// @param frames Length in frames of the dummy video
/// @param width Width in pixels of the dummy video
/// @param height Height in pixels of the dummy video
/// @param red Red component of the primary colour of the dummy video
/// @param green Green component of the primary colour of the dummy video
/// @param blue Blue component of the primary colour of the dummy video
/// @param pattern Use a checkerboard pattern rather than a solid colour
void Create(double fps, int frames, int width, int height, unsigned char red, unsigned char green, unsigned char blue, bool pattern);
public: public:
DummyVideoProvider(wxString filename); /// Create a dummy video from a string returned from MakeFilename
DummyVideoProvider(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); DummyVideoProvider(wxString const& filename);
/// Create a dummy video from separate parameters
/// @param fps Frame rate of the dummy video
/// @param frames Length in frames of the dummy video
/// @param width Width in pixels of the dummy video
/// @param height Height in pixels of the dummy video
/// @param colour Primary colour of the dummy video
/// @param pattern Use a checkerboard pattern rather than a solid colour
DummyVideoProvider(double fps, int frames, int width, int height, wxColour const& colour, bool pattern);
/// Destructor
~DummyVideoProvider(); ~DummyVideoProvider();
const AegiVideoFrame GetFrame(int n); /// Make a fake filename which when passed to the constructor taking a
static wxString MakeFilename(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); /// string will result in a video with the given parameters
static wxString MakeFilename(double fps, int frames, int width, int height, wxColour const& colour, bool pattern);
int GetFrameCount() const { return framecount; } const AegiVideoFrame GetFrame(int n) { return frame; }
int GetWidth() const { return width; } int GetFrameCount() const { return framecount; }
int GetHeight() const { return height; } int GetWidth() const { return width; }
agi::vfr::Framerate GetFPS() const { return fps; } int GetHeight() const { return height; }
agi::vfr::Framerate GetFPS() const { return fps; }
std::vector<int> GetKeyFrames() const { return std::vector<int>(); }; std::vector<int> GetKeyFrames() const { return std::vector<int>(); };
wxString GetDecoderName() const { return "Dummy Video Provider"; } wxString GetDecoderName() const { return "Dummy Video Provider"; }
}; };