2007-04-02 00:06:00 +02:00
|
|
|
// Copyright (c) 2007, Rodrigo Braz Monteiro
|
2006-02-24 03:54:30 +01:00
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
|
|
// may be used to endorse or promote products derived from this software
|
|
|
|
// without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
|
|
|
|
|
|
|
/// @file video_provider_dummy.cpp
|
|
|
|
/// @brief Video provider returning a constant frame
|
|
|
|
/// @ingroup video_input
|
|
|
|
///
|
2006-02-24 03:54:30 +01:00
|
|
|
|
2009-01-04 07:31:48 +01:00
|
|
|
#include "config.h"
|
|
|
|
|
2012-02-07 02:21:37 +01:00
|
|
|
#include "video_provider_dummy.h"
|
|
|
|
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "colorspace.h"
|
2013-07-01 05:15:43 +02:00
|
|
|
#include "video_frame.h"
|
2013-01-04 16:01:50 +01:00
|
|
|
|
2012-10-26 16:09:14 +02:00
|
|
|
#include <libaegisub/color.h>
|
2013-01-04 16:01:50 +01:00
|
|
|
#include <libaegisub/fs.h>
|
|
|
|
#include <libaegisub/util.h>
|
|
|
|
|
|
|
|
#include <boost/algorithm/string/classification.hpp>
|
|
|
|
#include <boost/algorithm/string/predicate.hpp>
|
|
|
|
#include <boost/algorithm/string/split.hpp>
|
|
|
|
#include <boost/format.hpp>
|
2013-07-01 05:15:43 +02:00
|
|
|
#include <boost/gil/gil_all.hpp>
|
2007-04-02 00:06:00 +02:00
|
|
|
|
2012-02-07 02:21:37 +01:00
|
|
|
void DummyVideoProvider::Create(double fps, int frames, int width, int height, unsigned char red, unsigned char green, unsigned char blue, bool pattern) {
|
|
|
|
this->framecount = frames;
|
|
|
|
this->fps = fps;
|
|
|
|
this->width = width;
|
|
|
|
this->height = height;
|
2013-07-01 05:15:43 +02:00
|
|
|
data.resize(width * height * 4);
|
2007-04-04 03:54:37 +02:00
|
|
|
|
2013-07-01 05:15:43 +02:00
|
|
|
using namespace boost::gil;
|
|
|
|
auto dst = interleaved_view(width, height, (bgra8_pixel_t*)data.data(), 4 * width);
|
|
|
|
|
|
|
|
bgra8_pixel_t colors[2] = {
|
|
|
|
bgra8_pixel_t(blue, green, red, 0),
|
|
|
|
bgra8_pixel_t(blue, green, red, 0)
|
2012-02-07 02:21:37 +01:00
|
|
|
};
|
2007-04-04 03:54:37 +02:00
|
|
|
|
|
|
|
if (pattern) {
|
2012-02-07 02:21:37 +01:00
|
|
|
// Generate light version
|
|
|
|
unsigned char h, s, l;
|
|
|
|
rgb_to_hsl(red, blue, green, &h, &s, &l);
|
|
|
|
l += 24;
|
|
|
|
if (l < 24) l -= 48;
|
2013-07-01 05:15:43 +02:00
|
|
|
hsl_to_rgb(h, s, l, &red, &blue, &green);
|
|
|
|
colors[1] = bgra8_pixel_t(blue, green, red, 0);
|
2012-02-07 02:21:37 +01:00
|
|
|
|
|
|
|
// Divide into a 8x8 grid and use light colours when row % 2 != col % 2
|
2013-07-01 05:15:43 +02:00
|
|
|
auto out = dst.begin();
|
|
|
|
for (int y = 0; y < height; ++y)
|
|
|
|
for (int x = 0; x < width; ++x)
|
|
|
|
*out++ = colors[((y / 8) & 1) != ((x / 8) & 1)];
|
2007-04-04 03:54:37 +02:00
|
|
|
}
|
|
|
|
else {
|
2013-07-01 05:15:43 +02:00
|
|
|
fill_pixels(dst, colors[0]);
|
2007-04-02 01:13:29 +02:00
|
|
|
}
|
2007-04-02 00:06:00 +02:00
|
|
|
}
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
DummyVideoProvider::DummyVideoProvider(agi::fs::path const& filename) {
|
|
|
|
if (!boost::starts_with(filename.string(), "?dummy"))
|
|
|
|
throw agi::fs::FileNotFound(std::string("Attempted creating dummy video provider with non-dummy filename"));
|
2007-04-02 20:28:09 +02:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
std::vector<std::string> toks;
|
|
|
|
auto const& fields = filename.string().substr(7);
|
|
|
|
boost::split(toks, fields, boost::is_any_of(":"));
|
|
|
|
if (toks.size() != 8)
|
2010-08-02 08:32:01 +02:00
|
|
|
throw VideoOpenError("Too few fields in dummy video parameter list");
|
2007-04-02 20:28:09 +02:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
size_t i = 0;
|
2009-07-20 02:39:38 +02:00
|
|
|
double fps;
|
2013-01-04 16:01:50 +01:00
|
|
|
int frames, width, height, red, green, blue;
|
2007-04-02 20:28:09 +02:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
using agi::util::try_parse;
|
|
|
|
if (!try_parse(toks[i++], &fps)) throw VideoOpenError("Unable to parse fps field in dummy video parameter list");
|
|
|
|
if (!try_parse(toks[i++], &frames)) throw VideoOpenError("Unable to parse framecount field in dummy video parameter list");
|
|
|
|
if (!try_parse(toks[i++], &width)) throw VideoOpenError("Unable to parse width field in dummy video parameter list");
|
|
|
|
if (!try_parse(toks[i++], &height)) throw VideoOpenError("Unable to parse height field in dummy video parameter list");
|
|
|
|
if (!try_parse(toks[i++], &red)) throw VideoOpenError("Unable to parse red colour field in dummy video parameter list");
|
|
|
|
if (!try_parse(toks[i++], &green)) throw VideoOpenError("Unable to parse green colour field in dummy video parameter list");
|
|
|
|
if (!try_parse(toks[i++], &blue)) throw VideoOpenError("Unable to parse blue colour field in dummy video parameter list");
|
2007-04-02 20:28:09 +02:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
bool pattern = toks[i] == "c";
|
2007-04-02 20:28:09 +02:00
|
|
|
|
2012-02-07 02:21:37 +01:00
|
|
|
Create(fps, frames, width, height, red, green, blue, pattern);
|
2007-04-02 20:28:09 +02:00
|
|
|
}
|
|
|
|
|
2012-10-26 16:09:14 +02:00
|
|
|
DummyVideoProvider::DummyVideoProvider(double fps, int frames, int width, int height, agi::Color colour, bool pattern) {
|
|
|
|
Create(fps, frames, width, height, colour.r, colour.g, colour.b, pattern);
|
2007-04-02 20:28:09 +02:00
|
|
|
}
|
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
std::string DummyVideoProvider::MakeFilename(double fps, int frames, int width, int height, agi::Color colour, bool pattern) {
|
|
|
|
return str(boost::format("?dummy:%f:%d:%d:%d:%d:%d:%d:%s") % fps % frames % width % height % (int)colour.r % (int)colour.g % (int)colour.b % (pattern ? "c" : ""));
|
2007-04-02 00:06:00 +02:00
|
|
|
}
|
2013-07-01 05:15:43 +02:00
|
|
|
|
|
|
|
std::shared_ptr<VideoFrame> DummyVideoProvider::GetFrame(int) {
|
|
|
|
return std::make_shared<VideoFrame>(data.data(), width, height, width * 4, false);
|
|
|
|
}
|