2019-02-13 18:10:18 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
|
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
|
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
2021-08-31 11:26:17 +00:00
|
|
|
#include "data/data_audio_msg_id.h"
|
2019-09-13 12:22:54 +00:00
|
|
|
#include "ui/rect_part.h"
|
|
|
|
|
2019-09-13 06:06:02 +00:00
|
|
|
enum class ImageRoundRadius;
|
|
|
|
|
2019-02-13 18:10:18 +00:00
|
|
|
namespace Media {
|
|
|
|
|
2019-06-26 15:04:38 +00:00
|
|
|
inline constexpr auto kTimeUnknown = std::numeric_limits<crl::time>::min();
|
|
|
|
inline constexpr auto kDurationMax = crl::time(std::numeric_limits<int>::max());
|
|
|
|
inline constexpr auto kDurationUnavailable = std::numeric_limits<crl::time>::max();
|
2019-02-17 06:54:57 +00:00
|
|
|
|
2019-02-21 16:01:55 +00:00
|
|
|
namespace Audio {
|
|
|
|
bool SupportsSpeedControl();
|
|
|
|
} // namespace Audio
|
|
|
|
|
2019-02-21 11:15:44 +00:00
|
|
|
namespace Streaming {
|
|
|
|
|
2019-02-21 16:01:55 +00:00
|
|
|
inline bool SupportsSpeedControl() {
|
|
|
|
return Media::Audio::SupportsSpeedControl();
|
|
|
|
}
|
|
|
|
|
2019-02-20 13:28:48 +00:00
|
|
|
class VideoTrack;
|
|
|
|
class AudioTrack;
|
|
|
|
|
2019-02-13 18:10:18 +00:00
|
|
|
enum class Mode {
|
|
|
|
Both,
|
|
|
|
Audio,
|
|
|
|
Video,
|
2019-02-17 06:54:57 +00:00
|
|
|
Inspection,
|
2019-02-13 18:10:18 +00:00
|
|
|
};
|
|
|
|
|
2019-02-21 09:17:25 +00:00
|
|
|
struct PlaybackOptions {
|
|
|
|
Mode mode = Mode::Both;
|
|
|
|
crl::time position = 0;
|
|
|
|
float64 speed = 1.; // Valid values between 0.5 and 2.
|
2019-02-28 21:03:25 +00:00
|
|
|
AudioMsgId audioId;
|
2019-02-21 13:40:09 +00:00
|
|
|
bool syncVideoByAudio = true;
|
2019-12-11 14:01:11 +00:00
|
|
|
bool waitForMarkAsShown = false;
|
2022-03-30 08:20:44 +00:00
|
|
|
bool hwAllowed = false;
|
2019-03-05 07:40:25 +00:00
|
|
|
bool loop = false;
|
2019-02-21 09:17:25 +00:00
|
|
|
};
|
|
|
|
|
2019-02-17 11:08:29 +00:00
|
|
|
struct TrackState {
|
|
|
|
crl::time position = kTimeUnknown;
|
|
|
|
crl::time receivedTill = kTimeUnknown;
|
2019-02-20 13:28:48 +00:00
|
|
|
crl::time duration = kTimeUnknown;
|
2019-02-17 11:08:29 +00:00
|
|
|
};
|
|
|
|
|
2019-02-20 13:28:48 +00:00
|
|
|
struct VideoInformation {
|
|
|
|
TrackState state;
|
|
|
|
QSize size;
|
|
|
|
QImage cover;
|
|
|
|
int rotation = 0;
|
2022-01-21 15:00:13 +00:00
|
|
|
bool alpha = false;
|
2019-02-17 11:08:29 +00:00
|
|
|
};
|
|
|
|
|
2019-02-20 13:28:48 +00:00
|
|
|
struct AudioInformation {
|
|
|
|
TrackState state;
|
|
|
|
};
|
2019-02-13 18:10:18 +00:00
|
|
|
|
2019-02-20 13:28:48 +00:00
|
|
|
struct Information {
|
|
|
|
VideoInformation video;
|
|
|
|
AudioInformation audio;
|
2019-05-31 11:45:35 +00:00
|
|
|
int headerSize = 0;
|
2019-02-13 18:10:18 +00:00
|
|
|
};
|
|
|
|
|
2019-02-20 13:28:48 +00:00
|
|
|
template <typename Track>
|
|
|
|
struct PreloadedUpdate {
|
|
|
|
crl::time till = kTimeUnknown;
|
2019-02-17 11:08:29 +00:00
|
|
|
};
|
|
|
|
|
2019-02-20 13:28:48 +00:00
|
|
|
template <typename Track>
|
|
|
|
struct PlaybackUpdate {
|
|
|
|
crl::time position = kTimeUnknown;
|
2019-02-13 18:10:18 +00:00
|
|
|
};
|
|
|
|
|
2019-02-20 13:28:48 +00:00
|
|
|
using PreloadedVideo = PreloadedUpdate<VideoTrack>;
|
|
|
|
using UpdateVideo = PlaybackUpdate<VideoTrack>;
|
|
|
|
using PreloadedAudio = PreloadedUpdate<AudioTrack>;
|
|
|
|
using UpdateAudio = PlaybackUpdate<AudioTrack>;
|
|
|
|
|
2019-02-17 06:54:57 +00:00
|
|
|
struct WaitingForData {
|
2019-03-01 11:16:55 +00:00
|
|
|
bool waiting = false;
|
2019-02-13 18:10:18 +00:00
|
|
|
};
|
|
|
|
|
2019-02-17 06:54:57 +00:00
|
|
|
struct MutedByOther {
|
2019-02-13 18:10:18 +00:00
|
|
|
};
|
2019-02-16 10:29:55 +00:00
|
|
|
|
2019-02-22 11:58:26 +00:00
|
|
|
struct Finished {
|
|
|
|
};
|
|
|
|
|
2019-02-17 06:54:57 +00:00
|
|
|
struct Update {
|
2020-08-31 08:14:53 +00:00
|
|
|
std::variant<
|
2019-02-17 06:54:57 +00:00
|
|
|
Information,
|
2019-02-20 13:28:48 +00:00
|
|
|
PreloadedVideo,
|
2019-02-17 11:08:29 +00:00
|
|
|
UpdateVideo,
|
2019-02-20 13:28:48 +00:00
|
|
|
PreloadedAudio,
|
2019-02-17 11:08:29 +00:00
|
|
|
UpdateAudio,
|
2019-02-17 06:54:57 +00:00
|
|
|
WaitingForData,
|
2019-02-22 11:58:26 +00:00
|
|
|
MutedByOther,
|
|
|
|
Finished> data;
|
2019-02-16 10:29:55 +00:00
|
|
|
};
|
|
|
|
|
2019-03-05 13:56:27 +00:00
|
|
|
enum class Error {
|
|
|
|
OpenFailed,
|
|
|
|
LoadFailed,
|
|
|
|
InvalidData,
|
|
|
|
NotStreamable,
|
2019-02-13 18:10:18 +00:00
|
|
|
};
|
|
|
|
|
2019-02-17 11:08:29 +00:00
|
|
|
struct FrameRequest {
|
|
|
|
QSize resize;
|
|
|
|
QSize outer;
|
|
|
|
ImageRoundRadius radius = ImageRoundRadius();
|
|
|
|
RectParts corners = RectPart::AllCorners;
|
2022-01-21 15:00:13 +00:00
|
|
|
QColor colored = QColor(0, 0, 0, 0);
|
2021-06-03 12:57:48 +00:00
|
|
|
bool requireARGB32 = true;
|
2022-01-19 14:45:51 +00:00
|
|
|
bool keepAlpha = false;
|
2019-03-26 08:54:51 +00:00
|
|
|
bool strict = true;
|
|
|
|
|
|
|
|
static FrameRequest NonStrict() {
|
|
|
|
auto result = FrameRequest();
|
|
|
|
result.strict = false;
|
|
|
|
return result;
|
|
|
|
}
|
2019-02-17 11:08:29 +00:00
|
|
|
|
2019-12-12 06:56:08 +00:00
|
|
|
[[nodiscard]] bool empty() const {
|
2019-02-17 11:08:29 +00:00
|
|
|
return resize.isEmpty();
|
|
|
|
}
|
|
|
|
|
2019-12-12 06:56:08 +00:00
|
|
|
[[nodiscard]] bool operator==(const FrameRequest &other) const {
|
2019-02-17 11:08:29 +00:00
|
|
|
return (resize == other.resize)
|
|
|
|
&& (outer == other.outer)
|
|
|
|
&& (radius == other.radius)
|
2021-06-03 12:57:48 +00:00
|
|
|
&& (corners == other.corners)
|
2022-01-21 15:00:13 +00:00
|
|
|
&& (colored == other.colored)
|
2022-01-19 14:45:51 +00:00
|
|
|
&& (keepAlpha == other.keepAlpha)
|
2021-06-03 12:57:48 +00:00
|
|
|
&& (requireARGB32 == other.requireARGB32);
|
2019-02-17 11:08:29 +00:00
|
|
|
}
|
2019-12-12 06:56:08 +00:00
|
|
|
[[nodiscard]] bool operator!=(const FrameRequest &other) const {
|
2019-02-17 11:08:29 +00:00
|
|
|
return !(*this == other);
|
|
|
|
}
|
2019-12-12 06:56:08 +00:00
|
|
|
|
|
|
|
[[nodiscard]] bool goodFor(const FrameRequest &other) const {
|
2021-06-03 12:57:48 +00:00
|
|
|
return (requireARGB32 == other.requireARGB32)
|
2022-01-19 14:45:51 +00:00
|
|
|
&& (keepAlpha == other.keepAlpha)
|
2022-01-21 15:00:13 +00:00
|
|
|
&& (colored == other.colored)
|
|
|
|
&& ((strict && !other.strict) || (*this == other));
|
2019-12-12 06:56:08 +00:00
|
|
|
}
|
2019-02-17 11:08:29 +00:00
|
|
|
};
|
|
|
|
|
2021-06-03 12:57:48 +00:00
|
|
|
enum class FrameFormat {
|
|
|
|
None,
|
|
|
|
ARGB32,
|
|
|
|
YUV420,
|
2022-03-22 15:50:23 +00:00
|
|
|
NV12,
|
2021-06-03 12:57:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FrameChannel {
|
|
|
|
const void *data = nullptr;
|
|
|
|
int stride = 0;
|
|
|
|
};
|
|
|
|
|
2022-03-22 15:50:23 +00:00
|
|
|
struct FrameYUV {
|
2021-06-03 12:57:48 +00:00
|
|
|
QSize size;
|
|
|
|
QSize chromaSize;
|
|
|
|
FrameChannel y;
|
|
|
|
FrameChannel u;
|
|
|
|
FrameChannel v;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FrameWithInfo {
|
2022-02-10 16:10:42 +00:00
|
|
|
QImage image;
|
2022-03-22 15:50:23 +00:00
|
|
|
FrameYUV *yuv = nullptr;
|
2021-06-03 12:57:48 +00:00
|
|
|
FrameFormat format = FrameFormat::None;
|
|
|
|
int index = -1;
|
2022-01-21 15:00:13 +00:00
|
|
|
bool alpha = false;
|
2021-06-03 12:57:48 +00:00
|
|
|
};
|
|
|
|
|
2019-02-13 18:10:18 +00:00
|
|
|
} // namespace Streaming
|
|
|
|
} // namespace Media
|