Added a new cropSize property to the video element.

This commit is contained in:
Leon Styhre 2023-03-01 20:55:22 +01:00
parent b9a2a146b7
commit 95ef3b0555
5 changed files with 64 additions and 6 deletions

View file

@ -317,6 +317,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"video",
{{"pos", NORMALIZED_PAIR},
{"size", NORMALIZED_PAIR},
{"cropSize", NORMALIZED_PAIR},
{"maxSize", NORMALIZED_PAIR},
{"origin", NORMALIZED_PAIR},
{"path", PATH},

View file

@ -28,6 +28,8 @@ VideoComponent::VideoComponent()
, mTargetSize {0.0f, 0.0f}
, mVideoAreaPos {0.0f, 0.0f}
, mVideoAreaSize {0.0f, 0.0f}
, mTopLeftCrop {0.0f, 0.0f}
, mBottomRightCrop {1.0f, 1.0f}
, mPillarboxThreshold {0.85f, 0.90f}
, mStartTime {0}
, mIsPlaying {false}
@ -36,6 +38,7 @@ VideoComponent::VideoComponent()
, mMediaViewerMode {false}
, mScreensaverMode {false}
, mTargetIsMax {false}
, mTargetIsCrop {false}
, mPlayAudio {true}
, mDrawPillarboxes {true}
, mRenderScanlines {false}
@ -154,6 +157,13 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
setMaxSize(videoMaxSize * scale);
mVideoAreaSize = videoMaxSize * scale;
}
else if (elem->has("cropSize")) {
glm::vec2 videoCropSize {elem->get<glm::vec2>("cropSize")};
videoCropSize.x = glm::clamp(videoCropSize.x, 0.01f, 2.0f);
videoCropSize.y = glm::clamp(videoCropSize.y, 0.01f, 2.0f);
setCroppedSize(videoCropSize * scale);
mVideoAreaSize = videoCropSize * scale;
}
}
if (properties & ThemeFlags::POSITION) {
@ -302,8 +312,17 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mPillarboxThreshold.y = glm::clamp(pillarboxThreshold.y, 0.2f, 1.0f);
}
if (elem->has("scanlines"))
mRenderScanlines = elem->get<bool>("scanlines");
if (elem->has("scanlines")) {
if (elem->has("cropSize") && elem->get<bool>("scanlines")) {
LOG(LogWarning) << "VideoComponent: Invalid theme configuration, property "
"\"cropSize\" for element \""
<< element.substr(6)
<< "\" can't be combined with the \"scanlines\" property";
}
else {
mRenderScanlines = elem->get<bool>("scanlines");
}
}
if (elem->has("scrollFadeIn") && elem->get<bool>("scrollFadeIn"))
mComponentThemeFlags |= ComponentThemeFlags::SCROLL_FADE_IN;

View file

@ -83,6 +83,8 @@ public:
// Never breaks the aspect ratio. setMaxSize() and setResize() are mutually exclusive.
virtual void setMaxSize(float width, float height) = 0;
void setMaxSize(const glm::vec2& size) { setMaxSize(size.x, size.y); }
// Resize and crop the video so it fills the entire area.
virtual void setCroppedSize(const glm::vec2& size) = 0;
// Basic video controls.
void startVideoPlayer();
@ -109,6 +111,8 @@ protected:
glm::vec2 mTargetSize;
glm::vec2 mVideoAreaPos;
glm::vec2 mVideoAreaSize;
glm::vec2 mTopLeftCrop;
glm::vec2 mBottomRightCrop;
glm::vec2 mPillarboxThreshold;
std::shared_ptr<TextureResource> mTexture;
std::string mStaticImagePath;
@ -126,6 +130,7 @@ protected:
bool mMediaViewerMode;
bool mScreensaverMode;
bool mTargetIsMax;
bool mTargetIsCrop;
bool mPlayAudio;
bool mDrawPillarboxes;
bool mRenderScanlines;

View file

