Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qffmpegmuxer.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
6#include <QtCore/qloggingcategory.h>
7
9
10namespace QFFmpeg {
11
12Q_STATIC_LOGGING_CATEGORY(qLcFFmpegMuxer, "qt.multimedia.ffmpeg.muxer");
13
14Muxer::Muxer(RecordingEngine *encoder) : m_encoder(encoder)
15{
16 setObjectName(QLatin1String("Muxer"));
17}
18
19void Muxer::addPacket(AVPacketUPtr packet)
20{
21 {
22 QMutexLocker locker = lockLoopData();
23 m_packetQueue.push(std::move(packet));
24 }
25
26 // qCDebug(qLcFFmpegEncoder) << "Muxer::addPacket" << packet->pts << packet->stream_index;
27 dataReady();
28}
29
30AVPacketUPtr Muxer::takePacket()
31{
32 QMutexLocker locker = lockLoopData();
33 return dequeueIfPossible(m_packetQueue);
34}
35
36bool Muxer::init()
37{
38 qCDebug(qLcFFmpegMuxer) << "Muxer::init started thread.";
39 return true;
40}
41
43{
44 while (!m_packetQueue.empty())
46
47 const int status = av_interleaved_write_frame(m_encoder->avFormatContext(), nullptr);
48 if (status < 0)
49 qCWarning(qLcFFmpegMuxer) << "Failed to flush muxer:" << AVError(status);
50}
51
52bool QFFmpeg::Muxer::hasData() const
53{
54 return !m_packetQueue.empty();
55}
56
58{
59 auto packet = takePacket();
60 // qCDebug(qLcFFmpegEncoder) << "writing packet to file" << packet->pts << packet->duration <<
61 // packet->stream_index;
62
63 // from AVPacket Struct Reference:
64 // "The semantics of data ownership depends on the buf field. If it is set, the packet data is
65 // dynamically allocated and is valid indefinitely until a call to av_packet_unref() reduces the
66 // reference count to 0."
67 //
68 // from av_interleaved_write_frame:
69 // "If the packet is reference-counted, this function will take ownership of this reference and
70 // unreference it later when it sees fit. The caller must not access the data through this
71 // reference after this function returns. If the packet is not reference-counted, libavformat
72 // will make a copy."
73 //
74 // This means that av_interleaved_write_frame takes ownership of the AVBufferRef field, not the
75 // whole AVPacket.
76
77 const int status = av_interleaved_write_frame(m_encoder->avFormatContext(), packet.get());
78 if (status < 0)
79 qCWarning(qLcFFmpegMuxer) << "Failed to write packet to file:" << AVError(status);
80 Q_ASSERT(packet->buf == nullptr); // av_interleaved_write_frame took ownership of the buffer
81}
82
83} // namespace QFFmpeg
84
85QT_END_NAMESPACE
bool init() override
Called on this thread when thread starts.
void cleanup() override
Called on this thread before thread exits.
Muxer(RecordingEngine *encoder)
void processOne() override
Process one work item.
void addPacket(AVPacketUPtr packet)
bool hasData() const override
Must return true when data is available for processing.
Q_STATIC_LOGGING_CATEGORY(qLCAndroidVideoDevices, "qt.multimedia.ffmpeg.android.videoDevices")
QT_MANGLE_NAMESPACE(QMacScreenCaptureStreamDelegate) QMacScreenCaptureStreamDelegate
Combined button and popup list for selecting options.