tdesktop/Telegram/SourceFiles/lottie/lottie_cache.h

127 lines
2.5 KiB
C
Raw Normal View History

2019-06-26 14:18:00 +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
2019-06-27 13:27:01 +00:00
#include "ffmpeg/ffmpeg_utility.h"
2019-06-26 14:18:00 +00:00
#include <QImage>
#include <QSize>
#include <QByteArray>
namespace Lottie {
2019-06-26 17:14:46 +00:00
struct FrameRequest;
2019-06-27 13:27:01 +00:00
class EncodedStorage {
2019-06-26 14:18:00 +00:00
public:
2019-06-27 13:27:01 +00:00
void allocate(int width, int height);
int width() const;
int height() const;
char *data();
const char *data() const;
int size() const;
uint8_t *yData();
const uint8_t *yData() const;
int yBytesPerLine() const;
uint8_t *uData();
const uint8_t *uData() const;
int uBytesPerLine() const;
uint8_t *vData();
const uint8_t *vData() const;
int vBytesPerLine() const;
uint8_t *aData();
const uint8_t *aData() const;
int aBytesPerLine() const;
2019-06-26 14:18:00 +00:00
private:
void reallocate();
2019-06-27 13:27:01 +00:00
int _width = 0;
int _height = 0;
QByteArray _data;
2019-06-26 14:18:00 +00:00
};
class Cache {
2019-06-26 14:18:00 +00:00
public:
2019-06-27 09:57:48 +00:00
enum class Encoder : qint8 {
2019-06-26 14:18:00 +00:00
YUV420A4_LZ4,
};
Cache(
const QByteArray &data,
const FrameRequest &request,
FnMut<void(QByteArray &&cached)> put);
2019-06-26 14:18:00 +00:00
2019-06-26 17:14:46 +00:00
void init(
QSize original,
int frameRate,
int framesCount,
const FrameRequest &request);
2019-06-26 14:18:00 +00:00
[[nodiscard]] int frameRate() const;
[[nodiscard]] int framesReady() const;
[[nodiscard]] int framesCount() const;
2019-06-26 17:14:46 +00:00
[[nodiscard]] QSize originalSize() const;
2019-06-26 14:18:00 +00:00
[[nodiscard]] QImage takeFirstFrame();
2019-06-26 17:14:46 +00:00
[[nodiscard]] bool renderFrame(
QImage &to,
const FrameRequest &request,
int index);
void appendFrame(
const QImage &frame,
const FrameRequest &request,
int index);
~Cache();
2019-06-26 14:18:00 +00:00
private:
struct ReadResult {
bool ok = false;
bool xored = false;
};
2019-06-27 13:27:01 +00:00
struct EncodeFields {
std::vector<QByteArray> compressedFrames;
QByteArray compressBuffer;
QByteArray xorCompressBuffer;
QImage cache;
FFmpeg::SwscalePointer context;
2019-06-27 16:57:32 +00:00
int totalSize = 0;
2019-06-27 13:27:01 +00:00
};
2019-06-27 09:57:48 +00:00
int headerSize() const;
2019-06-26 14:18:00 +00:00
void prepareBuffers();
2019-06-27 09:57:48 +00:00
void finalizeEncoding();
2019-06-26 17:14:46 +00:00
void writeHeader();
2019-07-01 12:38:19 +00:00
void updateFramesReadyCount();
2019-06-26 17:14:46 +00:00
[[nodiscard]] bool readHeader(const FrameRequest &request);
[[nodiscard]] ReadResult readCompressedFrame();
2019-06-26 14:18:00 +00:00
QByteArray _data;
2019-06-27 13:27:01 +00:00
EncodeFields _encode;
2019-06-26 14:18:00 +00:00
QSize _size;
QSize _original;
2019-06-27 13:27:01 +00:00
EncodedStorage _uncompressed;
EncodedStorage _previous;
FFmpeg::SwscalePointer _decodeContext;
2019-06-26 14:18:00 +00:00
QImage _firstFrame;
int _frameRate = 0;
int _framesCount = 0;
int _framesReady = 0;
int _offset = 0;
2019-06-26 17:14:46 +00:00
int _offsetFrameIndex = 0;
2019-06-26 14:18:00 +00:00
Encoder _encoder = Encoder::YUV420A4_LZ4;
FnMut<void(QByteArray &&cached)> _put;
2019-06-26 14:18:00 +00:00
};
} // namespace Lottie