@ -66,6 +66,7 @@ void VideoFFmpegComponent::setResize(const float width, const float height)
// This resize function is used when stretching videos to full screen in the video screensaver.
mTargetSize = glm::vec2 {width, height};
mTargetIsMax = false;
mTargetIsCrop = false;
mStaticImage.setResize(mTargetSize);
resize();
}
@ -76,10 +77,20 @@ void VideoFFmpegComponent::setMaxSize(float width, float height)
// and the gamelist videos.
mTargetSize = glm::vec2 {width, height};
mTargetIsMax = true;
mTargetIsCrop = false;
mStaticImage.setMaxSize(width, height);
resize();
}
void VideoFFmpegComponent::setCroppedSize(const glm::vec2& size)
{
mTargetSize = size;
mTargetIsMax = false;
mTargetIsCrop = true;
mStaticImage.setCroppedSize(size);
resize();
}
void VideoFFmpegComponent::resize()
{
if (!mTexture)
@ -106,6 +117,25 @@ void VideoFFmpegComponent::resize()
mSize.x = (mSize.y / textureSize.y) * textureSize.x;
}
else if (mTargetIsCrop) {
// Size texture to allow for cropped video to fill the entire area.
const float cropFactor {
std::max(mTargetSize.x / textureSize.x, mTargetSize.y / textureSize.y)};
mSize = textureSize * cropFactor;
if (std::round(mSize.y) > std::round(mTargetSize.y)) {
const float cropSize {1.0f - (mTargetSize.y / mSize.y)};
mTopLeftCrop.y = cropSize / 2.0f;
mBottomRightCrop.y = 1.0f - (cropSize / 2.0f);
mSize.y = mSize.y - (mSize.y * cropSize);
}
else {
const float cropSize {1.0f - (mTargetSize.x / mSize.x)};
mTopLeftCrop.x = cropSize / 2.0f;
mBottomRightCrop.x = 1.0f - (cropSize / 2.0f);
mSize.x = mSize.x - (mSize.x * cropSize);
}
}
else {
// If both components are set, we just stretch.
// If no components are set, we don't resize at all.
@ -159,10 +189,10 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
return;
// clang-format off
vertices[0] = {{0.0f + mRectangleOffset.x, 0.0f + mRectangleOffset.y }, {0.0f, 0.0f}, 0xFFFFFFFF};
vertices[1] = {{0.0f + mRectangleOffset.x, mSize.y + mRectangleOffset.y }, {0.0f, 1.0f}, 0xFFFFFFFF};
vertices[2] = {{mSize.x + mRectangleOffset.x, 0.0f + + mRectangleOffset.y }, {1.0f, 0.0f}, 0xFFFFFFFF};
vertices[3] = {{mSize.x + mRectangleOffset.x, mSize.y + + mRectangleOffset.y}, {1.0f, 1.0f}, 0xFFFFFFFF};
vertices[0] = {{0.0f + mRectangleOffset.x, 0.0f + mRectangleOffset.y }, {mTopLeftCrop.x, 1.0f - mBottomRightCrop.y}, 0xFFFFFFFF};
vertices[1] = {{0.0f + mRectangleOffset.x, mSize.y + mRectangleOffset.y }, {mTopLeftCrop.x, 1.0f - mTopLeftCrop.y }, 0xFFFFFFFF};
vertices[2] = {{mSize.x + mRectangleOffset.x, 0.0f + + mRectangleOffset.y }, {mBottomRightCrop.x * 1.0f, 1.0f - mBottomRightCrop.y}, 0xFFFFFFFF};
vertices[3] = {{mSize.x + mRectangleOffset.x, mSize.y + + mRectangleOffset.y}, {mBottomRightCrop.x * 1.0f, 1.0f - mTopLeftCrop.y }, 0xFFFFFFFF};
// clang-format on
vertices[0].color = mColorShift;

View file

@ -46,6 +46,9 @@ public:
// This can be set before or after a video is loaded.
// Never breaks the aspect ratio. setMaxSize() and setResize() are mutually exclusive.
void setMaxSize(float width, float height) override;
// Resize and crop the video so it fills the entire area.
void setCroppedSize(const glm::vec2& size) override;
// Basic video controls.
void stopVideoPlayer(bool muteAudio = true) override;
void pauseVideoPlayer() override;