修复bug

This commit is contained in:
2026-01-05 03:40:36 +08:00
parent 8263ccf814
commit 79f376b512
11 changed files with 431 additions and 24 deletions
+6
View File
@@ -7,11 +7,17 @@ add_executable(olive-gtest
node_keyframe_test.cpp
node_serialization_test.cpp
render_videoparams_test.cpp
render_videoparams_branch_test.cpp
render_audioparams_test.cpp
render_audioparams_branch_test.cpp
render_sampleformat_test.cpp
render_pixelformat_test.cpp
project_serializer_test.cpp
timeline_marker_test.cpp
undo_stack_test.cpp
plugin_support_test.cpp
plugin_support_image_test.cpp
plugin_support_clip_test.cpp
codec_frame_test.cpp
task_taskmanager_test.cpp
module_smoke_test.cpp
+96
View File
@@ -0,0 +1,96 @@
#include <gtest/gtest.h>
#include "ofxImageEffect.h"
#include "ofxhClip.h"
#include "pluginSupport/OliveClip.h"
namespace {
olive::VideoParams MakeParams(int width, int height,
olive::core::PixelFormat format,
int channels,
bool premultiplied)
{
olive::VideoParams params;
params.set_width(width);
params.set_height(height);
params.set_format(format);
params.set_channel_count(channels);
params.set_premultiplied_alpha(premultiplied);
return params;
}
}
TEST(PluginSupportClip, PropertyGetters)
{
OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName);
olive::VideoParams params =
MakeParams(1920, 1080, olive::core::PixelFormat::U16, 3, false);
params.set_pixel_aspect_ratio(olive::core::rational(2, 1));
params.set_frame_rate(olive::core::rational(30, 1));
params.set_start_time(2);
params.set_duration(4);
params.set_interlacing(olive::VideoParams::kInterlacedTopFirst);
olive::plugin::OliveClipInstance clip(nullptr, desc, params);
EXPECT_EQ(clip.getUnmappedBitDepth(), kOfxBitDepthShort);
EXPECT_EQ(clip.getUnmappedComponents(), kOfxImageComponentRGB);
EXPECT_EQ(clip.getPremult(), kOfxImageUnPreMultiplied);
EXPECT_DOUBLE_EQ(clip.getAspectRatio(), 2.0);
EXPECT_DOUBLE_EQ(clip.getFrameRate(), 30.0);
double start_frame = 0.0;
double end_frame = 0.0;
clip.getFrameRange(start_frame, end_frame);
EXPECT_DOUBLE_EQ(start_frame, 60.0);
EXPECT_DOUBLE_EQ(end_frame, 180.0);
EXPECT_EQ(clip.getFieldOrder(), kOfxImageFieldUpper);
EXPECT_DOUBLE_EQ(clip.getUnmappedFrameRate(), 30.0);
clip.getUnmappedFrameRange(start_frame, end_frame);
EXPECT_DOUBLE_EQ(start_frame, 60.0);
EXPECT_DOUBLE_EQ(end_frame, 180.0);
EXPECT_FALSE(clip.getContinuousSamples());
EXPECT_FALSE(clip.getConnected());
}
TEST(PluginSupportClip, GetImageClampsBoundsAndCachesOutput)
{
OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName);
olive::VideoParams params =
MakeParams(100, 80, olive::core::PixelFormat::U8, 4, true);
olive::plugin::OliveClipInstance clip(nullptr, desc, params);
OfxRectD optional_bounds = { -10.0, -10.0, 200.0, 200.0 };
OFX::Host::ImageEffect::Image *image =
clip.getImage(0.0, &optional_bounds);
ASSERT_NE(image, nullptr);
auto *olive_image = static_cast<olive::plugin::Image *>(image);
EXPECT_EQ(olive_image->width(), 100);
EXPECT_EQ(olive_image->height(), 80);
OFX::Host::ImageEffect::Image *image_again =
clip.getImage(0.0, nullptr);
EXPECT_EQ(image, image_again);
}
TEST(PluginSupportClip, GetImageReturnsNewImageForNonOutput)
{
OFX::Host::ImageEffect::ClipDescriptor desc("Source");
olive::VideoParams params =
MakeParams(64, 64, olive::core::PixelFormat::U8, 4, false);
olive::plugin::OliveClipInstance clip(nullptr, desc, params);
OFX::Host::ImageEffect::Image *first = clip.getImage(0.0, nullptr);
OFX::Host::ImageEffect::Image *second = clip.getImage(0.0, nullptr);
EXPECT_NE(first, nullptr);
EXPECT_NE(second, nullptr);
EXPECT_NE(first, second);
first->releaseReference();
second->releaseReference();
}
+91
View File
@@ -0,0 +1,91 @@
#include <gtest/gtest.h>
#include "ofxImageEffect.h"
#include "ofxhClip.h"
#include "pluginSupport/OliveClip.h"
#include "pluginSupport/image.h"
namespace {
olive::VideoParams MakeParams(int width, int height,
olive::core::PixelFormat format,
int channels,
bool premultiplied)
{
olive::VideoParams params;
params.set_width(width);
params.set_height(height);
params.set_format(format);
params.set_channel_count(channels);
params.set_premultiplied_alpha(premultiplied);
return params;
}
}
TEST(PluginSupportImage, AllocateFromParamsSetsProperties)
{
OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName);
olive::VideoParams params =
MakeParams(640, 480, olive::core::PixelFormat::U8, 4, true);
olive::plugin::OliveClipInstance clip(nullptr, desc, params);
olive::plugin::Image image(clip);
OfxRectI bounds = { 0, 0, 640, 480 };
OfxRectI rod = bounds;
image.AllocateFromParams(params, bounds, rod, true);
EXPECT_NE(image.data(), nullptr);
EXPECT_EQ(image.width(), 640);
EXPECT_EQ(image.height(), 480);
EXPECT_EQ(image.row_bytes(), 640 * 4);
EXPECT_EQ(image.pixel_format(), olive::core::PixelFormat::U8);
EXPECT_EQ(image.channel_count(), 4);
EXPECT_TRUE(image.premultiplied_alpha());
}
TEST(PluginSupportImage, EnsureAllocatedFromParamsClearsAndResizes)
{
OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName);
olive::VideoParams params =
MakeParams(64, 32, olive::core::PixelFormat::U8, 3, false);
olive::plugin::OliveClipInstance clip(nullptr, desc, params);
olive::plugin::Image image(clip);
OfxRectI bounds = { 0, 0, 64, 32 };
OfxRectI rod = bounds;
image.AllocateFromParams(params, bounds, rod, true);
ASSERT_NE(image.data(), nullptr);
image.data()[0] = 0xAB;
image.EnsureAllocatedFromParams(params, bounds, rod, true);
EXPECT_EQ(image.data()[0], 0);
OfxRectI new_bounds = { 0, 0, 16, 16 };
image.EnsureAllocatedFromParams(params, new_bounds, rod, false);
EXPECT_EQ(image.width(), 16);
EXPECT_EQ(image.height(), 16);
}
TEST(PluginSupportImage, PropertyFallbacks)
{
OFX::Host::ImageEffect::ClipDescriptor desc(kOfxImageEffectOutputClipName);
olive::VideoParams params =
MakeParams(1, 1, olive::core::PixelFormat::INVALID, 0, false);
olive::plugin::OliveClipInstance clip(nullptr, desc, params);
olive::plugin::Image image(clip);
image.setStringProperty(kOfxImageEffectPropPixelDepth, kOfxBitDepthHalf);
image.setStringProperty(kOfxImageEffectPropComponents,
kOfxImageComponentRGB);
image.setStringProperty(kOfxImageEffectPropPreMultiplication,
kOfxImagePreMultiplied);
image.setIntProperty(kOfxImagePropBounds, 10, 0);
image.setIntProperty(kOfxImagePropBounds, 20, 1);
image.setIntProperty(kOfxImagePropBounds, 42, 2);
image.setIntProperty(kOfxImagePropBounds, 70, 3);
EXPECT_EQ(image.pixel_format(), olive::core::PixelFormat::F16);
EXPECT_EQ(image.channel_count(), 3);
EXPECT_TRUE(image.premultiplied_alpha());
EXPECT_EQ(image.width(), 32);
EXPECT_EQ(image.height(), 50);
}
@@ -0,0 +1,42 @@
#include <gtest/gtest.h>
#include "olive/core/render/audioparams.h"
TEST(RenderAudioParams, ValidityAndEquality)
{
olive::core::AudioParams invalid;
EXPECT_FALSE(invalid.is_valid());
olive::core::AudioParams params(
48000, AV_CH_LAYOUT_STEREO, olive::core::SampleFormat::S16);
EXPECT_TRUE(params.is_valid());
olive::core::AudioParams other(
48000, AV_CH_LAYOUT_STEREO, olive::core::SampleFormat::S16);
EXPECT_TRUE(params == other);
other.set_sample_rate(44100);
EXPECT_TRUE(params != other);
}
TEST(RenderAudioParams, TimeAndSampleConversions)
{
olive::core::AudioParams params(
48000, AV_CH_LAYOUT_STEREO, olive::core::SampleFormat::S16);
EXPECT_EQ(params.channel_count(), 2);
EXPECT_EQ(params.bytes_per_sample_per_channel(), 2);
EXPECT_EQ(params.bits_per_sample(), 16);
EXPECT_EQ(params.time_to_samples(1.0), 48000);
EXPECT_EQ(params.time_to_bytes_per_channel(1.0), 96000);
EXPECT_EQ(params.time_to_bytes(1.0), 192000);
EXPECT_EQ(params.samples_to_bytes(48000), 192000);
EXPECT_EQ(params.samples_to_bytes_per_channel(48000), 96000);
EXPECT_EQ(params.bytes_to_samples(192000), 48000);
EXPECT_EQ(params.bytes_to_time(192000), olive::core::rational(1, 1));
EXPECT_EQ(params.bytes_per_channel_to_time(96000),
olive::core::rational(1, 1));
}
+28
View File
@@ -0,0 +1,28 @@
#include <gtest/gtest.h>
#include "olive/core/render/pixelformat.h"
TEST(RenderPixelFormat, ByteCountAndString)
{
using olive::core::PixelFormat;
EXPECT_EQ(PixelFormat::byte_count(PixelFormat::INVALID), 0);
EXPECT_EQ(PixelFormat::byte_count(PixelFormat::U8), 1);
EXPECT_EQ(PixelFormat::byte_count(PixelFormat::U16), 2);
EXPECT_EQ(PixelFormat::byte_count(PixelFormat::F16), 2);
EXPECT_EQ(PixelFormat::byte_count(PixelFormat::F32), 4);
EXPECT_EQ(PixelFormat(PixelFormat::U8).to_string(), std::string("u8"));
EXPECT_EQ(PixelFormat(PixelFormat::INVALID).to_string(), std::string(""));
}
TEST(RenderPixelFormat, FloatChecks)
{
using olive::core::PixelFormat;
EXPECT_FALSE(PixelFormat::is_float(PixelFormat::U8));
EXPECT_FALSE(PixelFormat::is_float(PixelFormat::U16));
EXPECT_TRUE(PixelFormat::is_float(PixelFormat::F16));
EXPECT_TRUE(PixelFormat::is_float(PixelFormat::F32));
EXPECT_FALSE(PixelFormat::is_float(PixelFormat::INVALID));
}
+29
View File
@@ -0,0 +1,29 @@
#include <gtest/gtest.h>
#include "olive/core/render/sampleformat.h"
TEST(RenderSampleFormat, ByteCountAndStringRoundTrip)
{
using olive::core::SampleFormat;
EXPECT_EQ(SampleFormat::byte_count(SampleFormat::INVALID), 0);
EXPECT_EQ(SampleFormat::byte_count(SampleFormat::U8), 1);
EXPECT_EQ(SampleFormat::byte_count(SampleFormat::S16), 2);
EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F32), 4);
EXPECT_EQ(SampleFormat::byte_count(SampleFormat::F64), 8);
EXPECT_EQ(SampleFormat::to_string(SampleFormat::S16), "s16");
EXPECT_EQ(SampleFormat::from_string("s16"), SampleFormat::S16);
EXPECT_EQ(SampleFormat::from_string(""), SampleFormat::INVALID);
EXPECT_EQ(SampleFormat::from_string("unknown"), SampleFormat::INVALID);
}
TEST(RenderSampleFormat, PackedAndPlanarChecks)
{
using olive::core::SampleFormat;
EXPECT_TRUE(SampleFormat::is_packed(SampleFormat::S16));
EXPECT_FALSE(SampleFormat::is_packed(SampleFormat::S16P));
EXPECT_TRUE(SampleFormat::is_planar(SampleFormat::S16P));
EXPECT_FALSE(SampleFormat::is_planar(SampleFormat::S16));
}
@@ -0,0 +1,84 @@
#include <gtest/gtest.h>
extern "C" {
#include <libavutil/avutil.h>
}
#include "render/videoparams.h"
TEST(RenderVideoParams, BytesPerChannelAndPixel)
{
EXPECT_EQ(olive::VideoParams::GetBytesPerChannel(
olive::core::PixelFormat::INVALID),
0);
EXPECT_EQ(olive::VideoParams::GetBytesPerChannel(
olive::core::PixelFormat::U8),
1);
EXPECT_EQ(olive::VideoParams::GetBytesPerChannel(
olive::core::PixelFormat::U16),
2);
EXPECT_EQ(olive::VideoParams::GetBytesPerChannel(
olive::core::PixelFormat::F16),
2);
EXPECT_EQ(olive::VideoParams::GetBytesPerChannel(
olive::core::PixelFormat::F32),
4);
EXPECT_EQ(olive::VideoParams::GetBytesPerPixel(
olive::core::PixelFormat::U8, 4),
4);
}
TEST(RenderVideoParams, DividerAndFormatNames)
{
EXPECT_EQ(olive::VideoParams::GetNameForDivider(1),
QStringLiteral("Full"));
EXPECT_EQ(olive::VideoParams::GetNameForDivider(3),
QStringLiteral("1/3"));
const QString unknown =
olive::VideoParams::GetFormatName(olive::core::PixelFormat::INVALID);
EXPECT_TRUE(unknown.contains(QStringLiteral("Unknown")));
}
TEST(RenderVideoParams, ScalingAndDividerForTarget)
{
EXPECT_EQ(olive::VideoParams::GetScaledDimension(100, 3), 33);
EXPECT_EQ(olive::VideoParams::GetDividerForTargetResolution(
1920, 1080, 960, 540),
2);
EXPECT_EQ(olive::VideoParams::GetDividerForTargetResolution(
1920, 1080, 480, 270),
4);
}
TEST(RenderVideoParams, FrameRateStringsAndPixelAspect)
{
const QString fps =
olive::VideoParams::FrameRateToString(olive::core::rational(24, 1));
EXPECT_TRUE(fps.contains(QStringLiteral("24")));
EXPECT_TRUE(fps.contains(QStringLiteral("FPS")));
const QStringList names =
olive::VideoParams::GetStandardPixelAspectRatioNames();
ASSERT_EQ(names.size(), 6);
EXPECT_TRUE(names.at(0).contains(QStringLiteral("1.0000")));
}
TEST(RenderVideoParams, ValidityAndTimebase)
{
olive::VideoParams params;
EXPECT_FALSE(params.is_valid());
EXPECT_EQ(params.get_time_in_timebase_units(olive::core::rational(1, 1)),
AV_NOPTS_VALUE);
params.set_width(1920);
params.set_height(1080);
params.set_format(olive::core::PixelFormat::U8);
params.set_channel_count(4);
params.set_pixel_aspect_ratio(olive::core::rational(1, 1));
params.set_time_base(olive::core::rational(1, 1));
params.set_start_time(10);
EXPECT_TRUE(params.is_valid());
EXPECT_EQ(params.get_time_in_timebase_units(olive::core::rational(2, 1)),
12);
}