You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Adding unit tests to validate FFmpegReader, Clip, and Timeline frame accuracy of GIF files, plus GIF with time curves.
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
+127
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "openshot_catch.h"
|
#include "openshot_catch.h"
|
||||||
|
|
||||||
@@ -226,6 +227,132 @@ TEST_CASE( "effects", "[libopenshot][clip]" )
|
|||||||
CHECK((int)c10.Effects().size() == 2);
|
CHECK((int)c10.Effects().size() == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "GIF_clip_properties", "[libopenshot][clip][gif]" )
|
||||||
|
{
|
||||||
|
std::stringstream path;
|
||||||
|
path << TEST_MEDIA_PATH << "animation.gif";
|
||||||
|
Clip c(path.str());
|
||||||
|
c.Open();
|
||||||
|
|
||||||
|
FFmpegReader *r = dynamic_cast<FFmpegReader*>(c.Reader());
|
||||||
|
REQUIRE(r != nullptr);
|
||||||
|
CHECK(r->info.video_length == 20);
|
||||||
|
CHECK(r->info.fps.num == 5);
|
||||||
|
CHECK(r->info.fps.den == 1);
|
||||||
|
CHECK(r->info.duration == Approx(4.0f).margin(0.01));
|
||||||
|
|
||||||
|
c.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "GIF_time_mapping", "[libopenshot][clip][gif]" )
|
||||||
|
{
|
||||||
|
std::stringstream path;
|
||||||
|
path << TEST_MEDIA_PATH << "animation.gif";
|
||||||
|
|
||||||
|
auto frame_color = [](std::shared_ptr<Frame> f) {
|
||||||
|
const unsigned char* row = f->GetPixels(25);
|
||||||
|
return row[25 * 4];
|
||||||
|
};
|
||||||
|
auto expected_color = [](int frame) {
|
||||||
|
return (frame - 1) * 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Slow mapping: stretch 20 frames over 50 frames
|
||||||
|
Clip slow(path.str());
|
||||||
|
slow.time.AddPoint(1,1, LINEAR);
|
||||||
|
slow.time.AddPoint(50,20, LINEAR);
|
||||||
|
slow.Open();
|
||||||
|
|
||||||
|
std::set<int> slow_colors;
|
||||||
|
for (int i = 1; i <= 50; ++i) {
|
||||||
|
int src = slow.time.GetLong(i);
|
||||||
|
int c = frame_color(slow.GetFrame(i));
|
||||||
|
CHECK(c == expected_color(src));
|
||||||
|
slow_colors.insert(c);
|
||||||
|
}
|
||||||
|
CHECK((int)slow_colors.size() == 20);
|
||||||
|
slow.Close();
|
||||||
|
|
||||||
|
// Fast mapping: shrink 20 frames to 10 frames
|
||||||
|
Clip fast(path.str());
|
||||||
|
fast.time.AddPoint(1,1, LINEAR);
|
||||||
|
fast.time.AddPoint(10,20, LINEAR);
|
||||||
|
fast.Open();
|
||||||
|
|
||||||
|
std::set<int> fast_colors;
|
||||||
|
for (int i = 1; i <= 10; ++i) {
|
||||||
|
int src = fast.time.GetLong(i);
|
||||||
|
int c = frame_color(fast.GetFrame(i));
|
||||||
|
CHECK(c == expected_color(src));
|
||||||
|
fast_colors.insert(c);
|
||||||
|
}
|
||||||
|
CHECK((int)fast_colors.size() == 10);
|
||||||
|
fast.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "GIF_timeline_mapping", "[libopenshot][clip][gif]" )
|
||||||
|
{
|
||||||
|
// Create a timeline
|
||||||
|
Timeline t1(50, 50, Fraction(5, 1), 44100, 2, LAYOUT_STEREO);
|
||||||
|
|
||||||
|
std::stringstream path;
|
||||||
|
path << TEST_MEDIA_PATH << "animation.gif";
|
||||||
|
|
||||||
|
auto frame_color = [](std::shared_ptr<Frame> f) {
|
||||||
|
const unsigned char* row = f->GetPixels(25);
|
||||||
|
return row[25 * 4];
|
||||||
|
};
|
||||||
|
auto expected_color = [](int frame) {
|
||||||
|
return (frame - 1) * 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Slow mapping: stretch 20 frames over 50 frames
|
||||||
|
Clip slow(path.str());
|
||||||
|
slow.Position(0.0);
|
||||||
|
slow.Layer(1);
|
||||||
|
slow.time.AddPoint(1,1, LINEAR);
|
||||||
|
slow.time.AddPoint(50,20, LINEAR);
|
||||||
|
slow.End(10.0);
|
||||||
|
t1.AddClip(&slow);
|
||||||
|
t1.Open();
|
||||||
|
|
||||||
|
std::set<int> slow_colors;
|
||||||
|
for (int i = 1; i <= 50; ++i) {
|
||||||
|
int src = slow.time.GetLong(i);
|
||||||
|
std::stringstream frame_save;
|
||||||
|
t1.GetFrame(i)->Save(frame_save.str(), 1.0, "PNG", 100);
|
||||||
|
int c = frame_color(t1.GetFrame(i));
|
||||||
|
std::cout << c << std::endl;
|
||||||
|
CHECK(c == expected_color(src));
|
||||||
|
slow_colors.insert(c);
|
||||||
|
}
|
||||||
|
CHECK((int)slow_colors.size() == 20);
|
||||||
|
t1.Close();
|
||||||
|
|
||||||
|
// Create a timeline
|
||||||
|
Timeline t2(50, 50, Fraction(5, 1), 44100, 2, LAYOUT_STEREO);
|
||||||
|
|
||||||
|
// Fast mapping: shrink 20 frames to 10 frames
|
||||||
|
Clip fast(path.str());
|
||||||
|
fast.Position(0.0);
|
||||||
|
fast.Layer(1);
|
||||||
|
fast.time.AddPoint(1,1, LINEAR);
|
||||||
|
fast.time.AddPoint(10,20, LINEAR);
|
||||||
|
fast.End(2.0);
|
||||||
|
t2.AddClip(&fast);
|
||||||
|
t2.Open();
|
||||||
|
|
||||||
|
std::set<int> fast_colors;
|
||||||
|
for (int i = 1; i <= 10; ++i) {
|
||||||
|
int src = fast.time.GetLong(i);
|
||||||
|
int c = frame_color(t2.GetFrame(i));
|
||||||
|
CHECK(c == expected_color(src));
|
||||||
|
fast_colors.insert(c);
|
||||||
|
}
|
||||||
|
CHECK((int)fast_colors.size() == 10);
|
||||||
|
t2.Close();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE( "verify parent Timeline", "[libopenshot][clip]" )
|
TEST_CASE( "verify parent Timeline", "[libopenshot][clip]" )
|
||||||
{
|
{
|
||||||
Timeline t1(640, 480, Fraction(30,1), 44100, 2, LAYOUT_STEREO);
|
Timeline t1(640, 480, Fraction(30,1), 44100, 2, LAYOUT_STEREO);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "openshot_catch.h"
|
#include "openshot_catch.h"
|
||||||
|
|
||||||
@@ -189,6 +190,35 @@ TEST_CASE( "Frame_Rate", "[libopenshot][ffmpegreader]" )
|
|||||||
r.Close();
|
r.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "GIF_TimeBase", "[libopenshot][ffmpegreader]" )
|
||||||
|
{
|
||||||
|
// Create a reader
|
||||||
|
std::stringstream path;
|
||||||
|
path << TEST_MEDIA_PATH << "animation.gif";
|
||||||
|
FFmpegReader r(path.str());
|
||||||
|
r.Open();
|
||||||
|
|
||||||
|
// Verify basic info
|
||||||
|
CHECK(r.info.fps.num == 5);
|
||||||
|
CHECK(r.info.fps.den == 1);
|
||||||
|
CHECK(r.info.video_length == 20);
|
||||||
|
CHECK(r.info.duration == Approx(4.0f).margin(0.01));
|
||||||
|
|
||||||
|
auto frame_color = [](std::shared_ptr<Frame> f) {
|
||||||
|
const unsigned char* row = f->GetPixels(25);
|
||||||
|
return row[25 * 4];
|
||||||
|
};
|
||||||
|
auto expected_color = [](int frame) {
|
||||||
|
return (frame - 1) * 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 1; i <= r.info.video_length; ++i) {
|
||||||
|
CHECK(frame_color(r.GetFrame(i)) == expected_color(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Close();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE( "Multiple_Open_and_Close", "[libopenshot][ffmpegreader]" )
|
TEST_CASE( "Multiple_Open_and_Close", "[libopenshot][ffmpegreader]" )
|
||||||
{
|
{
|
||||||
// Create a reader
|
// Create a reader
|
||||||
|
|||||||
Reference in New Issue
Block a user