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
mediainfo_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef MEDIAINFO_P_H
5#define MEDIAINFO_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtTest/QTest>
19#include <QtMultimedia/qmediaplayer.h>
20#include <QtMultimedia/qmediametadata.h>
21#include <QtMultimedia/qaudiooutput.h>
22#include <QtMultimedia/qaudiobufferoutput.h>
23#include <QtMultimedia/qaudiobuffer.h>
24#include <private/testvideosink_p.h>
25#include <chrono>
26
27QT_USE_NAMESPACE
28
29using namespace std::chrono;
30
31// Extracts media metadata from a input media file
33{
34 static std::optional<MediaInfo> create(const QUrl &fileLocation, bool keepFrames = false)
35 {
36 QMediaPlayer player;
37 const QSignalSpy mediaStatusChanged{ &player, &QMediaPlayer::mediaStatusChanged };
38
39 QAudioBufferOutput audioOutput;
40 player.setAudioBufferOutput(&audioOutput);
41
42 TestVideoSink sink;
43 player.setVideoSink(&sink);
44
45 std::vector<std::array<QColor, 4>> colors;
46 std::vector<QVideoFrame> frames;
47 QObject::connect(&sink, &TestVideoSink::videoFrameChangedSync, &sink,
48 [&](const QVideoFrame &frame) {
49 if (keepFrames)
50 frames.push_back(frame);
51 if (frame.isValid())
52 colors.push_back(sampleQuadrants(frame.toImage()));
53 });
54
55 QByteArray audioData;
56 QAudioFormat audioFormat;
57 QObject::connect(&audioOutput, &QAudioBufferOutput::audioBufferReceived, &audioOutput,
58 [&](const QAudioBuffer &buffer) {
59 if (!buffer.isValid())
60 return;
61 if (!audioFormat.isValid())
62 audioFormat = buffer.format();
63 else
64 QTEST_ASSERT(audioFormat == buffer.format());
65
66 audioData.append(buffer.data<const char>(), buffer.byteCount());
67 });
68
69 player.setSource(fileLocation);
70
71 // Loop through all frames to be able to count them
72 player.setPlaybackRate(50); // let's speed it up
73 player.play();
74
75 const bool endReached = QTest::qWaitFor(
76 [&] {
77 return mediaStatusChanged.contains(QList<QVariant>{ QMediaPlayer::EndOfMedia })
78 || mediaStatusChanged.contains(
79 QList<QVariant>{ QMediaPlayer::InvalidMedia });
80 },
81 10min);
82
83 if (!endReached)
84 return {};
85
86 MediaInfo info{};
87 info.m_url = fileLocation.toString();
88 info.m_frameRate = player.metaData().value(QMediaMetaData::VideoFrameRate).toReal();
89 info.m_size = player.metaData().value(QMediaMetaData::Resolution).toSize();
90
91 info.m_duration = milliseconds{ player.duration() };
92 info.m_frameCount = sink.m_totalFrames - 1;
93 info.m_frameTimes = sink.m_frameTimes;
94 info.m_hasVideo = player.hasVideo();
95 info.m_hasAudio = player.hasAudio();
96 info.m_colors = std::move(colors);
97 info.m_frames = std::move(frames);
98 info.m_audioBuffer = QAudioBuffer(audioData, audioFormat);
99 return info;
100 }
101
102
103
104 static std::array<QColor, 4> sampleQuadrants(const QImage &image)
105 {
106 const int width = image.width();
107 const int height = image.height();
108 return {
109 image.pixel(width / 4, height / 4),
110 image.pixel(3 * width / 4, height / 4),
111 image.pixel(width / 4, 3 * height / 4),
112 image.pixel(3 * width / 4, 3 * height / 4),
113 };
114
115 }
116
117 QString m_url; // Visualize recorded file name when debugging.
122 bool m_hasVideo = false;
123 bool m_hasAudio = false;
124 std::vector<QVideoFrame> m_frames; // Decoded video frames (optional)
125 std::vector<std::array<QColor, 4>> m_colors; // Colors in upper left, upper right, bottom left, and bottom right
127
129};
130
131#endif
static std::array< QColor, 4 > sampleQuadrants(const QImage &image)
int m_frameCount
static std::optional< MediaInfo > create(const QUrl &fileLocation, bool keepFrames=false)
Definition mediainfo_p.h:34
bool m_hasVideo
milliseconds m_duration
qreal m_frameRate
std::vector< TestVideoSink::TimePoint > m_frameTimes
QAudioBuffer m_audioBuffer
std::vector< QVideoFrame > m_frames
QString m_url
QSize m_size
bool m_hasAudio