Clean up DummyVideoProvider a bit
Originally committed to SVN as r6443.
This commit is contained in:
parent
f48ccc0640
commit
68c9989c89
2 changed files with 91 additions and 175 deletions
|
@ -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:", ¶ms)) {
|
if (!filename.StartsWith("?dummy:", ¶ms))
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"; }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue