示例#1
0
/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
{
   spx_int16_t opt = compute_opt_delay(jitter);
   /*fprintf(stderr, "opt adjustment is %d ", opt);*/
   
   if (opt < 0)
   {
      shift_timings(jitter, -opt);
      
      jitter->pointer_timestamp += opt;
      jitter->interp_requested = -opt;
      /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/
   } else if (opt > 0)
   {
      shift_timings(jitter, -opt);
      jitter->pointer_timestamp += opt;
      /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/
   }
   
   return opt;
}
示例#2
0
/** Get one packet from the jitter buffer */
EXPORT int jitter_buffer_get(JitterBuffer * jitter, JitterBufferPacket * packet,
			     spx_int32_t desired_span,
			     spx_int32_t * start_offset)
{
	int i;
	unsigned int j;
	spx_int16_t opt;

	if (start_offset != NULL)
		*start_offset = 0;

	/* Syncing on the first call */
	if (jitter->reset_state) {
		int found = 0;
		/* Find the oldest packet */
		spx_uint32_t oldest = 0;
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			if (jitter->packets[i].data
			    && (!found
				|| LT32(jitter->packets[i].timestamp,
					oldest))) {
				oldest = jitter->packets[i].timestamp;
				found = 1;
			}
		}
		if (found) {
			jitter->reset_state = 0;
			jitter->pointer_timestamp = oldest;
			jitter->next_stop = oldest;
		} else {
			packet->timestamp = 0;
			packet->span = jitter->interp_requested;
			return JITTER_BUFFER_MISSING;
		}
	}

	jitter->last_returned_timestamp = jitter->pointer_timestamp;

	if (jitter->interp_requested != 0) {
		packet->timestamp = jitter->pointer_timestamp;
		packet->span = jitter->interp_requested;

		/* Increment the pointer because it got decremented in the delay update */
		jitter->pointer_timestamp += jitter->interp_requested;
		packet->len = 0;
		/*fprintf (stderr, "Deferred interpolate\n"); */

		jitter->interp_requested = 0;

		jitter->buffered = packet->span - desired_span;

		return JITTER_BUFFER_INSERTION;
	}

	/* Searching for the packet that fits best */

	/* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */
	for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
		if (jitter->packets[i].data
		    && jitter->packets[i].timestamp == jitter->pointer_timestamp
		    && GE32(jitter->packets[i].timestamp +
			    jitter->packets[i].span,
			    jitter->pointer_timestamp + desired_span))
			break;
	}

	/* If no match, try for an "older" packet that still spans (fully) the current chunk */
	if (i == SPEEX_JITTER_MAX_BUFFER_SIZE) {
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			if (jitter->packets[i].data
			    && LE32(jitter->packets[i].timestamp,
				    jitter->pointer_timestamp)
			    && GE32(jitter->packets[i].timestamp +
				    jitter->packets[i].span,
				    jitter->pointer_timestamp + desired_span))
				break;
		}
	}

	/* If still no match, try for an "older" packet that spans part of the current chunk */
	if (i == SPEEX_JITTER_MAX_BUFFER_SIZE) {
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			if (jitter->packets[i].data
			    && LE32(jitter->packets[i].timestamp,
				    jitter->pointer_timestamp)
			    && GT32(jitter->packets[i].timestamp +
				    jitter->packets[i].span,
				    jitter->pointer_timestamp))
				break;
		}
	}

	/* If still no match, try for earliest packet possible */
	if (i == SPEEX_JITTER_MAX_BUFFER_SIZE) {
		int found = 0;
		spx_uint32_t best_time = 0;
		int best_span = 0;
		int besti = 0;
		for (i = 0; i < SPEEX_JITTER_MAX_BUFFER_SIZE; i++) {
			/* check if packet starts within current chunk */
			if (jitter->packets[i].data
			    && LT32(jitter->packets[i].timestamp,
				    jitter->pointer_timestamp + desired_span)
			    && GE32(jitter->packets[i].timestamp,
				    jitter->pointer_timestamp)) {
				if (!found
				    || LT32(jitter->packets[i].timestamp,
					    best_time)
				    || (jitter->packets[i].timestamp ==
					best_time
					&& GT32(jitter->packets[i].span,
						best_span))) {
					best_time =
					    jitter->packets[i].timestamp;
					best_span = jitter->packets[i].span;
					besti = i;
					found = 1;
				}
			}
		}
		if (found) {
			i = besti;
			/*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span); */
		}
	}

	/* If we find something */
	if (i != SPEEX_JITTER_MAX_BUFFER_SIZE) {
		spx_int32_t offset;

		/* We (obviously) haven't lost this packet */
		jitter->lost_count = 0;

		/* In this case, 0 isn't as a valid timestamp */
		if (jitter->arrival[i] != 0) {
			update_timings(jitter,
				       ((spx_int32_t) jitter->packets[i].
					timestamp) -
				       ((spx_int32_t) jitter->arrival[i]) -
				       jitter->buffer_margin);
		}

		/* Copy packet */
		if (jitter->destroy) {
			packet->data = jitter->packets[i].data;
			packet->len = jitter->packets[i].len;
		} else {
			if (jitter->packets[i].len > packet->len) {
				speex_warning_int
				    ("jitter_buffer_get(): packet too large to fit. Size is",
				     jitter->packets[i].len);
			} else {
				packet->len = jitter->packets[i].len;
			}
			for (j = 0; j < packet->len; j++)
				packet->data[j] = jitter->packets[i].data[j];
			/* Remove packet */
			speex_free(jitter->packets[i].data);
		}
		jitter->packets[i].data = NULL;
		/* Set timestamp and span (if requested) */
		offset =
		    (spx_int32_t) jitter->packets[i].timestamp -
		    (spx_int32_t) jitter->pointer_timestamp;
		if (start_offset != NULL)
			*start_offset = offset;
		else if (offset != 0)
			speex_warning_int
			    ("jitter_buffer_get() discarding non-zero start_offset",
			     offset);

		packet->timestamp = jitter->packets[i].timestamp;
		jitter->last_returned_timestamp = packet->timestamp;

		packet->span = jitter->packets[i].span;
		packet->sequence = jitter->packets[i].sequence;
		packet->user_data = jitter->packets[i].user_data;
		/* Point to the end of the current packet */
		jitter->pointer_timestamp =
		    jitter->packets[i].timestamp + jitter->packets[i].span;

		jitter->buffered = packet->span - desired_span;

		if (start_offset != NULL)
			jitter->buffered += *start_offset;

		return JITTER_BUFFER_OK;
	}

	/* If we haven't found anything worth returning */

	/*fprintf (stderr, "not found\n"); */
	jitter->lost_count++;
	/*fprintf (stderr, "m"); */
	/*fprintf (stderr, "lost_count = %d\n", jitter->lost_count); */

	opt = compute_opt_delay(jitter);

	/* Should we force an increase in the buffer or just do normal interpolation? */
	if (opt < 0) {
		/* Need to increase buffering */

		/* Shift histogram to compensate */
		shift_timings(jitter, -opt);

		packet->timestamp = jitter->pointer_timestamp;
		packet->span = -opt;
		/* Don't move the pointer_timestamp forward */
		packet->len = 0;

		jitter->buffered = packet->span - desired_span;
		return JITTER_BUFFER_INSERTION;
		/*jitter->pointer_timestamp -= jitter->delay_step; */
		/*fprintf (stderr, "Forced to interpolate\n"); */
	} else {
		/* Normal packet loss */
		packet->timestamp = jitter->pointer_timestamp;

		desired_span =
		    ROUND_DOWN(desired_span, jitter->concealment_size);
		packet->span = desired_span;
		jitter->pointer_timestamp += desired_span;
		packet->len = 0;

		jitter->buffered = packet->span - desired_span;
		return JITTER_BUFFER_MISSING;
		/*fprintf (stderr, "Normal loss\n"); */
	}

}