|
Wavelength
Privacy-focused, cross-platform, and open-source communication application
|
Decodes and plays audio data using FFmpeg libraries in a separate thread. More...
#include <audio_decoder.h>
Signals | |
| void | audioInfo (int sample_rate, int channels, double duration) |
| Emitted after successful initialization, providing audio stream details. | |
| void | error (const QString &message) |
| Emitted when an error occurs during initialization or decoding. | |
| void | playbackFinished () |
| Emitted when the decoder reaches the end of the audio stream. | |
| void | positionChanged (double position) |
| Emitted periodically during playback to indicate the current position. | |
Public Member Functions | |
| AudioDecoder (const QByteArray &audio_data, QObject *parent=nullptr) | |
| Constructs an AudioDecoder object. Initializes internal state, allocates memory for FFmpeg's custom I/O context, and copies the provided audio data into an internal buffer. | |
| float | GetVolume () const |
| Gets the current playback volume. This operation is thread-safe. | |
| bool | Initialize () |
| Initializes the FFmpeg components and QAudioOutput for playback. Opens the input stream using the custom I/O context, finds the audio stream and codec, opens the codec, sets up the resampler (to convert to PCM S16LE stereo 44.1 kHz), configures and starts QAudioOutput. Emits audioInfo upon success. This operation is thread-safe and should be called before starting the thread. | |
| bool | IsDecoderRunning () const |
| Checks if the decoding thread is currently running. | |
| bool | IsPaused () const |
| Checks if the playback is currently paused. This operation is thread-safe. | |
| void | Pause () |
| Toggles the paused state of the playback. If paused, playback stops; if unpaused, playback resumes. Wakes the thread if it was waiting due to being paused. This operation is thread-safe. | |
| bool | Reinitialize () |
| Reinitializes the decoder after it has been stopped or encountered an error. Releases existing resources, resets state flags (paused, stopped, seeking, position), reallocates I/O buffer and context if necessary. Does not automatically start playback. This operation is thread-safe. | |
| void | ReleaseResources () |
| Releases all FFmpeg and Qt Multimedia resources. Stops audio output, frees contexts (format, codec, resampler, I/O), frames, and buffers. Resets the initialization flag. This operation is thread-safe. | |
| void | Reset () |
| Resets the playback position to the beginning (0 seconds). Seeks the FFmpeg format context, flushes codec buffers, resets the internal position counter, resets the audio output device, and emits positionChanged(0). This operation is thread-safe. | |
| void | Seek (double position) |
| Seeks to a specific position in the audio stream. The position is specified in seconds. Sets the seeking_ flag and wakes the thread. The actual seek operation happens within the run() loop. This operation is thread-safe. | |
| void | SetVolume (float volume) const |
| Sets the playback volume. The volume is a linear factor between 0.0 (silent) and 1.0 (full volume). This operation is thread-safe. | |
| void | Stop () |
| Stops the decoding thread and playback gracefully. Sets the stopped_ flag and wakes the thread if it's waiting. The thread will then exit its run loop. This operation is thread-safe. | |
| ~AudioDecoder () override | |
| Destructor. Stops the decoding thread, waits for it to finish, and releases all allocated resources. | |
Protected Member Functions | |
| void | DecodeAudioFrame (const AVFrame *audio_frame) const |
| Decodes a single audio frame using the FFmpeg resampler and writes the result to the audio device. | |
| void | run () override |
| The main function executed by the QThread. Contains the loop that reads packets, decodes frames, handles seeking/pausing, updates playback position, and sends decoded audio data to the output device. | |
Static Private Member Functions | |
| static int | ReadPacket (void *opaque, uint8_t *buf, int buf_size) |
| Custom read function for FFmpeg's AVIOContext. Reads data from the internal audio_data_ QByteArray buffer. | |
| 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 offset and whence parameters. Supports SEEK_SET, SEEK_CUR, SEEK_END, and AVSEEK_SIZE. | |
Private Attributes | |
| AVCodecContext * | audio_codec_context_ = nullptr |
| FFmpeg context for the audio codec. | |
| QByteArray | audio_data_ |
| The raw audio data provided in the constructor. | |
| QIODevice * | audio_device_ = nullptr |
| Qt I/O device associated with audio_output_, used for writing PCM data. | |
| QAudioFormat | audio_format_ |
| Qt audio format description (PCM S16LE stereo 44.1kHz). | |
| AVFrame * | audio_frame_ = nullptr |
| FFmpeg frame structure to hold decoded audio data. | |
| QAudioOutput * | audio_output_ = nullptr |
| Qt Multimedia object for audio output. | |
| int | audio_stream_ = -1 |
| Index of the audio stream within the format context. | |
| double | current_position_ = 0 |
| Current playback position in seconds. | |
| AVFormatContext * | format_context_ = nullptr |
| FFmpeg context for handling the container format. | |
| bool | initialized_ = false |
| Flag indicating if the Initialize() method has completed successfully. | |
| unsigned char * | io_buffer_ = nullptr |
| Buffer used by the custom I/O context to hold audio_data_. | |
| AVIOContext * | io_context_ = nullptr |
| FFmpeg context for custom I/O operations (reading from memory). | |
| QMutex | mutex_ |
| Mutex protecting access to shared state variables from different threads. | |
| bool | paused_ = true |
| Flag indicating if playback is currently paused. | |
| bool | reached_end_of_stream_ = false |
| Flag indicating if the end of the audio stream has been reached. | |
| int | read_position_ = 0 |
| Current read position within audio_data_ for the custom I/O context. | |
| int64_t | seek_position_ = 0 |
| Target timestamp for the pending seek operation (in stream timebase). | |
| bool | seeking_ = false |
| Flag indicating if a seek operation is pending. | |
| bool | stopped_ = false |
| Flag indicating if the thread should stop execution. | |
| SwrContext * | swr_context_ = nullptr |
| FFmpeg context for audio resampling (format/rate/channel conversion). | |
| QWaitCondition | wait_condition_ |
| Condition variable used to pause/resume the decoding thread. | |
Decodes and plays audio data using FFmpeg libraries in a separate thread.
This class takes raw audio data (e.g., from a file) as a QByteArray, uses FFmpeg (libavformat, libavcodec, libswresample) to decode it, and plays the resulting PCM audio using Qt Multimedia (QAudioOutput). It runs the decoding and playback loop in a separate QThread to avoid blocking the main UI thread. It supports pausing, seeking, volume control, and provides signals for status updates (errors, position, finish).
|
explicit |
Constructs an AudioDecoder object. Initializes internal state, allocates memory for FFmpeg's custom I/O context, and copies the provided audio data into an internal buffer.
| audio_data | The raw audio data to be decoded. |
| parent | Optional parent QObject. |
|
override |
Destructor. Stops the decoding thread, waits for it to finish, and releases all allocated resources.
|
signal |
Emitted after successful initialization, providing audio stream details.
| sample_rate | The sample rate of the audio in Hz. |
| channels | The number of audio channels. |
| duration | The total duration of the audio in seconds. |
|
protected |
Decodes a single audio frame using the FFmpeg resampler and writes the result to the audio device.
Converts the input frame (audio_frame) to the target format (PCM S16LE stereo 44.1 kHz), allocates a buffer for the converted data, performs the conversion using swr_convert, and writes the resulting data to the QAudioOutput device (audio_device_). Includes logic to wait if the audio device buffer is nearly full. This method is thread-safe regarding access to shared decoder state via mutex_.
| audio_frame | The raw audio frame received from the FFmpeg decoder. |
|
signal |
Emitted when an error occurs during initialization or decoding.
| message | A description of the error. |
| float AudioDecoder::GetVolume | ( | ) | const |
Gets the current playback volume. This operation is thread-safe.
| bool AudioDecoder::Initialize | ( | ) |
Initializes the FFmpeg components and QAudioOutput for playback. Opens the input stream using the custom I/O context, finds the audio stream and codec, opens the codec, sets up the resampler (to convert to PCM S16LE stereo 44.1 kHz), configures and starts QAudioOutput. Emits audioInfo upon success. This operation is thread-safe and should be called before starting the thread.
|
inline |
Checks if the decoding thread is currently running.
| bool AudioDecoder::IsPaused | ( | ) | const |
Checks if the playback is currently paused. This operation is thread-safe.
| void AudioDecoder::Pause | ( | ) |
Toggles the paused state of the playback. If paused, playback stops; if unpaused, playback resumes. Wakes the thread if it was waiting due to being paused. This operation is thread-safe.
|
signal |
Emitted when the decoder reaches the end of the audio stream.
|
signal |
Emitted periodically during playback to indicate the current position.
| position | The current playback position in seconds. |
|
staticprivate |
Custom read function for FFmpeg's AVIOContext. Reads data from the internal audio_data_ QByteArray buffer.
| opaque | Pointer to the AudioDecoder instance. |
| buf | Buffer to read data into. |
| buf_size | Size of the buffer. |
| bool AudioDecoder::Reinitialize | ( | ) |
Reinitializes the decoder after it has been stopped or encountered an error. Releases existing resources, resets state flags (paused, stopped, seeking, position), reallocates I/O buffer and context if necessary. Does not automatically start playback. This operation is thread-safe.
| void AudioDecoder::ReleaseResources | ( | ) |
Releases all FFmpeg and Qt Multimedia resources. Stops audio output, frees contexts (format, codec, resampler, I/O), frames, and buffers. Resets the initialization flag. This operation is thread-safe.
| void AudioDecoder::Reset | ( | ) |
Resets the playback position to the beginning (0 seconds). Seeks the FFmpeg format context, flushes codec buffers, resets the internal position counter, resets the audio output device, and emits positionChanged(0). This operation is thread-safe.
|
overrideprotected |
The main function executed by the QThread. Contains the loop that reads packets, decodes frames, handles seeking/pausing, updates playback position, and sends decoded audio data to the output device.
| void AudioDecoder::Seek | ( | double | position | ) |
Seeks to a specific position in the audio stream. The position is specified in seconds. Sets the seeking_ flag and wakes the thread. The actual seek operation happens within the run() loop. This operation is thread-safe.
| position | The target position in seconds from the beginning of the audio. |
|
staticprivate |
Custom seek function for FFmpeg's AVIOContext. Adjusts the internal read_position_ based on the offset and whence parameters. Supports SEEK_SET, SEEK_CUR, SEEK_END, and AVSEEK_SIZE.
| opaque | Pointer to the AudioDecoder instance. |
| offset | The offset to seek to/by. |
| whence | The seeking mode (SEEK_SET, SEEK_CUR, SEEK_END, AVSEEK_SIZE). |
| void AudioDecoder::SetVolume | ( | float | volume | ) | const |
Sets the playback volume. The volume is a linear factor between 0.0 (silent) and 1.0 (full volume). This operation is thread-safe.
| volume | The desired volume level (0.0 to 1.0). |
| void AudioDecoder::Stop | ( | ) |
Stops the decoding thread and playback gracefully. Sets the stopped_ flag and wakes the thread if it's waiting. The thread will then exit its run loop. This operation is thread-safe.
|
private |
FFmpeg context for the audio codec.
|
private |
The raw audio data provided in the constructor.
|
private |
Qt I/O device associated with audio_output_, used for writing PCM data.
|
private |
Qt audio format description (PCM S16LE stereo 44.1kHz).
|
private |
FFmpeg frame structure to hold decoded audio data.
|
private |
Qt Multimedia object for audio output.
|
private |
Index of the audio stream within the format context.
|
private |
Current playback position in seconds.
|
private |
FFmpeg context for handling the container format.
|
private |
Flag indicating if the Initialize() method has completed successfully.
|
private |
Buffer used by the custom I/O context to hold audio_data_.
|
private |
FFmpeg context for custom I/O operations (reading from memory).
|
mutableprivate |
Mutex protecting access to shared state variables from different threads.
|
private |
Flag indicating if playback is currently paused.
|
private |
Flag indicating if the end of the audio stream has been reached.
|
private |
Current read position within audio_data_ for the custom I/O context.
|
private |
Target timestamp for the pending seek operation (in stream timebase).
|
private |
Flag indicating if a seek operation is pending.
|
private |
Flag indicating if the thread should stop execution.
|
private |
FFmpeg context for audio resampling (format/rate/channel conversion).
|
private |
Condition variable used to pause/resume the decoding thread.