FFmpeg Audio Backend
1 Overview
The FFmpeg audio backend is a small C++ wrapper with a plain C ABI. It hides the FFmpeg data structures from the caller and exposes a simple audio-only decoder interface.
The caller does not handle FFmpeg streams, packets, frames, codec contexts or resampler objects. A file is opened, the best audio stream is selected, and decoding is performed by repeatedly calling fmpg_decode_next.
The output format is fixed: signed 32-bit integer PCM, interleaved, in native endian format.
A sample frame means one sample moment across all channels. For stereo S32, one sample frame contains two int32_t values and therefore takes 8 bytes.
2 Opaque Instance
typedef struct fmpg_instance fmpg_instance; |
The decoder instance is opaque. The caller only receives and passes around a pointer to this type. All FFmpeg state is stored internally.
3 Lifecycle
fmpg_instance *fmpg_init(void); |
Creates a new decoder instance.
Before allocating the instance, the backend checks whether the FFmpeg major versions used at compile time match the FFmpeg major versions available at runtime. If they do not match, NULL is returned.
Returns a pointer to a new fmpg_instance, or NULL on failure.
void fmpg_free(fmpg_instance *instance); |
Frees the decoder instance. If the instance still has an open input, it is closed as part of destruction.
int fmpg_open_file(fmpg_instance *instance, const char *filename); |
Opens a media file, selects the best audio stream, initializes the decoder and initializes the resampler.
After a successful call, stream information, duration and metadata can be read using the getter functions.
Returns 1 on success and 0 on failure. The call fails if the instance is NULL, if a file is already open, if filename is NULL, if no usable audio stream is found, or if FFmpeg cannot open or initialize the file.
void fmpg_close(fmpg_instance *instance); |
Closes the current file and releases all FFmpeg state owned by the instance. The instance itself remains valid and may be reused.
int fmpg_is_open(fmpg_instance *instance); |
Returns 1 if the instance is open and ready to decode. Otherwise returns 0.
4 Audio Information
int fmpg_audio_stream_count(fmpg_instance *instance); |
int fmpg_audio_sample_rate(fmpg_instance *instance); |
int fmpg_audio_channels(fmpg_instance *instance); |
int fmpg_audio_bits_per_sample(fmpg_instance *instance); |
int fmpg_audio_bytes_per_sample(fmpg_instance *instance); |
int64_t fmpg_duration_ms(fmpg_instance *instance); |
int64_t fmpg_duration_samples(fmpg_instance *instance); |
These functions return information about the selected audio stream.
fmpg_audio_stream_count returns the number of audio streams found in the opened file, or 0.
fmpg_audio_sample_rate returns the selected stream’s sample rate, or 0.
fmpg_audio_channels returns the selected stream’s channel count, or 0.
fmpg_audio_bits_per_sample always returns 32.
fmpg_audio_bytes_per_sample always returns 4.
fmpg_duration_ms returns the duration in milliseconds, or -1.
fmpg_duration_samples returns the duration in output sample frames, or -1.
5 Metadata
const char *fmpg_file_title(fmpg_instance *instance); |
const char *fmpg_file_author(fmpg_instance *instance); |
const char *fmpg_file_album(fmpg_instance *instance); |
const char *fmpg_file_genre(fmpg_instance *instance); |
const char *fmpg_file_comment(fmpg_instance *instance); |
const char *fmpg_file_copyright(fmpg_instance *instance); |
int fmpg_file_year(fmpg_instance *instance); |
int fmpg_file_track(fmpg_instance *instance); |
int64_t fmpg_file_bitrate(fmpg_instance *instance); |
The metadata getters return values read from the container metadata. A missing string value is returned as an empty string. A missing numeric value is returned as -1. fmpg_file_author returns the artist metadata field.
6 Decoding
int fmpg_decode_next(fmpg_instance *instance); |
Decodes the next block of audio.
Internally, the backend reads packets from the selected audio stream, feeds them to the FFmpeg decoder, receives all available decoded frames, converts them to signed 32-bit interleaved PCM, and concatenates the result in the instance output buffer.
Packets from non-selected streams are skipped internally.
Returns 1 if decoded PCM data is available through fmpg_buffer and fmpg_buffer_size. Returns 0 at EOF or on error.
int fmpg_seek_ms(fmpg_instance *instance, int64_t target_pos_ms); |
Seeks to an absolute position in milliseconds.
FFmpeg may seek to a packet before the requested timestamp. After seeking, this backend discards decoded pre-roll samples until the requested output sample position is reached, when timestamps are available.
Returns 1 on success and 0 on failure.
7 Output Buffer and Sample Positions
const uint8_t *fmpg_buffer(fmpg_instance *instance); |
int fmpg_buffer_size(fmpg_instance *instance); |
int64_t fmpg_buffer_samples(fmpg_instance *instance); |
int64_t fmpg_buffer_start_sample(fmpg_instance *instance); |
int64_t fmpg_buffer_end_sample(fmpg_instance *instance); |
int64_t fmpg_sample_position(fmpg_instance *instance); |
double fmpg_timecode(fmpg_instance *instance); |
fmpg_buffer returns a pointer to the current decoded PCM buffer, or NULL if there is no current buffer. The pointer remains valid only until the next API call that decodes, seeks, closes or frees the instance.
fmpg_buffer_size returns the size of the current buffer in bytes. fmpg_buffer_samples returns the number of sample frames in the current buffer. fmpg_buffer_start_sample returns the absolute sample-frame index of the first sample frame in the buffer, and fmpg_buffer_end_sample returns the absolute sample-frame index just after the current buffer.
fmpg_sample_position returns the current absolute sample position in the music stream. After a successful fmpg_decode_next, this is the same value as fmpg_buffer_end_sample.
fmpg_timecode returns the approximate start time of the current decoded block in seconds.
8 FFmpeg Version Checks
const char *fmpg_ffmpeg_version(void); |
const char *fmpg_int_version2string(unsigned version); |
int fmpg_compatible_ffmpeg(void); |
fmpg_ffmpeg_version returns a string describing the FFmpeg versions used when the backend was compiled. The string includes avformat, avcodec, swresample and avutil.
fmpg_int_version2string converts an FFmpeg integer version value to a string of the form major.minor.micro.
fmpg_compatible_ffmpeg checks whether the FFmpeg major versions used at compile time match the FFmpeg major versions available at runtime. It returns 1 when the versions are compatible and 0 otherwise.
9 Decoder Model
The backend uses the modern FFmpeg send/receive decoding model. Packets are sent with avcodec_send_packet, decoded frames are received with avcodec_receive_frame, and conversion to the fixed output format is done with libswresample.
The public API intentionally avoids exposing these details. From the caller perspective, decoding is a sequence of calls to fmpg_decode_next followed by reading the current output buffer and its sample-position metadata.