FFmpeg Decoder
| (require (file "../ffmpeg-decoder.rkt")) | package: base |
This module provides an audio decoder based on the FFmpeg audio shim. It uses the lower-level racket-sound/ffmpeg-ffi module and presents a callback-based decoder interface comparable to the other audio decoders.
The native FFmpeg layer decodes audio to signed 32-bit interleaved PCM. The decoder therefore reports 32 bits per sample and 4 bytes per sample when no more specific information is available.
This predicate is deliberately weak. Existence and extension checks are expected to be performed by the generic audio-decoder layer. Actual file validation is done when the FFmpeg shim opens the file.
procedure
(ffmpeg-open audio-file cb-stream-info cb-audio) → (or/c any/c #f) audio-file : (or/c path? string?) cb-stream-info : procedure? cb-audio : procedure?
If audio-file is a path, it is converted to a string before it is passed to the native layer.
The cb-stream-info callback is called with a mutable hash that describes the stream. The cb-audio callback is called with the same kind of hash, a PCM buffer pointer and the buffer size in bytes.
This function loops until decoding reaches the end of the stream or until ffmpeg-stop requests termination. During the read loop, pending seek requests made with ffmpeg-seek are applied before the next native read.
The stream-info callback is called when format information becomes available. The audio callback is called as:
(cb-audio info buffer size)
where info is a mutable hash, buffer is a pointer to interleaved signed 32-bit PCM data, and size is the size of the buffer in bytes.
When reading stops, the native FFmpeg instance is closed and deleted.
The percentage argument is interpreted as a percentage of the total number of samples in the stream. Fractional percentages are allowed. The actual seek is performed by ffmpeg-read before the next native read call.
If the total sample count is unknown or invalid, no seek request is made.
This function waits until ffmpeg-read has left its read loop. It polls the internal reading flag with a short sleep interval.
1 Stream Information
The stream-info and audio callbacks receive a mutable hash. The decoder stores at least the following keys:
'sample-rate
'channels
'bits-per-sample
'bytes-per-sample
'total-samples
'duration
For audio callbacks, the hash is also updated with:
'sample, the current sample position
'current-time, the current time in seconds
If the native layer omits format values, the decoder fills in the most recent known values. Initial defaults are 44100 Hz, 2 channels, 32 bits per sample and 4 bytes per sample.
2 Decoding Model
The decoder keeps a small Racket handle around the native FFmpeg handler. The handle stores the callbacks, stop and seek state, the current reading state and the current format hash.
Seeking is asynchronous with respect to ffmpeg-seek: the function only records the requested target sample. The read loop applies the pending seek request before decoding the next block.
3 Notes
The FFmpeg shim output is expected to be signed 32-bit interleaved PCM. This keeps the decoder interface suitable for a playback pipeline that feeds decoded audio to libao.