162 lines
6.0 KiB
C
162 lines
6.0 KiB
C
#ifndef FFMPEG_AUDIO_H
|
|
#define FFMPEG_AUDIO_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef _WIN32
|
|
#ifdef LIB_COMPILE
|
|
#define FFMPEG_EXTERN __declspec(dllexport)
|
|
#else
|
|
#define FFMPEG_EXTERN __declspec(dllimport)
|
|
#endif
|
|
#else
|
|
#define FFMPEG_EXTERN
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
* Audio-only FFmpeg wrapper.
|
|
*
|
|
* The implementation is C++, but the exported API is plain C. The caller never
|
|
* sees FFmpeg objects, stream indices, packets, decoders, or C++ objects.
|
|
*
|
|
* Output audio format is fixed:
|
|
*
|
|
* signed 32-bit integer PCM
|
|
* interleaved / packed
|
|
* native endian
|
|
*
|
|
* A sample frame means one sample moment across all channels. For stereo S32,
|
|
* one sample frame is two int32_t values, therefore 8 bytes.
|
|
*/
|
|
|
|
typedef struct __fmpg_instance__ fmpg_instance;
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* Lifecycle */
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
FFMPEG_EXTERN fmpg_instance *fmpg_init(void);
|
|
FFMPEG_EXTERN void fmpg_free(fmpg_instance *instance);
|
|
|
|
/*
|
|
* Open a media file, select the best audio stream, and create the internal
|
|
* decoder/resampler for that stream.
|
|
*
|
|
* After success, metadata, duration, sample rate and channel count are
|
|
* available through the getters below.
|
|
*
|
|
* Return: 1 on success, 0 on failure.
|
|
*/
|
|
FFMPEG_EXTERN int fmpg_open_file(fmpg_instance *instance, const char *filename);
|
|
|
|
FFMPEG_EXTERN void fmpg_close(fmpg_instance *instance);
|
|
FFMPEG_EXTERN int fmpg_is_open(fmpg_instance *instance);
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* Audio information */
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
FFMPEG_EXTERN int fmpg_audio_stream_count(fmpg_instance *instance);
|
|
FFMPEG_EXTERN int fmpg_audio_sample_rate(fmpg_instance *instance);
|
|
FFMPEG_EXTERN int fmpg_audio_channels(fmpg_instance *instance);
|
|
FFMPEG_EXTERN int fmpg_audio_bits_per_sample(fmpg_instance *instance);
|
|
FFMPEG_EXTERN int fmpg_audio_bytes_per_sample(fmpg_instance *instance);
|
|
|
|
/* Duration in milliseconds, or -1 if unknown. */
|
|
FFMPEG_EXTERN int64_t fmpg_duration_ms(fmpg_instance *instance);
|
|
|
|
/* Duration in output sample frames, or -1 if unknown. */
|
|
FFMPEG_EXTERN int64_t fmpg_duration_samples(fmpg_instance *instance);
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* Metadata */
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
FFMPEG_EXTERN const char *fmpg_file_title(fmpg_instance *instance);
|
|
FFMPEG_EXTERN const char *fmpg_file_author(fmpg_instance *instance);
|
|
FFMPEG_EXTERN const char *fmpg_file_album(fmpg_instance *instance);
|
|
FFMPEG_EXTERN const char *fmpg_file_genre(fmpg_instance *instance);
|
|
FFMPEG_EXTERN const char *fmpg_file_comment(fmpg_instance *instance);
|
|
FFMPEG_EXTERN const char *fmpg_file_copyright(fmpg_instance *instance);
|
|
FFMPEG_EXTERN int fmpg_file_year(fmpg_instance *instance);
|
|
FFMPEG_EXTERN int fmpg_file_track(fmpg_instance *instance);
|
|
FFMPEG_EXTERN int fmpg_file_bitrate(fmpg_instance *instance);
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* Decoding */
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/*
|
|
* Decode the next block of audio.
|
|
*
|
|
* Internally this reads compressed 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 them in the
|
|
* instance output buffer.
|
|
*
|
|
* Non-selected streams are skipped internally. The caller does not handle
|
|
* stream_index, packets, or decoder objects.
|
|
*
|
|
* Return:
|
|
* 1 if PCM data is available through fmpg_buffer()/fmpg_buffer_size()
|
|
* 0 at EOF or on error
|
|
*/
|
|
FFMPEG_EXTERN int fmpg_decode_next(fmpg_instance *instance);
|
|
|
|
/*
|
|
* Seek to an absolute position in milliseconds.
|
|
*
|
|
* FFmpeg may seek to a packet before the requested timestamp. This wrapper
|
|
* decodes and discards pre-roll samples until the requested output sample is
|
|
* reached, when timestamps are available. That makes the exposed sample
|
|
* position match the music position as closely as FFmpeg's timestamps allow.
|
|
*
|
|
* Return: 1 on success, 0 on failure.
|
|
*/
|
|
FFMPEG_EXTERN int fmpg_seek_ms(fmpg_instance *instance, int64_t target_pos_ms);
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* Output buffer and sample positions */
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Pointer to the current decoded PCM buffer. Valid until next API call that
|
|
* decodes, seeks, closes, or frees the instance. */
|
|
FFMPEG_EXTERN const uint8_t *fmpg_buffer(fmpg_instance *instance);
|
|
|
|
/* Size of the current decoded PCM buffer in bytes. */
|
|
FFMPEG_EXTERN int fmpg_buffer_size(fmpg_instance *instance);
|
|
|
|
/* Number of sample frames in the current decoded PCM buffer. */
|
|
FFMPEG_EXTERN int64_t fmpg_buffer_samples(fmpg_instance *instance);
|
|
|
|
/* Absolute sample-frame index of the first sample frame in the current buffer. */
|
|
FFMPEG_EXTERN int64_t fmpg_buffer_start_sample(fmpg_instance *instance);
|
|
|
|
/* Absolute sample-frame index just after the current buffer. */
|
|
FFMPEG_EXTERN int64_t fmpg_buffer_end_sample(fmpg_instance *instance);
|
|
|
|
/*
|
|
* Current absolute sample position in the music stream.
|
|
*
|
|
* This is the same as fmpg_buffer_end_sample() after a successful
|
|
* fmpg_decode_next(): it points just after the last produced sample frame.
|
|
*/
|
|
FFMPEG_EXTERN int64_t fmpg_sample_position(fmpg_instance *instance);
|
|
|
|
/* Approximate start time of the current decoded block in seconds. */
|
|
FFMPEG_EXTERN double fmpg_timecode(fmpg_instance *instance);
|
|
|
|
FFMPEG_EXTERN const char *fmpg_ffmpeg_version();
|
|
FFMPEG_EXTERN const char *fmpg_int_version2string(int ver);
|
|
FFMPEG_EXTERN int fmpg_compatible_ffmpeg();
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|