Use TouchGFX
This commit is contained in:
@ -0,0 +1,171 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2018(-2023) STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of the TouchGFX 4.21.2 distribution.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file in
|
||||
* the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include <touchgfx/Application.hpp>
|
||||
#include <touchgfx/Utils.hpp>
|
||||
#include <touchgfx/hal/HAL.hpp>
|
||||
#include <touchgfx/widgets/VideoWidget.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
VideoWidget::VideoWidget()
|
||||
: Widget(),
|
||||
movieEndedAction(0), buffer(0), format(Bitmap::RGB888),
|
||||
bufferWidth(0), bufferHeight(0), videoWidth(0), videoHeight(0)
|
||||
{
|
||||
handle = VideoController::getInstance().registerVideoWidget(*this);
|
||||
Application::getInstance()->registerTimerWidget(this);
|
||||
}
|
||||
|
||||
VideoWidget::~VideoWidget()
|
||||
{
|
||||
VideoController::getInstance().unregisterVideoWidget(handle);
|
||||
Application::getInstance()->unregisterTimerWidget(this);
|
||||
}
|
||||
|
||||
void VideoWidget::play() const
|
||||
{
|
||||
VideoController::getInstance().setCommand(handle, VideoController::PLAY, 0);
|
||||
}
|
||||
|
||||
void VideoWidget::pause() const
|
||||
{
|
||||
VideoController::getInstance().setCommand(handle, VideoController::PAUSE, 0);
|
||||
}
|
||||
|
||||
void VideoWidget::stop() const
|
||||
{
|
||||
VideoController::getInstance().setCommand(handle, VideoController::STOP, 0);
|
||||
}
|
||||
|
||||
bool VideoWidget::isPlaying() const
|
||||
{
|
||||
return VideoController::getInstance().getIsPlaying(handle);
|
||||
}
|
||||
|
||||
void VideoWidget::seek(uint32_t frameNumber) const
|
||||
{
|
||||
VideoController::getInstance().setCommand(handle, VideoController::SEEK, frameNumber);
|
||||
}
|
||||
|
||||
void VideoWidget::showFrame(uint32_t frameNumber) const
|
||||
{
|
||||
if (isPlaying())
|
||||
{
|
||||
seek(frameNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
VideoController::getInstance().setCommand(handle, VideoController::SHOW, frameNumber);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::setRepeat(bool repeat) const
|
||||
{
|
||||
VideoController::getInstance().setCommand(handle, VideoController::SET_REPEAT, repeat ? 1 : 0);
|
||||
}
|
||||
|
||||
void VideoWidget::handleTickEvent()
|
||||
{
|
||||
const bool hasMoreFrames = VideoController::getInstance().updateFrame(handle, *this);
|
||||
if (!hasMoreFrames)
|
||||
{
|
||||
// Now showing last frame
|
||||
if (movieEndedAction && movieEndedAction->isValid())
|
||||
{
|
||||
movieEndedAction->execute(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rect VideoWidget::getSolidRect() const
|
||||
{
|
||||
// For Dedicated or DoubleBuffered video we have a bufferWidth > 0
|
||||
// But maybe no buffer yet (only after decoding first frame)
|
||||
if (bufferWidth > 0)
|
||||
{
|
||||
// Solid inside video area if we have a buffer, otherwise transparent
|
||||
if (buffer != 0)
|
||||
{
|
||||
return Rect(0, 0, MIN(videoWidth, bufferWidth), MIN(videoHeight, bufferHeight));
|
||||
}
|
||||
return Rect();
|
||||
}
|
||||
|
||||
//Direct to framebuffer, solid inside the video area
|
||||
return Rect(0, 0, videoWidth, videoHeight);
|
||||
}
|
||||
|
||||
void VideoWidget::draw(const Rect& invalidatedArea) const
|
||||
{
|
||||
// Only draw the invalidated area inside the video x buffer
|
||||
Rect invVideoRect(0, 0, videoWidth, videoHeight);
|
||||
invVideoRect &= invalidatedArea;
|
||||
|
||||
// Inform controller that we are drawing
|
||||
VideoController::getInstance().draw(handle, invVideoRect, *this);
|
||||
|
||||
// If we have a buffer, draw that
|
||||
if (buffer != 0)
|
||||
{
|
||||
// Limit to buffer size
|
||||
invVideoRect &= Rect(0, 0, bufferWidth, bufferHeight);
|
||||
|
||||
// Convert to lcd coordinates. Width is buffer stride.
|
||||
Rect absolute = getAbsoluteRect();
|
||||
absolute.width = bufferWidth;
|
||||
// Copy to LCD, always solid
|
||||
HAL::lcd().blitCopy(buffer, format, absolute, invVideoRect, 255, false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t VideoWidget::getCurrentFrameNumber() const
|
||||
{
|
||||
return VideoController::getInstance().getCurrentFrameNumber(handle);
|
||||
}
|
||||
|
||||
void VideoWidget::setFrameRate(uint32_t ui_frames, uint32_t video_frames) const
|
||||
{
|
||||
VideoController::getInstance().setFrameRate(handle, ui_frames, video_frames);
|
||||
}
|
||||
|
||||
void VideoWidget::setVideoData(const uint8_t* movie, const uint32_t length)
|
||||
{
|
||||
VideoController::getInstance().setVideoData(handle, movie, length);
|
||||
|
||||
readVideoInformation();
|
||||
}
|
||||
|
||||
void VideoWidget::setVideoData(VideoDataReader& reader)
|
||||
{
|
||||
VideoController::getInstance().setVideoData(handle, reader);
|
||||
|
||||
readVideoInformation();
|
||||
}
|
||||
|
||||
void VideoWidget::getVideoInformation(VideoInformation* data) const
|
||||
{
|
||||
VideoController::getInstance().getVideoInformation(handle, data);
|
||||
}
|
||||
|
||||
void VideoWidget::readVideoInformation()
|
||||
{
|
||||
// Set frame rate to movie speed (assuming 60 ui frames in a second)
|
||||
VideoInformation videoInformation;
|
||||
VideoController::getInstance().getVideoInformation(handle, &videoInformation);
|
||||
videoWidth = (int16_t)videoInformation.frame_width;
|
||||
videoHeight = (int16_t)videoInformation.frame_height;
|
||||
uint32_t videoFramesIn1000ms = 1000 / videoInformation.ms_between_frames;
|
||||
setFrameRate(60, videoFramesIn1000ms);
|
||||
}
|
||||
|
||||
} // namespace touchgfx
|
||||
Reference in New Issue
Block a user