Stop erroneously assuming that the buffer passed to the player is not changed -- sometimes it is, it seems. Tidy up some typing.
This commit is contained in:
@@ -22,7 +22,7 @@ typedef struct {
|
||||
void (*start)(int sample_rate, int sample_format);
|
||||
|
||||
// block of samples
|
||||
void (*play)(short buf[], int samples);
|
||||
void (*play)(void *buf, int samples);
|
||||
void (*stop)(void);
|
||||
|
||||
// may be null if not implemented
|
||||
|
||||
+6
-7
@@ -40,7 +40,7 @@ static void help(void);
|
||||
static int init(int argc, char **argv);
|
||||
static void deinit(void);
|
||||
static void start(int i_sample_rate, int i_sample_format);
|
||||
static void play(short buf[], int samples);
|
||||
static void play(void *buf, int samples);
|
||||
static void stop(void);
|
||||
static void flush(void);
|
||||
int delay(long *the_delay);
|
||||
@@ -836,7 +836,7 @@ int delay(long *the_delay) {
|
||||
}
|
||||
}
|
||||
|
||||
static void play(short buf[], int samples) {
|
||||
static void play(void *buf, int samples) {
|
||||
// debug(3,"audio_alsa play called.");
|
||||
int ret = 0;
|
||||
if (alsa_handle == NULL) {
|
||||
@@ -867,7 +867,7 @@ static void play(short buf[], int samples) {
|
||||
if (samples == 0)
|
||||
debug(1, "empty buffer being passed to pcm_writei -- skipping it");
|
||||
if ((samples != 0) && (buf != NULL)) {
|
||||
err = alsa_pcm_write(alsa_handle, (char *)buf, samples);
|
||||
err = alsa_pcm_write(alsa_handle, buf, samples);
|
||||
if (err < 0) {
|
||||
debug(1, "Error %d writing %d samples in play(): \"%s\".", err, samples,
|
||||
snd_strerror(err));
|
||||
@@ -893,10 +893,8 @@ static void flush(void) {
|
||||
do_mute(1);
|
||||
if (alsa_handle) {
|
||||
|
||||
debug(1,"Start drain.");
|
||||
if ((derr = snd_pcm_drain(alsa_handle)))
|
||||
debug(1, "Error %d (\"%s\") draining output device.", derr, snd_strerror(derr));
|
||||
debug(1,"Finish drain.");
|
||||
if ((derr = snd_pcm_drop(alsa_handle)))
|
||||
debug(1, "Error %d (\"%s\") dropping output device.", derr, snd_strerror(derr));
|
||||
|
||||
if ((derr = snd_pcm_hw_free(alsa_handle)))
|
||||
debug(1, "Error %d (\"%s\") freeing the output device hardware.", derr, snd_strerror(derr));
|
||||
@@ -904,6 +902,7 @@ static void flush(void) {
|
||||
// flush also closes the device
|
||||
if ((derr = snd_pcm_close(alsa_handle)))
|
||||
debug(1, "Error %d (\"%s\") closing the output device.", derr, snd_strerror(derr));
|
||||
|
||||
alsa_handle = NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&alsa_mutex);
|
||||
|
||||
@@ -452,8 +452,7 @@ static void terminate_decoders(rtsp_conn_info *conn) {
|
||||
static void init_buffer(rtsp_conn_info *conn) {
|
||||
int i;
|
||||
for (i = 0; i < BUFFER_FRAMES; i++)
|
||||
conn->audio_buffer[i].data = malloc(
|
||||
conn->input_bytes_per_frame * (conn->max_frames_per_packet + conn->max_frame_size_change));
|
||||
conn->audio_buffer[i].data = malloc(conn->input_bytes_per_frame * conn->max_frames_per_packet);
|
||||
ab_resync(conn);
|
||||
}
|
||||
|
||||
@@ -1036,13 +1035,13 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
|
||||
// ab_write),ab_read,ab_write);
|
||||
conn->ab_buffering = 0;
|
||||
}
|
||||
signed short *silence;
|
||||
void *silence;
|
||||
// if (fs==0)
|
||||
// debug(2,"Zero length silence buffer needed with gross_frame_gap of %lld and
|
||||
// dac_delay of %lld.",gross_frame_gap,dac_delay);
|
||||
// the fs (number of frames of silence to play) can be zero in the DAC doesn't
|
||||
// start
|
||||
// ouotputting frames for a while -- it could get loaded up but not start
|
||||
// outputting frames for a while -- it could get loaded up but not start
|
||||
// responding
|
||||
// for many milliseconds.
|
||||
if (fs > 0) {
|
||||
@@ -1066,7 +1065,7 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
|
||||
// debug(1,"Back end has no delay function.");
|
||||
// send the appropriate prefiller here...
|
||||
|
||||
signed short *silence;
|
||||
void *silence;
|
||||
if (lead_time != 0) {
|
||||
int64_t frame_gap = (lead_time * config.output_rate) >> 32;
|
||||
// debug(1,"%d frames needed.",frame_gap);
|
||||
@@ -1079,7 +1078,7 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
|
||||
if (silence == NULL)
|
||||
debug(1, "Failed to allocate %d frame silence buffer.", fs);
|
||||
else {
|
||||
// debug(1, "Outputting %d frames of silence.", fs);
|
||||
// debug(1, "No delay function -- outputting %d frames of silence.", fs);
|
||||
memset(silence, 0, conn->output_bytes_per_frame * fs);
|
||||
config.output->play(silence, fs);
|
||||
free(silence);
|
||||
@@ -1546,7 +1545,7 @@ static void *player_thread_func(void *arg) {
|
||||
static char rnstate[256];
|
||||
initstate(time(NULL), rnstate, 256);
|
||||
|
||||
signed short *inbuf, *tbuf, *silence;
|
||||
signed short *inbuf, *tbuf;
|
||||
|
||||
int32_t *sbuf;
|
||||
|
||||
@@ -1597,13 +1596,12 @@ static void *player_thread_func(void *arg) {
|
||||
die("Failed to allocate memory for the transition buffer.");
|
||||
sbuf = 0;
|
||||
// initialise this, because soxr stuffing might be chosen later
|
||||
// if (config.packet_stuffing == ST_soxr) { // needed for stuffing
|
||||
|
||||
sbuf = malloc(sizeof(int32_t) * 2 * (conn->max_frames_per_packet * conn->output_sample_ratio +
|
||||
conn->max_frame_size_change));
|
||||
if (sbuf == NULL)
|
||||
debug(1, "Failed to allocate memory for the sbuf buffer.");
|
||||
// }
|
||||
// We might need an output buffer and a buffer of silence.
|
||||
|
||||
// The size of these dependents on the number of frames, the size of each frame and the maximum
|
||||
// size change
|
||||
outbuf = malloc(
|
||||
@@ -1611,12 +1609,6 @@ static void *player_thread_func(void *arg) {
|
||||
(conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change));
|
||||
if (outbuf == NULL)
|
||||
die("Failed to allocate memory for an output buffer.");
|
||||
silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet *
|
||||
conn->output_sample_ratio);
|
||||
if (silence == NULL)
|
||||
die("Failed to allocate memory for a silence buffer.");
|
||||
memset(silence, 0,
|
||||
conn->output_bytes_per_frame * conn->max_frames_per_packet * conn->output_sample_ratio);
|
||||
conn->first_packet_timestamp = 0;
|
||||
conn->missing_packets = conn->late_packets = conn->too_late_packets = conn->resend_requests = 0;
|
||||
conn->flush_rtp_timestamp =
|
||||
@@ -1695,10 +1687,22 @@ static void *player_thread_func(void *arg) {
|
||||
conn->play_number_after_flush++;
|
||||
if (inframe->timestamp == 0) {
|
||||
debug(3, "Player has supplied a silent frame, (possibly frame %u) for play number %d.",
|
||||
SUCCESSOR(conn->last_seqno_read),play_number);
|
||||
SUCCESSOR(conn->last_seqno_read), play_number);
|
||||
conn->last_seqno_read = (SUCCESSOR(conn->last_seqno_read) &
|
||||
0xffff); // manage the packet out of sequence minder
|
||||
config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio);
|
||||
|
||||
void *silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet *
|
||||
conn->output_sample_ratio);
|
||||
if (silence == NULL) {
|
||||
debug(1, "Failed to allocate memory for a silent frame silence buffer.");
|
||||
} else {
|
||||
// the player may change the contents of the buffer, so it has to be zeroed each time;
|
||||
// might as well malloc and freee it locally
|
||||
memset(silence, 0, conn->output_bytes_per_frame * conn->max_frames_per_packet *
|
||||
conn->output_sample_ratio);
|
||||
config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio);
|
||||
free(silence);
|
||||
}
|
||||
} else if (conn->play_number_after_flush < 10) {
|
||||
/*
|
||||
int64_t difference = 0;
|
||||
@@ -1708,7 +1712,18 @@ static void *player_thread_func(void *arg) {
|
||||
debug(1, "Play number %d, monotonic timestamp %llx, difference
|
||||
%lld.",conn->play_number_after_flush,inframe->timestamp,difference);
|
||||
*/
|
||||
config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio);
|
||||
void *silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet *
|
||||
conn->output_sample_ratio);
|
||||
if (silence == NULL) {
|
||||
debug(1, "Failed to allocate memory for a flush silence buffer.");
|
||||
} else {
|
||||
// the player may change the contents of the buffer, so it has to be zeroed each time;
|
||||
// might as well malloc and freee it locally
|
||||
memset(silence, 0, conn->output_bytes_per_frame * conn->max_frames_per_packet *
|
||||
conn->output_sample_ratio);
|
||||
config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio);
|
||||
free(silence);
|
||||
}
|
||||
} else if (frames_to_drop) {
|
||||
if (frames_to_drop > 3 * config.output_rate)
|
||||
warn("Very large number of frames to drop: %" PRId64 ".", frames_to_drop);
|
||||
@@ -1948,7 +1963,7 @@ static void *player_thread_func(void *arg) {
|
||||
die("Failed to allocate memory for a long_silence buffer of %d frames.",
|
||||
silence_length);
|
||||
memset(long_silence, 0, conn->output_bytes_per_frame * silence_length);
|
||||
config.output->play((short *)long_silence, silence_length);
|
||||
config.output->play(long_silence, silence_length);
|
||||
free(long_silence);
|
||||
}
|
||||
} else {
|
||||
@@ -2085,7 +2100,7 @@ static void *player_thread_func(void *arg) {
|
||||
if (play_samples == 0)
|
||||
debug(1, "play_samples==0 skipping it (1).");
|
||||
else
|
||||
config.output->play((short *)outbuf, play_samples); // remove the (short*)!
|
||||
config.output->play(outbuf, play_samples);
|
||||
}
|
||||
|
||||
// check for loss of sync
|
||||
@@ -2119,7 +2134,7 @@ static void *player_thread_func(void *arg) {
|
||||
if (outbuf == NULL)
|
||||
debug(1, "NULL outbuf to play -- skipping it.");
|
||||
else
|
||||
config.output->play((short *)outbuf, play_samples); // remove the (short*)!
|
||||
config.output->play(outbuf, play_samples); // remove the (short*)!
|
||||
}
|
||||
|
||||
// mark the frame as finished
|
||||
@@ -2314,8 +2329,6 @@ static void *player_thread_func(void *arg) {
|
||||
}
|
||||
if (outbuf)
|
||||
free(outbuf);
|
||||
if (silence)
|
||||
free(silence);
|
||||
if (tbuf)
|
||||
free(tbuf);
|
||||
if (sbuf)
|
||||
|
||||
@@ -302,13 +302,15 @@ void *rtp_control_receiver(void *arg) {
|
||||
|
||||
uint16_t flags = nctohs(&packet[2]);
|
||||
int64_t la = sync_rtp_timestamp - rtp_timestamp_less_latency;
|
||||
debug(3, "Latency derived just from the sync packet is %" PRId64 " frames.", la);
|
||||
// debug(3, "Latency derived just from the sync packet is %" PRId64 " frames.", la);
|
||||
if ((flags == 7) || ((conn->AirPlayVersion > 0) && (conn->AirPlayVersion <= 353))) {
|
||||
la += config.fixedLatencyOffset;
|
||||
debug(3, "A fixed latency offset of %d frames has been added, giving a latency of "
|
||||
"%" PRId64
|
||||
" frames with flags: %d and AirPlay version %d (triggers if 353 or less).",
|
||||
config.fixedLatencyOffset, la, flags, conn->AirPlayVersion);
|
||||
// debug(3, "A fixed latency offset of %d frames has been added, giving a latency of
|
||||
// "
|
||||
// "%" PRId64
|
||||
// " frames with flags: %d and AirPlay version %d (triggers if 353 or
|
||||
// less).",
|
||||
// config.fixedLatencyOffset, la, flags, conn->AirPlayVersion);
|
||||
}
|
||||
if ((conn->maximum_latency) && (conn->maximum_latency < la))
|
||||
la = conn->maximum_latency;
|
||||
|
||||
Reference in New Issue
Block a user