void player_put_packet(seq_t seqno, uint8_t *data, int len) { abuf_t *abuf = 0; int16_t buf_fill; pthread_mutex_lock(&ab_mutex); if (!ab_synced) { debug(1, "syncing to first seqno %04X\n", seqno); ab_write = seqno-1; ab_read = seqno; ab_synced = 1; } if (seq_diff(ab_write, seqno) == 1) { // expected packet abuf = audio_buffer + BUFIDX(seqno); ab_write = seqno; } else if (seq_order(ab_write, seqno)) { // newer than expected // Be careful with new packets that are in advance // Those more than a buffer size in advance will cause an Overrun // When buffering the valid threshold should be the buffer fill target itself which should re-sync if (ab_buffering && (seq_diff(ab_read, seqno) > config.buffer_start_fill)) { warn("out of range re-sync %04X (%04X:%04X)", seqno, ab_read, ab_write); ab_resync(); ab_synced = 1; ab_read = seqno; ab_write = seqno; abuf = audio_buffer + BUFIDX(seqno); } else { debug(1, "advance packet %04X (%04X:%04X)\n", seqno, ab_read, ab_write); rtp_request_resend(ab_write+1, seqno-1); abuf = audio_buffer + BUFIDX(seqno); ab_write = seqno; } } else if (seq_order(ab_read, seqno)) { // late but not yet played abuf = audio_buffer + BUFIDX(seqno); if (abuf->ready) { // discard this frame if frame previously received abuf =0; debug(1, "duplicate packet %04X (%04X:%04X)\n", seqno, ab_read, ab_write); } } else { // too late. debug(1, "late packet %04X (%04X:%04X)\n", seqno, ab_read, ab_write); } buf_fill = seq_diff(ab_read, ab_write); pthread_mutex_unlock(&ab_mutex); if (abuf) { alac_decode(abuf->data, data, len); abuf->ready = 1; } pthread_mutex_lock(&ab_mutex); if (ab_buffering && buf_fill >= config.buffer_start_fill) { debug(1, "buffering over. starting play (%04X:%04X)\n", ab_read, ab_write); ab_buffering = 0; } pthread_mutex_unlock(&ab_mutex); }
// get the next frame, when available. return 0 if underrun/stream reset. static inline short buffer_get_frame(signed short **inbuf) { unsigned short buf_fill; seq_t read; pthread_mutex_lock(&ab_mutex); buf_fill=BUF_FILL_SIZE(ab_write,ab_read); #ifdef DEBUG fprintf(stderr,"ab_write=%d ab_read=%d buf_fill=%d ab_buffering=%d\n",ab_write,ab_read,buf_fill,ab_buffering); #endif if (buf_fill < 1 || !ab_synced || ab_buffering) { // init or underrun. stop and wait #ifdef DEBUG if (ab_synced) fprintf(stderr, "\nunderrun.\n"); #endif ab_buffering = 1; pthread_cond_wait(&ab_buffer_ready, &ab_mutex); ab_read++; buf_fill=BUF_FILL_SIZE(ab_write,ab_read); bf_est_reset(buf_fill); pthread_mutex_unlock(&ab_mutex); return 0; } if (buf_fill < BUFFER_FRAMES) { #ifdef DEBUG fprintf(stderr, "pthread_cond_signal ab_buffer_full\n"); #endif pthread_cond_signal(&ab_buffer_full); } read = ab_read; ab_read++; buf_fill=BUF_FILL_SIZE(ab_write,ab_read); bf_est_update(buf_fill); abuf_t *curframe = audio_buffer + BUFIDX(read); if (curframe->ready) { alac_decode(*inbuf, curframe->data, curframe->len); curframe->ready = 0; pthread_mutex_unlock(&ab_mutex); return 1; } else { #ifdef DEBUG fprintf(stderr, "\nmissing frame.\n"); #endif curframe->ready = 0; pthread_mutex_unlock(&ab_mutex); return 0; } }
void buffer_put_packet(seq_t seqno, char *data, int len) { volatile abuf_t *abuf = 0; short read; short buf_fill; pthread_mutex_lock(&ab_mutex); if (!ab_synced) { ab_write = seqno; ab_read = seqno-1; ab_synced = 1; } if (seqno == ab_write+1) { // expected packet abuf = audio_buffer + BUFIDX(seqno); ab_write = seqno; } else if (seq_order(ab_write, seqno)) { // newer than expected rtp_request_resend(ab_write, seqno-1); abuf = audio_buffer + BUFIDX(seqno); ab_write = seqno; } else if (seq_order(ab_read, seqno)) { // late but not yet played abuf = audio_buffer + BUFIDX(seqno); } else { // too late. fprintf(stderr, "\nlate packet %04X (%04X:%04X)\n", seqno, ab_read, ab_write); } buf_fill = ab_write - ab_read; pthread_mutex_unlock(&ab_mutex); if (abuf) { alac_decode(abuf->data, data, len); abuf->ready = 1; } if (ab_buffering && buf_fill >= buffer_start_fill) { ab_buffering = 0; pthread_cond_signal(&ab_buffer_ready); } if (!ab_buffering) { // check if the t+10th packet has arrived... last-chance resend read = ab_read + 10; abuf = audio_buffer + BUFIDX(read); if (abuf->ready != 1) { rtp_request_resend(read, read); abuf->ready = -1; } } }
void player_put_packet(seq_t seqno, uint8_t *data, int len) { abuf_t *abuf = 0; int16_t buf_fill; pthread_mutex_lock(&ab_mutex); if (!ab_synced) { debug(2, "syncing to first seqno %04X\n", seqno); ab_write = seqno-1; ab_read = seqno; ab_synced = 1; } if (seq_diff(ab_write, seqno) == 1) { // expected packet abuf = audio_buffer + BUFIDX(seqno); ab_write = seqno; } else if (seq_order(ab_write, seqno)) { // newer than expected rtp_request_resend(ab_write+1, seqno-1); abuf = audio_buffer + BUFIDX(seqno); ab_write = seqno; } else if (seq_order(ab_read, seqno)) { // late but not yet played abuf = audio_buffer + BUFIDX(seqno); } else { // too late. debug(1, "late packet %04X (%04X:%04X)", seqno, ab_read, ab_write); } buf_fill = seq_diff(ab_read, ab_write); pthread_mutex_unlock(&ab_mutex); if (abuf) { alac_decode(abuf->data, data, len); abuf->ready = 1; } pthread_mutex_lock(&ab_mutex); if (ab_buffering && buf_fill >= config.buffer_start_fill) { debug(1, "buffering over. starting play\n"); ab_buffering = 0; bf_est_reset(buf_fill); } pthread_mutex_unlock(&ab_mutex); }
void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len) { pthread_mutex_lock(&ab_mutex); packet_count++; time_of_last_audio_packet = get_absolute_time_in_fp(); if (connection_state_to_output) { // if we are supposed to be processing these packets if ((flush_rtp_timestamp != 0) && ((timestamp == flush_rtp_timestamp) || seq32_order(timestamp, flush_rtp_timestamp))) { debug(2, "Dropping flushed packet in player_put_packet, seqno %u, timestamp %u, flushing to " "timestamp: %u.", seqno, timestamp, flush_rtp_timestamp); } else { if ((flush_rtp_timestamp != 0x0) && (!seq32_order(timestamp, flush_rtp_timestamp))) // if we have gone past the flush boundary time flush_rtp_timestamp = 0x0; abuf_t *abuf = 0; if (!ab_synced) { debug(2, "syncing to seqno %u.", seqno); ab_write = seqno; ab_read = seqno; ab_synced = 1; } if (ab_write == seqno) { // expected packet abuf = audio_buffer + BUFIDX(seqno); ab_write = SUCCESSOR(seqno); } else if (seq_order(ab_write, seqno)) { // newer than expected // if (ORDINATE(seqno)>(BUFFER_FRAMES*7)/8) // debug(1,"An interval of %u frames has opened, with ab_read: %u, ab_write: %u and seqno: // %u.",seq_diff(ab_read,seqno),ab_read,ab_write,seqno); int32_t gap = seq_diff(ab_write, PREDECESSOR(seqno)) + 1; if (gap <= 0) debug(1, "Unexpected gap size: %d.", gap); int i; for (i = 0; i < gap; i++) { abuf = audio_buffer + BUFIDX(seq_sum(ab_write, i)); abuf->ready = 0; // to be sure, to be sure abuf->timestamp = 0; abuf->sequence_number = 0; } // debug(1,"N %d s %u.",seq_diff(ab_write,PREDECESSOR(seqno))+1,ab_write); abuf = audio_buffer + BUFIDX(seqno); rtp_request_resend(ab_write, gap); resend_requests++; ab_write = SUCCESSOR(seqno); } else if (seq_order(ab_read, seqno)) { // late but not yet played late_packets++; abuf = audio_buffer + BUFIDX(seqno); } else { // too late. too_late_packets++; /* if (!late_packet_message_sent) { debug(1, "too-late packet received: %u; ab_read: %u; ab_write: %u.", seqno, ab_read, ab_write); late_packet_message_sent=1; } */ } // pthread_mutex_unlock(&ab_mutex); if (abuf) { alac_decode(abuf->data, data, len); abuf->ready = 1; abuf->timestamp = timestamp; abuf->sequence_number = seqno; } // pthread_mutex_lock(&ab_mutex); } int rc = pthread_cond_signal(&flowcontrol); if (rc) debug(1, "Error signalling flowcontrol."); } pthread_mutex_unlock(&ab_mutex); }