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 |
3 | |
4 | #include "recordingengine/qffmpegrecordingengineutils_p.h" |
5 | #include "recordingengine/qffmpegencoderthread_p.h" |
6 | #include "private/qplatformaudiobufferinput_p.h" |
7 | #include "private/qplatformvideoframeinput_p.h" |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | namespace QFFmpeg { |
12 | |
13 | template <typename F> |
14 | void doWithMediaFrameInput(QObject *source, F &&f) |
15 | { |
16 | if (auto videoFrameInput = qobject_cast<QPlatformVideoFrameInput *>(object: source)) |
17 | f(videoFrameInput); |
18 | else if (auto audioBufferInput = qobject_cast<QPlatformAudioBufferInput *>(object: source)) |
19 | f(audioBufferInput); |
20 | } |
21 | |
22 | void setEncoderInterface(QObject *source, QMediaInputEncoderInterface *encoderInterface) |
23 | { |
24 | doWithMediaFrameInput(source, f: [&](auto source) { |
25 | using Source = std::remove_pointer_t<decltype(source)>; |
26 | |
27 | source->setEncoderInterface(encoderInterface); |
28 | if (encoderInterface) |
29 | // Postpone emit 'encoderUpdated' as the encoding pipeline may be not |
30 | // completely ready at the moment. The case is calling QMediaRecorder::stop |
31 | // upon handling 'readyToSendFrame' |
32 | QMetaObject::invokeMethod(source, &Source::encoderUpdated, Qt::QueuedConnection); |
33 | else |
34 | emit source->encoderUpdated(); |
35 | }); |
36 | } |
37 | |
38 | void setEncoderUpdateConnection(QObject *source, EncoderThread *encoder) |
39 | { |
40 | doWithMediaFrameInput(source, f: [&](auto source) { |
41 | using Source = std::remove_pointer_t<decltype(source)>; |
42 | QObject::connect(encoder, &EncoderThread::canPushFrameChanged, source, |
43 | &Source::encoderUpdated); |
44 | }); |
45 | } |
46 | |
47 | void disconnectEncoderFromSource(EncoderThread *encoder) |
48 | { |
49 | QObject *source = encoder->source(); |
50 | if (!source) |
51 | return; |
52 | |
53 | // We should address the dependency AudioEncoder from QFFmpegAudioInput to |
54 | // set null source here. |
55 | // encoder->setSource(nullptr); |
56 | |
57 | QObject::disconnect(sender: source, signal: nullptr, receiver: encoder, member: nullptr); |
58 | setEncoderInterface(source, encoderInterface: nullptr); |
59 | } |
60 | |
61 | } // namespace QFFmpeg |
62 | |
63 | QT_END_NAMESPACE |
64 | |