summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2023-07-31 16:07:22 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-08-02 10:33:28 +0000
commit0562c1112ce30a6e9ea842722eb236e0b5fa1265 (patch)
tree8d246ff33e5e772b07d48ac166a9b2eb4857c7d8
parent106ef9957c284870fd8d991b639f97fac2c1739c (diff)
Move VideoFrameEncoder::Data members to VideoFrameEncoder
Dynamically allocated VideoFrameEncoder::Data is not need for this case, let's simplify and move all members to the class. Change-Id: I7bfa8f6a92ba0a449dd84843109b1344c86ad5bd Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> (cherry picked from commit 87adcdcf6ffa7d026b22917249fbbee1e5fd1dfd) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp17
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegencoder_p.h10
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder.cpp264
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder_p.h58
4 files changed, 175 insertions, 174 deletions
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp b/src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp
index 902daa5ad..cd0e040bb 100644
--- a/src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp
+++ b/src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp
@@ -495,13 +495,15 @@ VideoEncoder::VideoEncoder(Encoder *encoder, const QMediaEncoderSettings &settin
frameRate = 30.;
}
- frameEncoder = new VideoFrameEncoder(settings, format.frameSize(), frameRate, ffmpegPixelFormat,
- swFormat, encoder->formatContext);
+ frameEncoder = VideoFrameEncoder::create(settings, format.frameSize(), frameRate,
+ ffmpegPixelFormat, swFormat, encoder->formatContext);
}
-VideoEncoder::~VideoEncoder()
+VideoEncoder::~VideoEncoder() = default;
+
+bool VideoEncoder::isValid() const
{
- delete frameEncoder;
+ return frameEncoder != nullptr;
}
void VideoEncoder::addFrame(const QVideoFrame &frame)
@@ -522,11 +524,6 @@ void VideoEncoder::addFrame(const QVideoFrame &frame)
}
}
-bool VideoEncoder::isValid() const
-{
- return !frameEncoder->isNull();
-}
-
QVideoFrame VideoEncoder::takeFrame()
{
QMutexLocker locker(&queueMutex);
@@ -588,7 +585,7 @@ void VideoEncoder::loop()
if (!frame.isValid())
return;
- if (frameEncoder->isNull())
+ if (!isValid())
return;
// qCDebug(qLcFFmpegEncoder) << "new video buffer" << frame.startTime();
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegencoder_p.h b/src/plugins/multimedia/ffmpeg/qffmpegencoder_p.h
index 36471ac98..a2b64c09a 100644
--- a/src/plugins/multimedia/ffmpeg/qffmpegencoder_p.h
+++ b/src/plugins/multimedia/ffmpeg/qffmpegencoder_p.h
@@ -18,9 +18,12 @@
#include "qffmpeg_p.h"
#include "qffmpeghwaccel_p.h"
+#include "private/qmultimediautils_p.h"
+
#include <private/qplatformmediarecorder_p.h>
#include <qaudioformat.h>
#include <qaudiobuffer.h>
+#include <qmediarecorder.h>
#include <queue>
@@ -165,7 +168,6 @@ private:
QMediaEncoderSettings settings;
};
-
class VideoEncoder : public EncoderThread
{
mutable QMutex queueMutex;
@@ -177,10 +179,10 @@ public:
const QVideoFrameFormat &format, std::optional<AVPixelFormat> hwFormat);
~VideoEncoder() override;
- void addFrame(const QVideoFrame &frame);
-
bool isValid() const;
+ void addFrame(const QVideoFrame &frame);
+
void setPaused(bool b) override
{
EncoderThread::setPaused(b);
@@ -197,7 +199,7 @@ private:
bool shouldWait() const override;
void loop() override;
- VideoFrameEncoder *frameEncoder = nullptr;
+ std::unique_ptr<VideoFrameEncoder> frameEncoder;
QAtomicInteger<qint64> baseTime = std::numeric_limits<qint64>::min();
qint64 lastFrameTime = 0;
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder.cpp b/src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder.cpp
index fa596e276..6ef0b25bc 100644
--- a/src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder.cpp
+++ b/src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder.cpp
@@ -16,62 +16,71 @@ static Q_LOGGING_CATEGORY(qLcVideoFrameEncoder, "qt.multimedia.ffmpeg.videoencod
namespace QFFmpeg {
-VideoFrameEncoder::VideoFrameEncoder(const QMediaEncoderSettings &encoderSettings,
- const QSize &sourceSize, qreal sourceFrameRate,
- AVPixelFormat sourceFormat, AVPixelFormat sourceSWFormat,
- AVFormatContext *formatContext)
- : d(new Data)
+std::unique_ptr<VideoFrameEncoder>
+VideoFrameEncoder::create(const QMediaEncoderSettings &encoderSettings, const QSize &sourceSize,
+ qreal sourceFrameRate, AVPixelFormat sourceFormat,
+ AVPixelFormat sourceSWFormat, AVFormatContext *formatContext)
{
Q_ASSERT(isSwPixelFormat(sourceSWFormat));
Q_ASSERT(isHwPixelFormat(sourceFormat) || sourceSWFormat == sourceFormat);
- d->settings = encoderSettings;
- d->sourceSize = sourceSize;
+ std::unique_ptr<VideoFrameEncoder> result(new VideoFrameEncoder);
- if (!d->settings.videoResolution().isValid())
- d->settings.setVideoResolution(d->sourceSize);
+ result->m_settings = encoderSettings;
+ result->m_sourceSize = sourceSize;
+ result->m_sourceFormat = sourceFormat;
+ result->m_sourceSWFormat = sourceSWFormat;
- if (d->settings.videoFrameRate() <= 0.)
- d->settings.setVideoFrameRate(sourceFrameRate);
+ if (!result->m_settings.videoResolution().isValid())
+ result->m_settings.setVideoResolution(sourceSize);
- d->sourceFormat = sourceFormat;
- d->sourceSWFormat = sourceSWFormat;
+ if (result->m_settings.videoFrameRate() <= 0.)
+ result->m_settings.setVideoFrameRate(sourceFrameRate);
- if (!initCodec() || !initTargetFormats() || !initCodecContext(formatContext)) {
- d = {};
- return;
+ if (!result->initCodec() || !result->initTargetFormats()
+ || !result->initCodecContext(formatContext)) {
+ return nullptr;
}
- updateConversions();
+ // TODO: make VideoFrameEncoder::private and do openning here
+ // if (!open()) {
+ // m_error = QMediaRecorder::FormatError;
+ // m_errorStr = QLatin1StringView("Cannot open codec");
+ // return;
+ // }
+
+ result->updateConversions();
+
+ return result;
}
bool VideoFrameEncoder::initCodec()
{
- const auto qVideoCodec = d->settings.videoCodec();
+ const auto qVideoCodec = m_settings.videoCodec();
const auto codecID = QFFmpegMediaFormatInfo::codecIdForVideoCodec(qVideoCodec);
- const auto resolution = d->settings.videoResolution();
+ const auto resolution = m_settings.videoResolution();
- std::tie(d->codec, d->accel) = findHwEncoder(codecID, resolution);
+ std::tie(m_codec, m_accel) = findHwEncoder(codecID, resolution);
- if (!d->codec)
- d->codec = findSwEncoder(codecID, d->sourceSWFormat);
+ if (!m_codec)
+ m_codec = findSwEncoder(codecID, m_sourceSWFormat);
- if (!d->codec) {
+ if (!m_codec) {
qWarning() << "Could not find encoder for codecId" << codecID;
return false;
}
- qCDebug(qLcVideoFrameEncoder) << "found encoder" << d->codec->name << "for id" << d->codec->id;
+ qCDebug(qLcVideoFrameEncoder) << "found encoder" << m_codec->name << "for id" << m_codec->id;
#ifdef Q_OS_WINDOWS
// TODO: investigate, there might be more encoders not supporting odd resolution
- if (strcmp(d->codec->name, "h264_mf") == 0) {
+ if (strcmp(m_codec->name, "h264_mf") == 0) {
auto makeEven = [](int size) { return size & ~1; };
const QSize fixedResolution(makeEven(resolution.width()), makeEven(resolution.height()));
if (fixedResolution != resolution) {
- qCDebug(qLcVideoFrameEncoder) << "Fix odd video resolution for codec" << d->codec->name << ":"
- << resolution << "->" << fixedResolution;
- d->settings.setVideoResolution(fixedResolution);
+ qCDebug(qLcVideoFrameEncoder) << "Fix odd video resolution for codec" << m_codec->name
+ << ":" << resolution << "->" << fixedResolution;
+ m_settings.setVideoResolution(fixedResolution);
}
}
#endif
@@ -81,30 +90,29 @@ bool VideoFrameEncoder::initCodec()
bool VideoFrameEncoder::initTargetFormats()
{
- d->targetFormat =
- findTargetFormat(d->sourceFormat, d->sourceSWFormat, d->codec, d->accel.get());
+ m_targetFormat = findTargetFormat(m_sourceFormat, m_sourceSWFormat, m_codec, m_accel.get());
- if (d->targetFormat == AV_PIX_FMT_NONE) {
- qWarning() << "Could not find target format for codecId" << d->codec->id;
+ if (m_targetFormat == AV_PIX_FMT_NONE) {
+ qWarning() << "Could not find target format for codecId" << m_codec->id;
return false;
}
- Q_ASSERT(isHwPixelFormat(d->targetFormat) == !!d->accel);
+ Q_ASSERT(isHwPixelFormat(m_targetFormat) == !!m_accel);
- if (d->accel) {
- d->targetSWFormat = findTargetSWFormat(d->sourceSWFormat, d->codec, *d->accel);
+ if (m_accel) {
+ m_targetSWFormat = findTargetSWFormat(m_sourceSWFormat, m_codec, *m_accel);
- if (d->targetSWFormat == AV_PIX_FMT_NONE) {
- qWarning() << "Cannot find software target format. sourceSWFormat:" << d->sourceSWFormat
- << "targetFormat:" << d->targetFormat;
+ if (m_targetSWFormat == AV_PIX_FMT_NONE) {
+ qWarning() << "Cannot find software target format. sourceSWFormat:" << m_sourceSWFormat
+ << "targetFormat:" << m_targetFormat;
return false;
}
- d->accel->createFramesContext(d->targetSWFormat, d->settings.videoResolution());
- if (!d->accel->hwFramesContextAsBuffer())
+ m_accel->createFramesContext(m_targetSWFormat, m_settings.videoResolution());
+ if (!m_accel->hwFramesContextAsBuffer())
return false;
} else {
- d->targetSWFormat = d->targetFormat;
+ m_targetSWFormat = m_targetFormat;
}
return true;
@@ -114,33 +122,33 @@ VideoFrameEncoder::~VideoFrameEncoder() = default;
bool QFFmpeg::VideoFrameEncoder::initCodecContext(AVFormatContext *formatContext)
{
- d->stream = avformat_new_stream(formatContext, nullptr);
- d->stream->id = formatContext->nb_streams - 1;
+ m_stream = avformat_new_stream(formatContext, nullptr);
+ m_stream->id = formatContext->nb_streams - 1;
//qCDebug(qLcVideoFrameEncoder) << "Video stream: index" << d->stream->id;
- d->stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
- d->stream->codecpar->codec_id = d->codec->id;
+ m_stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+ m_stream->codecpar->codec_id = m_codec->id;
// Apples HEVC decoders don't like the hev1 tag ffmpeg uses by default, use hvc1 as the more commonly accepted tag
- if (d->codec->id == AV_CODEC_ID_HEVC)
- d->stream->codecpar->codec_tag = MKTAG('h','v','c','1');
+ if (m_codec->id == AV_CODEC_ID_HEVC)
+ m_stream->codecpar->codec_tag = MKTAG('h', 'v', 'c', '1');
- const auto resolution = d->settings.videoResolution();
+ const auto resolution = m_settings.videoResolution();
// ### Fix hardcoded values
- d->stream->codecpar->format = d->targetFormat;
- d->stream->codecpar->width = resolution.width();
- d->stream->codecpar->height = resolution.height();
- d->stream->codecpar->sample_aspect_ratio = AVRational{1, 1};
- float requestedRate = d->settings.videoFrameRate();
+ m_stream->codecpar->format = m_targetFormat;
+ m_stream->codecpar->width = resolution.width();
+ m_stream->codecpar->height = resolution.height();
+ m_stream->codecpar->sample_aspect_ratio = AVRational{ 1, 1 };
+ float requestedRate = m_settings.videoFrameRate();
constexpr int TimeScaleFactor = 1000; // Allows not to follow fixed rate
- d->stream->time_base = AVRational{ 1, static_cast<int>(requestedRate * TimeScaleFactor) };
+ m_stream->time_base = AVRational{ 1, static_cast<int>(requestedRate * TimeScaleFactor) };
float delta = 1e10;
- if (d->codec->supported_framerates) {
+ if (m_codec->supported_framerates) {
// codec only supports fixed frame rates
- auto *best = d->codec->supported_framerates;
+ auto *best = m_codec->supported_framerates;
qCDebug(qLcVideoFrameEncoder) << "Finding fixed rate:";
- for (auto *f = d->codec->supported_framerates; f->num != 0; f++) {
+ for (auto *f = m_codec->supported_framerates; f->num != 0; f++) {
auto maybeRate = toFloat(*f);
if (!maybeRate)
continue;
@@ -152,34 +160,35 @@ bool QFFmpeg::VideoFrameEncoder::initCodecContext(AVFormatContext *formatContext
}
}
qCDebug(qLcVideoFrameEncoder) << "Fixed frame rate required. Requested:" << requestedRate << "Using:" << best->num << "/" << best->den;
- d->stream->time_base = *best;
+ m_stream->time_base = *best;
requestedRate = toFloat(*best).value_or(0.f);
}
- Q_ASSERT(d->codec);
- d->codecContext.reset(avcodec_alloc_context3(d->codec));
- if (!d->codecContext) {
+ Q_ASSERT(m_codec);
+ m_codecContext.reset(avcodec_alloc_context3(m_codec));
+ if (!m_codecContext) {
qWarning() << "Could not allocate codec context";
return false;
}
- avcodec_parameters_to_context(d->codecContext.get(), d->stream->codecpar);
- d->codecContext->time_base = d->stream->time_base;
- qCDebug(qLcVideoFrameEncoder) << "requesting time base" << d->codecContext->time_base.num << d->codecContext->time_base.den;
+ avcodec_parameters_to_context(m_codecContext.get(), m_stream->codecpar);
+ m_codecContext->time_base = m_stream->time_base;
+ qCDebug(qLcVideoFrameEncoder) << "requesting time base" << m_codecContext->time_base.num
+ << m_codecContext->time_base.den;
auto [num, den] = qRealToFraction(requestedRate);
- d->codecContext->framerate = { num, den };
- d->codecContext->pix_fmt = d->targetFormat;
- d->codecContext->width = resolution.width();
- d->codecContext->height = resolution.height();
+ m_codecContext->framerate = { num, den };
+ m_codecContext->pix_fmt = m_targetFormat;
+ m_codecContext->width = resolution.width();
+ m_codecContext->height = resolution.height();
- if (d->accel) {
- auto deviceContext = d->accel->hwDeviceContextAsBuffer();
+ if (m_accel) {
+ auto deviceContext = m_accel->hwDeviceContextAsBuffer();
Q_ASSERT(deviceContext);
- d->codecContext->hw_device_ctx = av_buffer_ref(deviceContext);
+ m_codecContext->hw_device_ctx = av_buffer_ref(deviceContext);
- auto framesContext = d->accel->hwFramesContextAsBuffer();
+ auto framesContext = m_accel->hwFramesContextAsBuffer();
Q_ASSERT(deviceContext);
- d->codecContext->hw_frames_ctx = av_buffer_ref(framesContext);
+ m_codecContext->hw_frames_ctx = av_buffer_ref(framesContext);
}
return true;
@@ -187,55 +196,54 @@ bool QFFmpeg::VideoFrameEncoder::initCodecContext(AVFormatContext *formatContext
bool VideoFrameEncoder::open()
{
- if (!d) {
- qWarning() << "Cannot open null VideoFrameEncoder";
+ if (!m_codecContext)
return false;
- }
+
AVDictionaryHolder opts;
- applyVideoEncoderOptions(d->settings, d->codec->name, d->codecContext.get(), opts);
- int res = avcodec_open2(d->codecContext.get(), d->codec, opts);
+ applyVideoEncoderOptions(m_settings, m_codec->name, m_codecContext.get(), opts);
+ int res = avcodec_open2(m_codecContext.get(), m_codec, opts);
if (res < 0) {
- d->codecContext.reset();
+ m_codecContext.reset();
qWarning() << "Couldn't open codec for writing" << err2str(res);
return false;
}
- qCDebug(qLcVideoFrameEncoder) << "video codec opened" << res << "time base" << d->codecContext->time_base.num << d->codecContext->time_base.den;
- d->stream->time_base = d->stream->time_base;
+ qCDebug(qLcVideoFrameEncoder) << "video codec opened" << res << "time base"
+ << m_codecContext->time_base.num << m_codecContext->time_base.den;
+ m_stream->time_base = m_stream->time_base;
return true;
}
qint64 VideoFrameEncoder::getPts(qint64 us) const
{
- Q_ASSERT(d);
- qint64 div = 1'000'000 * d->stream->time_base.num;
- return div != 0 ? (us * d->stream->time_base.den + div / 2) / div : 0;
+ qint64 div = 1'000'000 * m_stream->time_base.num;
+ return div != 0 ? (us * m_stream->time_base.den + div / 2) / div : 0;
}
const AVRational &VideoFrameEncoder::getTimeBase() const
{
- return d->stream->time_base;
+ return m_stream->time_base;
}
int VideoFrameEncoder::sendFrame(AVFrameUPtr frame)
{
- if (!d || !d->codecContext) {
+ if (!m_codecContext) {
qWarning() << "codec context is not initialized!";
return AVERROR(EINVAL);
}
if (!frame)
- return avcodec_send_frame(d->codecContext.get(), frame.get());
+ return avcodec_send_frame(m_codecContext.get(), frame.get());
- if (frame->format != d->sourceFormat) {
- qWarning() << "Frame format has changed:" << d->sourceFormat << "->" << frame->format;
+ if (frame->format != m_sourceFormat) {
+ qWarning() << "Frame format has changed:" << m_sourceFormat << "->" << frame->format;
return AVERROR(EINVAL);
}
const QSize frameSize(frame->width, frame->height);
- if (frameSize != d->sourceSize) {
+ if (frameSize != m_sourceSize) {
qCDebug(qLcVideoFrameEncoder) << "Update conversions on the fly. Source size"
- << d->sourceSize << "->" << frameSize;
- d->sourceSize = frameSize;
+ << m_sourceSize << "->" << frameSize;
+ m_sourceSize = frameSize;
updateConversions();
}
@@ -243,7 +251,7 @@ int VideoFrameEncoder::sendFrame(AVFrameUPtr frame)
AVRational timeBase = {};
getAVFrameTime(*frame, pts, timeBase);
- if (d->downloadFromHW) {
+ if (m_downloadFromHW) {
auto f = makeAVFrame();
int err = av_hwframe_transfer_data(f.get(), frame.get(), 0);
@@ -255,15 +263,15 @@ int VideoFrameEncoder::sendFrame(AVFrameUPtr frame)
frame = std::move(f);
}
- if (d->converter) {
+ if (m_converter) {
auto f = makeAVFrame();
- f->format = d->targetSWFormat;
- f->width = d->settings.videoResolution().width();
- f->height = d->settings.videoResolution().height();
+ f->format = m_targetSWFormat;
+ f->width = m_settings.videoResolution().width();
+ f->height = m_settings.videoResolution().height();
av_frame_get_buffer(f.get(), 0);
- const auto scaledHeight = sws_scale(d->converter.get(), frame->data, frame->linesize, 0,
+ const auto scaledHeight = sws_scale(m_converter.get(), frame->data, frame->linesize, 0,
frame->height, f->data, f->linesize);
if (scaledHeight != f->height)
@@ -272,8 +280,8 @@ int VideoFrameEncoder::sendFrame(AVFrameUPtr frame)
frame = std::move(f);
}
- if (d->uploadToHW) {
- auto *hwFramesContext = d->accel->hwFramesContextAsBuffer();
+ if (m_uploadToHW) {
+ auto *hwFramesContext = m_accel->hwFramesContextAsBuffer();
Q_ASSERT(hwFramesContext);
auto f = makeAVFrame();
@@ -302,28 +310,28 @@ int VideoFrameEncoder::sendFrame(AVFrameUPtr frame)
<< timeBase.den;
setAVFrameTime(*frame, pts, timeBase);
- return avcodec_send_frame(d->codecContext.get(), frame.get());
+ return avcodec_send_frame(m_codecContext.get(), frame.get());
}
AVPacketUPtr VideoFrameEncoder::retrievePacket()
{
- if (!d || !d->codecContext)
+ if (!m_codecContext)
return nullptr;
auto getPacket = [&]() {
AVPacketUPtr packet(av_packet_alloc());
- const int ret = avcodec_receive_packet(d->codecContext.get(), packet.get());
+ const int ret = avcodec_receive_packet(m_codecContext.get(), packet.get());
if (ret < 0) {
if (ret != AVERROR(EOF) && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
qCDebug(qLcVideoFrameEncoder) << "Error receiving packet" << ret << err2str(ret);
return AVPacketUPtr{};
}
- auto ts = timeStampMs(packet->pts, d->stream->time_base);
+ auto ts = timeStampMs(packet->pts, m_stream->time_base);
qCDebug(qLcVideoFrameEncoder)
<< "got a packet" << packet->pts << packet->dts << (ts ? *ts : 0);
- packet->stream_index = d->stream->id;
+ packet->stream_index = m_stream->id;
return packet;
};
@@ -362,43 +370,43 @@ AVPacketUPtr VideoFrameEncoder::retrievePacket()
void VideoFrameEncoder::updateConversions()
{
- const bool needToScale = d->sourceSize != d->settings.videoResolution();
- const bool zeroCopy = d->sourceFormat == d->targetFormat && !needToScale;
+ const bool needToScale = m_sourceSize != m_settings.videoResolution();
+ const bool zeroCopy = m_sourceFormat == m_targetFormat && !needToScale;
- d->converter.reset();
+ m_converter.reset();
if (zeroCopy) {
- d->downloadFromHW = false;
- d->uploadToHW = false;
+ m_downloadFromHW = false;
+ m_uploadToHW = false;
- qCDebug(qLcVideoFrameEncoder) << "zero copy encoding, format" << d->targetFormat;
+ qCDebug(qLcVideoFrameEncoder) << "zero copy encoding, format" << m_targetFormat;
// no need to initialize any converters
return;
}
- d->downloadFromHW = d->sourceFormat != d->sourceSWFormat;
- d->uploadToHW = d->targetFormat != d->targetSWFormat;
+ m_downloadFromHW = m_sourceFormat != m_sourceSWFormat;
+ m_uploadToHW = m_targetFormat != m_targetSWFormat;
- if (d->sourceSWFormat != d->targetSWFormat || needToScale) {
- const auto targetSize = d->settings.videoResolution();
+ if (m_sourceSWFormat != m_targetSWFormat || needToScale) {
+ const auto targetSize = m_settings.videoResolution();
qCDebug(qLcVideoFrameEncoder)
- << "video source and encoder use different formats:" << d->sourceSWFormat
- << d->targetSWFormat << "or sizes:" << d->sourceSize << targetSize;
+ << "video source and encoder use different formats:" << m_sourceSWFormat
+ << m_targetSWFormat << "or sizes:" << m_sourceSize << targetSize;
- d->converter.reset(sws_getContext(d->sourceSize.width(), d->sourceSize.height(),
- d->sourceSWFormat, targetSize.width(),
- targetSize.height(), d->targetSWFormat, SWS_FAST_BILINEAR,
- nullptr, nullptr, nullptr));
+ m_converter.reset(sws_getContext(m_sourceSize.width(), m_sourceSize.height(),
+ m_sourceSWFormat, targetSize.width(), targetSize.height(),
+ m_targetSWFormat, SWS_FAST_BILINEAR, nullptr, nullptr,
+ nullptr));
}
qCDebug(qLcVideoFrameEncoder) << "VideoFrameEncoder conversions initialized:"
- << "sourceFormat:" << d->sourceFormat
- << (isHwPixelFormat(d->sourceFormat) ? "(hw)" : "(sw)")
- << "targetFormat:" << d->targetFormat
- << (isHwPixelFormat(d->targetFormat) ? "(hw)" : "(sw)")
- << "sourceSWFormat:" << d->sourceSWFormat
- << "targetSWFormat:" << d->targetSWFormat
- << "converter:" << d->converter.get();
+ << "sourceFormat:" << m_sourceFormat
+ << (isHwPixelFormat(m_sourceFormat) ? "(hw)" : "(sw)")
+ << "targetFormat:" << m_targetFormat
+ << (isHwPixelFormat(m_targetFormat) ? "(hw)" : "(sw)")
+ << "sourceSWFormat:" << m_sourceSWFormat
+ << "targetSWFormat:" << m_targetSWFormat
+ << "converter:" << m_converter.get();
}
} // namespace QFFmpeg
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder_p.h b/src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder_p.h
index 6b3bef9ff..a977e13cd 100644
--- a/src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder_p.h
+++ b/src/plugins/multimedia/ffmpeg/qffmpegvideoframeencoder_p.h
@@ -24,41 +24,19 @@ namespace QFFmpeg {
class VideoFrameEncoder
{
- class Data final
- {
- public:
- QAtomicInt ref = 0;
- QMediaEncoderSettings settings;
- QSize sourceSize;
-
- std::unique_ptr<HWAccel> accel;
- const AVCodec *codec = nullptr;
- AVStream *stream = nullptr;
- AVCodecContextUPtr codecContext;
- std::unique_ptr<SwsContext, decltype(&sws_freeContext)> converter = { nullptr,
- &sws_freeContext };
- AVPixelFormat sourceFormat = AV_PIX_FMT_NONE;
- AVPixelFormat sourceSWFormat = AV_PIX_FMT_NONE;
- AVPixelFormat targetFormat = AV_PIX_FMT_NONE;
- AVPixelFormat targetSWFormat = AV_PIX_FMT_NONE;
- bool downloadFromHW = false;
- bool uploadToHW = false;
- };
-
- QExplicitlySharedDataPointer<Data> d;
public:
- VideoFrameEncoder() = default;
- VideoFrameEncoder(const QMediaEncoderSettings &encoderSettings, const QSize &sourceSize,
- qreal sourceFrameRate, AVPixelFormat sourceFormat, AVPixelFormat swFormat,
- AVFormatContext *formatContext);
+ static std::unique_ptr<VideoFrameEncoder> create(const QMediaEncoderSettings &encoderSettings,
+ const QSize &sourceSize, qreal sourceFrameRate,
+ AVPixelFormat sourceFormat,
+ AVPixelFormat sourceSWFormat,
+ AVFormatContext *formatContext);
+
~VideoFrameEncoder();
bool open();
- bool isNull() const { return !d; }
-
- AVPixelFormat sourceFormat() const { return d ? d->sourceFormat : AV_PIX_FMT_NONE; }
- AVPixelFormat targetFormat() const { return d ? d->targetFormat : AV_PIX_FMT_NONE; }
+ AVPixelFormat sourceFormat() const { return m_sourceFormat; }
+ AVPixelFormat targetFormat() const { return m_targetFormat; }
qint64 getPts(qint64 ms) const;
@@ -68,6 +46,8 @@ public:
AVPacketUPtr retrievePacket();
private:
+ VideoFrameEncoder() = default;
+
void updateConversions();
bool initCodec();
@@ -77,11 +57,25 @@ private:
bool initCodecContext(AVFormatContext *formatContext);
private:
+ QMediaEncoderSettings m_settings;
+ QSize m_sourceSize;
+
+ std::unique_ptr<HWAccel> m_accel;
+ const AVCodec *m_codec = nullptr;
+ AVStream *m_stream = nullptr;
+ AVCodecContextUPtr m_codecContext;
+ std::unique_ptr<SwsContext, decltype(&sws_freeContext)> m_converter = { nullptr,
+ &sws_freeContext };
+ AVPixelFormat m_sourceFormat = AV_PIX_FMT_NONE;
+ AVPixelFormat m_sourceSWFormat = AV_PIX_FMT_NONE;
+ AVPixelFormat m_targetFormat = AV_PIX_FMT_NONE;
+ AVPixelFormat m_targetSWFormat = AV_PIX_FMT_NONE;
+ bool m_downloadFromHW = false;
+ bool m_uploadToHW = false;
+
int64_t m_prevPacketDts = AV_NOPTS_VALUE;
int64_t m_packetDtsOffset = 0;
};
-
-
}
QT_END_NAMESPACE