Wavelength
Privacy-focused, cross-platform, and open-source communication application
Loading...
Searching...
No Matches
gif_decoder.h
Go to the documentation of this file.
1#ifndef GIF_DECODER_H
2#define GIF_DECODER_H
3
4#ifdef _MSC_VER
5#pragma comment(lib, "swscale.lib")
6#endif
7
8#include <QMutex>
9#include <QThread>
10#include <QWaitCondition>
11
12extern "C" {
13#include <libavcodec/avcodec.h>
14#include <libavformat/avformat.h>
15#include <libswscale/swscale.h>
16#include <libavutil/imgutils.h>
17}
18
29class GifDecoder final : public QThread {
30 Q_OBJECT
31
32public:
40 explicit GifDecoder(const QByteArray &gif_data, QObject *parent = nullptr);
41
46 ~GifDecoder() override;
47
53 void ReleaseResources();
54
62 bool Reinitialize();
63
72 bool Initialize();
73
79 void Stop();
80
86 void Pause();
87
93 bool IsPaused() const {
94 QMutexLocker locker(&mutex_);
95 return paused_;
96 }
97
103 void Reset();
104
109 bool IsDecoderRunning() const {
110 return isRunning();
111 }
112
118 double GetDuration() const {
119 QMutexLocker locker(&mutex_);
120 if (format_context_ && format_context_->duration != AV_NOPTS_VALUE) {
121 return format_context_->duration / static_cast<double>(AV_TIME_BASE);
122 }
123 return 0.0;
124 }
125
131 void Resume();
132
133signals:
138 void frameReady(const QImage &frame);
139
145 void firstFrameReady(const QImage &frame);
146
151 void error(const QString &message);
152
161 void gifInfo(int width, int height, double duration, double frame_rate, int num_of_streams);
162
169
174 void positionChanged(double position);
175
176protected:
182 void run() override;
183
184private:
193 static int ReadPacket(void *opaque, uint8_t *buf, int buf_size);
194
204 static int64_t SeekPacket(void *opaque, int64_t offset, int whence);
205
212
214 QByteArray gif_data_;
217
219 AVFormatContext *format_context_ = nullptr;
221 AVCodecContext *codec_context_ = nullptr;
223 SwsContext *sws_context_ = nullptr;
225 AVFrame *frame_ = nullptr;
227 AVFrame *frame_rgb_ = nullptr;
229 AVIOContext *io_context_ = nullptr;
231 unsigned char *io_buffer_ = nullptr;
233 int gif_stream_ = -1;
235 uint8_t *buffer_ = nullptr;
238
240 mutable QMutex mutex_;
242 QWaitCondition wait_condition_;
244 bool stopped_ = false;
246 bool paused_ = true;
248 int64_t seek_position_ = 0;
254 bool initialized_ = false;
255
257 double frame_rate_ = 0.0;
259 double frame_delay_ = 100.0; // ms
261 QElapsedTimer frame_timer_;
262};
263
264#endif // GIF_DECODER_H
static int ReadPacket(void *opaque, uint8_t *buf, int buf_size)
Custom read function for FFmpeg's AVIOContext. Reads data from the internal gif_data_ QByteArray buff...
Definition gif_decoder.cpp:435
double current_position_
Current playback position in seconds. Access protected by mutex_.
Definition gif_decoder.h:250
GifDecoder(const QByteArray &gif_data, QObject *parent=nullptr)
Constructs a GifDecoder object. Initializes internal state, allocates memory for FFmpeg's custom I/O ...
Definition gif_decoder.cpp:6
int gif_stream_
Index of the video stream within the format context.
Definition gif_decoder.h:233
bool IsPaused() const
Checks if the decoding is currently paused. This operation is thread-safe.
Definition gif_decoder.h:93
unsigned char * io_buffer_
Buffer used by the custom I/O context to hold gif_data_.
Definition gif_decoder.h:231
uint8_t * buffer_
Buffer holding the pixel data for frame_rgb_.
Definition gif_decoder.h:235
void gifInfo(int width, int height, double duration, double frame_rate, int num_of_streams)
Emitted after successful initialization, providing GIF stream details.
void playbackFinished()
Emitted when the decoder reaches the end of the stream (before looping).
double GetDuration() const
Gets the total duration of the GIF in seconds, if available. Reads the duration from the FFmpeg forma...
Definition gif_decoder.h:118
bool Initialize()
Initializes the FFmpeg components for decoding the GIF. Opens the input stream using the custom I/O c...
Definition gif_decoder.cpp:141
int read_position_
Current read position within gif_data_ for the custom I/O context.
Definition gif_decoder.h:216
static int64_t SeekPacket(void *opaque, int64_t offset, int whence)
Custom seek function for FFmpeg's AVIOContext. Adjusts the internal read_position_ based on the offse...
Definition gif_decoder.cpp:449
AVCodecContext * codec_context_
FFmpeg context for the GIF codec.
Definition gif_decoder.h:221
AVFrame * frame_
FFmpeg frame structure to hold the raw decoded frame data.
Definition gif_decoder.h:225
QMutex mutex_
Mutex protecting access to shared state variables from different threads.
Definition gif_decoder.h:240
void ExtractAndEmitFirstFrameInternal()
Internal helper function called by Initialize() to extract and emit the first frame....
Definition gif_decoder.cpp:471
void frameReady(const QImage &frame)
Emitted for each decoded frame of the GIF.
SwsContext * sws_context_
FFmpeg context for image scaling and pixel format conversion (to RGBA).
Definition gif_decoder.h:223
bool stopped_
Flag indicating if the thread should stop execution. Access protected by mutex_.
Definition gif_decoder.h:244
void Resume()
Resumes decoding if paused or starts the thread if not already running. Clears the paused_ flag and w...
Definition gif_decoder.cpp:295
void run() override
The main function executed by the QThread. Contains the loop that reads packets, decodes frames,...
Definition gif_decoder.cpp:312
bool reached_end_of_stream_
Flag indicating if the end of the GIF stream has been reached (before looping). Access protected by m...
Definition gif_decoder.h:252
void Reset()
Resets the playback position to the beginning of the GIF. Seeks the FFmpeg format context to the star...
Definition gif_decoder.cpp:279
bool Reinitialize()
Reinitializes the decoder after it has been stopped or encountered an error. Stops the thread if runn...
Definition gif_decoder.cpp:97
void error(const QString &message)
Emitted when an error occurs during initialization or decoding.
void Pause()
Pauses the decoding loop. Sets the paused_ flag. The thread will wait on the wait_condition_ in its n...
Definition gif_decoder.cpp:272
AVIOContext * io_context_
FFmpeg context for custom I/O operations (reading from memory).
Definition gif_decoder.h:229
bool initialized_
Flag indicating if the Initialize() method has completed successfully. Access protected by mutex_.
Definition gif_decoder.h:254
bool IsDecoderRunning() const
Checks if the decoding thread is currently running.
Definition gif_decoder.h:109
AVFrame * frame_rgb_
FFmpeg frame structure to hold the frame data after conversion to RGBA.
Definition gif_decoder.h:227
QByteArray gif_data_
The raw GIF data provided in the constructor.
Definition gif_decoder.h:214
void ReleaseResources()
Releases all FFmpeg resources (contexts, frames, buffers). Does not release the custom I/O context bu...
Definition gif_decoder.cpp:59
double frame_rate_
Calculated average frame rate of the GIF in frames per second.
Definition gif_decoder.h:257
bool paused_
Flag indicating if playback is currently paused. Access protected by mutex_.
Definition gif_decoder.h:246
int64_t seek_position_
Target timestamp for the pending seek operation (in stream timebase). Access protected by mutex_.
Definition gif_decoder.h:248
QWaitCondition wait_condition_
Condition variable used to pause/resume the decoding thread.
Definition gif_decoder.h:242
QElapsedTimer frame_timer_
Timer used to help synchronize frame emission based on frame_delay_.
Definition gif_decoder.h:261
void Stop()
Stops the decoding thread gracefully. Sets the stopped_ flag, unpauses if necessary,...
Definition gif_decoder.cpp:264
~GifDecoder() override
Destructor. Stops the decoding thread, waits for it to finish, and releases all allocated resources.
Definition gif_decoder.cpp:40
int buffer_size_
Size of the buffer_ in bytes.
Definition gif_decoder.h:237
void positionChanged(double position)
Emitted periodically during playback to indicate the current position.
AVFormatContext * format_context_
FFmpeg context for handling the container format (GIF).
Definition gif_decoder.h:219
void firstFrameReady(const QImage &frame)
Emitted once after successful initialization, containing the first frame. Useful for displaying a sta...
double frame_delay_
Calculated delay between frames in milliseconds.
Definition gif_decoder.h:259