示例#1
0
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);
}
示例#2
0
// 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;
    }
}
示例#3
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;
        }
    }
}
示例#4
0
文件: player.c 项目: peec/shairport
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);
}
示例#5
0
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);
}