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
27
28using namespace std::chrono;
29
30// Extracts media metadata from a input media file
32{
33 static std::optional<MediaInfo> create(const QUrl &fileLocation, bool keepFrames = false)
34 {
35 QMediaPlayer player;
36 const QSignalSpy mediaStatusChanged{ &player, &QMediaPlayer::mediaStatusChanged };
37
38 QAudioBufferOutput audioOutput;
39 player.setAudioBufferOutput(&audioOutput);
40
41 TestVideoSink sink;
42 player.setVideoSink(&sink);
43
44 std::vector<std::array<QColor, 4>> colors;
45 std::vector<QVideoFrame> frames;
46 QObject::connect(&sink, &TestVideoSink::videoFrameChangedSync, &sink,
47 [&](const QVideoFrame &frame) {
48 if (keepFrames)
49 frames.push_back(frame);
50 if (frame.isValid())
51 colors.push_back(sampleQuadrants(frame.toImage()));
52 });
53
54 QByteArray audioData;
55 QAudioFormat audioFormat;
56 QObject::connect(&audioOutput, &QAudioBufferOutput::audioBufferReceived, &audioOutput,
57 [&](const QAudioBuffer &buffer) {
58 if (!buffer.isValid())
59 return;
60 if (!audioFormat.isValid())
61 audioFormat = buffer.format();
62 else
63 QTEST_ASSERT(audioFormat == buffer.format());
64
65 audioData.append(buffer.data<const char>(), buffer.byteCount());
66 });
67
68 player.setSource(fileLocation);
69
70 // Loop through all frames to be able to count them
71 player.setPlaybackRate(50); // let's speed it up
72 player.play();
73
74 const bool endReached = QTest::qWaitFor(
75 [&] {
76 return mediaStatusChanged.contains(QList<QVariant>{ QMediaPlayer::EndOfMedia })
77 || mediaStatusChanged.contains(
78 QList<QVariant>{ QMediaPlayer::InvalidMedia });
79 },
80 10min);
81
82 if (!endReached)
83 return {};
84
85 MediaInfo info{};
86 info.m_url = fileLocation.toString();
87 info.m_frameRate = player.metaData().value(QMediaMetaData::VideoFrameRate).toReal();
88 info.m_size = player.metaData().value(QMediaMetaData::Resolution).toSize();
89
90 info.m_duration = milliseconds{ player.duration() };
91 info.m_frameCount = sink.m_totalFrames - 1;
92 info.m_frameTimes = sink.m_frameTimes;
93 info.m_hasVideo = player.hasVideo();
94 info.m_hasAudio = player.hasAudio();
95 info.m_colors = std::move(colors);
96 info.m_frames = std::move(frames);
97 info.m_audioBuffer = QAudioBuffer(audioData, audioFormat);
98 return info;
99 }
100
101
102
103 static std::array<QColor, 4> sampleQuadrants(const QImage &image)
104 {
105 const int width = image.width();
106 const int height = image.height();
107 return {
108 image.pixel(width / 4, height / 4),
109 image.pixel(3 * width / 4, height / 4),
110 image.pixel(width / 4, 3 * height / 4),
111 image.pixel(3 * width / 4, 3 * height / 4),
112 };
113
114 }
115
116 QString m_url; // Visualize recorded file name when debugging.
120 milliseconds m_duration;
121 bool m_hasVideo = false;
122 bool m_hasAudio = false;
123 std::vector<QVideoFrame> m_frames; // Decoded video frames (optional)
124 std::vector<std::array<QColor, 4>> m_colors; // Colors in upper left, upper right, bottom left, and bottom right
126
128};
129
130#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:33
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