8#include <QtCore/qloggingcategory.h>
23 AVPixelFormat ffmpegPixelFormat =
24 hwFormat && *hwFormat != AV_PIX_FMT_NONE ? *hwFormat : swFormat;
39 recordingEngine.avFormatContext());
46 return m_frameEncoder !=
nullptr;
59 const bool queueFull = m_videoFrameQueue.size() >= m_maxQueueSize;
62 qCDebug(qLcFFmpegVideoEncoder) <<
"RecordingEngine frame queue full. Frame lost.";
66 m_videoFrameQueue.push(
frame);
78void VideoEncoder::retrievePackets()
82 while (
auto packet = m_frameEncoder->retrievePacket())
90 qCDebug(qLcFFmpegVideoEncoder) <<
"VideoEncoder::init started video device thread.";
91 bool ok = m_frameEncoder->open();
94 "Could not initialize encoder");
99 while (!m_videoFrameQueue.empty())
101 if (m_frameEncoder) {
102 while (m_frameEncoder->sendFrame(
nullptr) == AVERROR(EAGAIN))
110 return !m_videoFrameQueue.empty();
128 auto frame = takeFrame();
129 if (!
frame.isValid())
143 if (hwFrame && hwFrame->format == m_frameEncoder->sourceFormat())
144 avFrame.reset(av_frame_clone(hwFrame));
151 avFrame->format = m_frameEncoder->sourceFormat();
152 avFrame->width =
size.width();
153 avFrame->height =
size.height();
155 for (
int i = 0;
i < 4; ++
i) {
156 avFrame->data[
i] =
const_cast<uint8_t *
>(
frame.bits(
i));
157 avFrame->linesize[
i] =
frame.bytesPerLine(
i);
165 avFrame->data[0] = (uint8_t *)
img.bits();
166 avFrame->linesize[0] =
img.bytesPerLine();
175 if (m_baseTime.
loadAcquire() == std::numeric_limits<qint64>::min()) {
177 qCDebug(qLcFFmpegVideoEncoder) <<
">>>> adjusting base time to" << m_baseTime.
loadAcquire()
178 <<
frame.startTime() << m_lastFrameTime;
184 setAVFrameTime(*avFrame, m_frameEncoder->getPts(
time), m_frameEncoder->getTimeBase());
189 <<
">>> sending frame" << avFrame->pts <<
time << m_lastFrameTime;
190 int ret = m_frameEncoder->sendFrame(std::move(avFrame));
200 return m_videoFrameQueue.size() < m_maxQueueSize;
202 return m_videoFrameQueue.empty();
T loadAcquire() const noexcept
void storeRelease(T newValue) noexcept
static AVPixelFormat toAVPixelFormat(QVideoFrameFormat::PixelFormat pixelFormat)
AVFrame * getHWFrame() const
void dataReady()
Wake thread from sleep and process data until hasData() returns false.
RecordingEngine & m_recordingEngine
void addPacket(AVPacketUPtr packet)
void newTimeStamp(qint64 time)
void sessionError(QMediaRecorder::Error code, const QString &description)
bool checkIfCanPushFrame() const override
void init() override
Called on this thread when thread starts.
void processOne() override
Process one work item.
void cleanup() override
Called on this thread before thread exits.
void addFrame(const QVideoFrame &frame)
bool hasData() const override
Must return true when data is available for processing.
VideoEncoder(RecordingEngine &recordingEngine, const QMediaEncoderSettings &settings, const QVideoFrameFormat &format, std::optional< AVPixelFormat > hwFormat)
static std::unique_ptr< VideoFrameEncoder > create(const QMediaEncoderSettings &encoderSettings, const QSize &sourceSize, QtVideo::Rotation sourceRotation, qreal sourceFrameRate, AVPixelFormat sourceFormat, AVPixelFormat sourceSWFormat, AVFormatContext *formatContext)
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
The QVideoFrame class represents a frame of video data.
AVFrameUPtr makeAVFrame()
QString err2str(int errnum)
void setAVFrameTime(AVFrame &frame, int64_t pts, const AVRational &timeBase)
static void freeQVideoFrame(void *opaque, uint8_t *)
std::unique_ptr< AVFrame, AVDeleter< decltype(&av_frame_free), &av_frame_free > > AVFrameUPtr
T dequeueIfPossible(std::queue< T > &queue)
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum format
QLatin1StringView QLatin1String
QSettings settings("MySoft", "Star Runner")
[0]