Play the decoded audio using SDL. The audio player frame sink receives the audio frames, resample them and write them to a byte buffer (introduced by this commit). On SDL audio callback (from an internal SDL thread), copy samples from this byte buffer to the SDL audio buffer. The byte buffer is protected by the SDL_AudioDeviceLock(), but it has been designed so that the producer and the consumer may write and read in parallel, provided that they don't access the same slices of the ring-buffer buffer. Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
55 lines
1.3 KiB
C
55 lines
1.3 KiB
C
#ifndef SC_AUDIO_PLAYER_H
|
|
#define SC_AUDIO_PLAYER_H
|
|
|
|
#include "common.h"
|
|
|
|
#include <stdbool.h>
|
|
#include "trait/frame_sink.h"
|
|
#include <util/average.h>
|
|
#include <util/bytebuf.h>
|
|
#include <util/thread.h>
|
|
|
|
#include <libavformat/avformat.h>
|
|
#include <libswresample/swresample.h>
|
|
#include <SDL2/SDL.h>
|
|
|
|
struct sc_audio_player {
|
|
struct sc_frame_sink frame_sink;
|
|
|
|
SDL_AudioDeviceID device;
|
|
|
|
// protected by SDL_AudioDeviceLock()
|
|
struct sc_bytebuf buf;
|
|
// Number of bytes which could be written without locking
|
|
size_t safe_empty_buffer;
|
|
|
|
struct SwrContext *swr_ctx;
|
|
|
|
// The sample rate is the same for input and output
|
|
unsigned sample_rate;
|
|
// The number of channels is the same for input and output
|
|
unsigned nb_channels;
|
|
|
|
unsigned out_bytes_per_sample;
|
|
|
|
// Target buffer for resampling
|
|
uint8_t *swr_buf;
|
|
size_t swr_buf_alloc_size;
|
|
|
|
// Number of buffered samples (may be negative on underflow)
|
|
struct sc_average avg_buffered_samples;
|
|
unsigned samples_since_resync;
|
|
|
|
const struct sc_audio_player_callbacks *cbs;
|
|
void *cbs_userdata;
|
|
};
|
|
|
|
struct sc_audio_player_callbacks {
|
|
void (*on_ended)(struct sc_audio_player *ap, bool success, void *userdata);
|
|
};
|
|
|
|
void
|
|
sc_audio_player_init(struct sc_audio_player *ap);
|
|
|
|
#endif
|