Revision control
Copy as Markdown
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtFFmpegMediaPluginImpl/private/qandroidvideoframefactory_p.h>
#include <QtMultimedia/qvideoframe.h>
QT_BEGIN_NAMESPACE
namespace {
// This is due to a limitation of ImageReader. When limit is reached, we cannot acquire more frames
// until we close any of the previous image. That is why, When the limit is reached, we will do
// a copy of the frame data and immediately close the image.
constexpr int NATIVE_FRAME_LIMIT = 10;
}
QVideoFrame QAndroidVideoFrameFactory::createVideoFrame(QtJniTypes::Image frame,
QtVideo::Rotation rotation)
{
const int currentCounter = m_framesCounter.fetch_add(1, std::memory_order_relaxed) + 1;
auto frameAdapter = std::make_unique<QAndroidVideoFrameBuffer>(
frame,
shared_from_this(),
currentCounter > NATIVE_FRAME_LIMIT ?
QAndroidVideoFrameBuffer::MemoryPolicy::Copy
: QAndroidVideoFrameBuffer::MemoryPolicy::Reuse,
rotation);
if (!frameAdapter->isParsed())
return QVideoFrame{};
const qint64 currentTimeStamp = frameAdapter->timestamp();
QVideoFrame videoFrame(std::move(frameAdapter));
if (m_lastTimestamp == 0)
m_lastTimestamp = currentTimeStamp;
videoFrame.setStartTime(m_lastTimestamp);
videoFrame.setEndTime(currentTimeStamp);
m_lastTimestamp = currentTimeStamp;
return videoFrame;
}
void QAndroidVideoFrameFactory::onFrameReleased()
{
const int currentCounter = m_framesCounter.fetch_sub(1, std::memory_order_relaxed);
Q_ASSERT(currentCounter >= 0);
}
QT_END_NAMESPACE