X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/9086a105b77eabd940a54e9a394b2500d9495db2..ceb044f4e944cd32110619d50b8ccb6dfddd3ac1:/clients/playrtp.c diff --git a/clients/playrtp.c b/clients/playrtp.c index 68926e6..fe9d1e2 100644 --- a/clients/playrtp.c +++ b/clients/playrtp.c @@ -51,6 +51,9 @@ /** @brief RTP socket */ static int rtpfd; +/** @brief Log output */ +static FILE *logfp; + /** @brief Output device */ static const char *device; @@ -200,8 +203,10 @@ static void *listen_thread(void attribute((unused)) *arg) { } } /* Ignore too-short packets */ - if((size_t)n <= sizeof (struct rtp_header)) + if((size_t)n <= sizeof (struct rtp_header)) { + info("ignored a short packet"); continue; + } p->timestamp = ntohl(packet.header.timestamp); /* Ignore packets in the past */ if(active && lt(p->timestamp, next_timestamp)) { @@ -218,7 +223,7 @@ static void *listen_thread(void attribute((unused)) *arg) { { size_t i; - for(i = 0; i < p->nsamples; ++n) + for(i = 0; i < p->nsamples; ++i) p->samples_float[i] = (int16_t)ntohs(samples[i]) * (0.5f / 32767); } #else @@ -232,13 +237,20 @@ static void *listen_thread(void attribute((unused)) *arg) { fatal(0, "unsupported RTP payload type %d", packet.header.mpt & 0x7F); } + if(logfp) + fprintf(logfp, "sequence %u timestamp %"PRIx32" length %"PRIx32" end %"PRIx32"\n", + ntohs(packet.header.seq), + p->timestamp, p->nsamples, p->timestamp + p->nsamples); pthread_mutex_lock(&lock); /* Stop reading if we've reached the maximum. * * This is rather unsatisfactory: it means that if packets get heavily * out of order then we guarantee dropouts. But for now... */ - while(nsamples >= maxbuffer) - pthread_cond_wait(&cond, &lock); + if(nsamples >= maxbuffer) { + info("buffer full"); + while(nsamples >= maxbuffer) + pthread_cond_wait(&cond, &lock); + } for(pp = &packets; *pp && lt((*pp)->timestamp, p->timestamp); pp = &(*pp)->next) @@ -288,13 +300,14 @@ static OSStatus adioproc if(le(packet_end, next_timestamp)) { /* This packet is in the past */ info("dropping buffered past packet %"PRIx32" < %"PRIx32, - packets->timestamp, next_timestamp); + packet_start, next_timestamp); + drop_first_packet(); continue; } if(ge(next_timestamp, packet_start) && lt(next_timestamp, packet_end)) { /* This packet is suitable */ - const uint32_t offset = next_timestamp - packets->timestamp; + const uint32_t offset = next_timestamp - packet_start; uint32_t samples_available = packet_end - next_timestamp; if(samples_available > samplesOutLeft) samples_available = samplesOutLeft; @@ -303,6 +316,7 @@ static OSStatus adioproc samples_available * sizeof(float)); samplesOut += samples_available; next_timestamp += samples_available; + samplesOutLeft -= samples_available; if(ge(next_timestamp, packet_end)) drop_first_packet(); continue; @@ -316,17 +330,17 @@ static OSStatus adioproc if(samples_available > samplesOutLeft) samples_available = samplesOutLeft; + info("infill by %"PRIu32, samples_available); /* Convniently the buffer is 0 to start with */ next_timestamp += samples_available; samplesOut += samples_available; samplesOutLeft -= samples_available; - /* TODO log infill */ } else { /* There's no next packet at all */ + info("infilled by %zu", samplesOutLeft); next_timestamp += samplesOutLeft; samplesOut += samplesOutLeft; samplesOutLeft = 0; - /* TODO log infill */ } } ++ab; @@ -605,9 +619,13 @@ static void play_rtp(void) { pthread_mutex_lock(&lock); for(;;) { /* Wait for the buffer to fill up a bit */ + info("Buffering..."); while(nsamples < readahead) pthread_cond_wait(&cond, &lock); /* Start playing now */ + info("Playing..."); + next_timestamp = packets->timestamp; + active = 1; status = AudioDeviceStart(adid, adioproc); if(status) fatal(0, "AudioDeviceStart: %d", (int)status); @@ -618,6 +636,7 @@ static void play_rtp(void) { status = AudioDeviceStop(adid, adioproc); if(status) fatal(0, "AudioDeviceStop: %d", (int)status); + active = 0; /* Go back round */ } } @@ -668,7 +687,7 @@ int main(int argc, char **argv) { mem_init(); if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale"); - while((n = getopt_long(argc, argv, "hVdD:m:b:x:", options, 0)) >= 0) { + while((n = getopt_long(argc, argv, "hVdD:m:b:x:L:", options, 0)) >= 0) { switch(n) { case 'h': help(); case 'V': version(); @@ -677,6 +696,7 @@ int main(int argc, char **argv) { case 'm': minbuffer = 2 * atol(optarg); break; case 'b': readahead = 2 * atol(optarg); break; case 'x': maxbuffer = 2 * atol(optarg); break; + case 'L': logfp = fopen(optarg, "w"); break; default: fatal(0, "invalid option"); } }