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
qwmf_support_p.h
Go to the documentation of this file.
1// Copyright (C) 2025 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
3
4//
5// W A R N I N G
6// -------------
7//
8// This file is not part of the Qt API. It exists for the convenience
9// of other Qt classes. This header file may change from version to
10// version without notice, or even be removed.
11//
12// We mean it.
13//
14
15#ifndef QWFM_SUPPORT_P_H
16#define QWFM_SUPPORT_P_H
17
18#include <QtMultimedia/qtmultimediaexports.h>
19#include <QtCore/qtconfigmacros.h>
20#include <QtCore/qspan.h>
21#include <QtCore/qbytearray.h>
22#include <QtCore/private/qexpected_p.h>
23#include <QtCore/private/qcomobject_p.h>
24#include <QtCore/private/qcomptr_p.h>
25
26#include <mfobjects.h>
27
28#include <chrono>
29#include <memory_resource>
30
31QT_BEGIN_NAMESPACE
32
33namespace QWMF {
34
35///////////////////////////////////////////////////////////////////////////////////////////////////
36
37template <typename Functor>
39
40template <typename Functor>
41[[nodiscard]]
42auto withLockedBuffer(IMFMediaBuffer *buffer, Functor &&f)
44{
45 if (!buffer)
46 return q23::unexpected{ E_POINTER };
47
48 BYTE *data = nullptr;
49 DWORD maxLength = 0;
50 DWORD currentLength = 0;
51
52 HRESULT hr = buffer->Lock(&data, &maxLength, &currentLength);
53 if (FAILED(hr))
54 return q23::unexpected{ hr };
55
56 auto unlockGuard = qScopeGuard([buffer]() {
57 buffer->Unlock();
58 });
59
60 if constexpr (std::is_void_v<IMFBufferReaderReturnType<Functor>>) {
61 f(QSpan{ data, qsizetype(currentLength) }, QSpan{ data, qsizetype(maxLength) });
62 return {};
63 } else
64 return f(QSpan{ data, qsizetype(currentLength) }, QSpan{ data, qsizetype(maxLength) });
65}
66
67template <typename Functor>
68[[nodiscard]]
69auto withLockedBuffer(const ComPtr<IMFMediaBuffer> &buffer, Functor &&f)
71{
72 return withLockedBuffer(buffer.Get(), std::forward<Functor>(f));
73}
74
75///////////////////////////////////////////////////////////////////////////////////////////////////
76
77class QByteArrayMFMediaBuffer final : public QComObject<IMFMediaBuffer>
78{
79public:
80 static HRESULT CreateInstance(QByteArray data, IMFMediaBuffer **ppBuffer,
81 bool isReadOnly = false);
82 static HRESULT CreateInstance(qsizetype capacity, IMFMediaBuffer **ppBuffer);
83
84 // --- IMFMediaBuffer Methods ---
85 STDMETHODIMP Lock(BYTE **ppbBuffer, DWORD *pcbMaxLength, DWORD *pcbCurrentLength) override;
86 STDMETHODIMP Unlock() override;
87 STDMETHODIMP GetCurrentLength(DWORD *pcbCurrentLength) override;
88 STDMETHODIMP SetCurrentLength(DWORD cbCurrentLength) override;
89 STDMETHODIMP GetMaxLength(DWORD *pcbMaxLength) override;
90
92
93private:
94 // Protected constructor to enforce creation via CreateInstance factory method.
95 explicit QByteArrayMFMediaBuffer(QByteArray &&data, bool isReadOnly);
96 ~QByteArrayMFMediaBuffer() = default;
97
98 DWORD GetMaxLengthInternal() const;
99
100 // Member variables
101 std::atomic_flag m_isLocked = ATOMIC_FLAG_INIT;
102 DWORD m_currentLength{ 0 };
103 QByteArray m_byteArray;
104 const bool m_isReadOnly{};
105
106public:
107 QByteArrayMFMediaBuffer(const QByteArrayMFMediaBuffer &) = delete;
108 QByteArrayMFMediaBuffer &operator=(const QByteArrayMFMediaBuffer &) = delete;
109 QByteArrayMFMediaBuffer(QByteArrayMFMediaBuffer &&) = delete;
110 QByteArrayMFMediaBuffer &operator=(QByteArrayMFMediaBuffer &&) = delete;
111};
112
113///////////////////////////////////////////////////////////////////////////////////////////////////
114
115class QPmrMediaBuffer final : public QComObject<IMFMediaBuffer>
116{
117public:
118 static HRESULT CreateInstance(QSpan<const std::byte>, std::pmr::memory_resource *,
119 IMFMediaBuffer **ppBuffer);
120 static HRESULT CreateInstance(qsizetype capacity, std::pmr::memory_resource *,
121 IMFMediaBuffer **ppBuffer);
122
123 // --- IUnknown Methods ---
124 // we override QComObject::Release to free via the memory_resource
125 STDMETHODIMP_(ULONG) Release() override;
126
127 // --- IMFMediaBuffer Methods ---
128 STDMETHODIMP Lock(BYTE **ppbBuffer, DWORD *pcbMaxLength, DWORD *pcbCurrentLength) override;
129 STDMETHODIMP Unlock() override;
130 STDMETHODIMP GetCurrentLength(DWORD *pcbCurrentLength) override;
131 STDMETHODIMP SetCurrentLength(DWORD cbCurrentLength) override;
132 STDMETHODIMP GetMaxLength(DWORD *pcbMaxLength) override;
133
134private:
135 // Protected constructor to enforce creation via CreateInstance factory method.
136 QPmrMediaBuffer(QSpan<const std::byte>, std::pmr::memory_resource *);
137 QPmrMediaBuffer(qsizetype capacity, std::pmr::memory_resource *);
138 ~QPmrMediaBuffer();
139
140 // Member variables
141 std::atomic_flag m_isLocked = ATOMIC_FLAG_INIT;
142 std::pmr::memory_resource *m_memoryResource;
143
144 DWORD m_currentLength{ 0 };
145 DWORD m_maxLength;
146 std::byte *const m_buffer;
147
148public:
149 Q_DISABLE_COPY_MOVE(QPmrMediaBuffer)
150};
151
152///////////////////////////////////////////////////////////////////////////////////////////////////
153
154// REFERENCE_TIME helper
155using reference_time = std::chrono::duration<long long, std::ratio<1, 10000000>>;
156static_assert(reference_time(1) == std::chrono::nanoseconds(100));
157
158} // namespace QWMF
159
160QT_END_NAMESPACE
161
162#endif // QWFM_SUPPORT_P_H
STDMETHODIMP GetCurrentLength(DWORD *pcbCurrentLength) override
QByteArrayMFMediaBuffer & operator=(const QByteArrayMFMediaBuffer &)=delete
STDMETHODIMP Lock(BYTE **ppbBuffer, DWORD *pcbMaxLength, DWORD *pcbCurrentLength) override
static HRESULT CreateInstance(QByteArray data, IMFMediaBuffer **ppBuffer, bool isReadOnly=false)
STDMETHODIMP SetCurrentLength(DWORD cbCurrentLength) override
QByteArrayMFMediaBuffer(QByteArrayMFMediaBuffer &&)=delete
QByteArrayMFMediaBuffer(const QByteArrayMFMediaBuffer &)=delete
static HRESULT CreateInstance(qsizetype capacity, IMFMediaBuffer **ppBuffer)
QByteArrayMFMediaBuffer & operator=(QByteArrayMFMediaBuffer &&)=delete
STDMETHODIMP Unlock() override
STDMETHODIMP GetMaxLength(DWORD *pcbMaxLength) override
STDMETHODIMP Lock(BYTE **ppbBuffer, DWORD *pcbMaxLength, DWORD *pcbCurrentLength) override
STDMETHODIMP SetCurrentLength(DWORD cbCurrentLength) override
STDMETHODIMP GetCurrentLength(DWORD *pcbCurrentLength) override
STDMETHODIMP_(ULONG) Release() override
static HRESULT CreateInstance(QSpan< const std::byte >, std::pmr::memory_resource *, IMFMediaBuffer **ppBuffer)
STDMETHODIMP GetMaxLength(DWORD *pcbMaxLength) override
STDMETHODIMP Unlock() override
Combined button and popup list for selecting options.
auto withLockedBuffer(const ComPtr< IMFMediaBuffer > &buffer, Functor &&f) -> q23::expected< IMFBufferReaderReturnType< Functor >, HRESULT >
std::chrono::duration< long long, std::ratio< 1, 10000000 > > reference_time
auto withLockedBuffer(IMFMediaBuffer *buffer, Functor &&f) -> q23::expected< IMFBufferReaderReturnType< Functor >, HRESULT >
static constexpr auto mfBufferAlignment