⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jitter.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
   /* 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->buf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size))            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->buf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GT32(jitter->timestamp[i]+jitter->span[i],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->buf[i] && LT32(jitter->timestamp[i],jitter->pointer_timestamp+chunk_size) && GE32(jitter->timestamp[i],jitter->pointer_timestamp))         {            if (!found || LT32(jitter->timestamp[i],best_time) || (jitter->timestamp[i]==best_time && GT32(jitter->span[i],best_span)))            {               best_time = jitter->timestamp[i];               best_span = jitter->span[i];               besti = i;               found = 1;            }         }      }      if (found)      {         i=besti;         incomplete = 1;         /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp, chunk_size, jitter->span[i]);*/      }   }   /* If we find something */   if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)   {      /* We (obviously) haven't lost this packet */      jitter->lost_count = 0;      jitter->loss_rate = .999*jitter->loss_rate;      /* Check for potential overflow */      packet->len = jitter->len[i];      /* Copy packet */      for (j=0;j<packet->len;j++)         packet->data[j] = jitter->buf[i][j];      /* Remove packet */      speex_free(jitter->buf[i]);      jitter->buf[i] = NULL;      /* Set timestamp and span (if requested) */      if (start_offset)         *start_offset = (spx_int32_t)jitter->timestamp[i]-(spx_int32_t)jitter->pointer_timestamp;      packet->timestamp = jitter->timestamp[i];      packet->span = jitter->span[i];      /* Point at the end of the current packet */      jitter->pointer_timestamp = jitter->timestamp[i]+jitter->span[i];      if (incomplete)         return JITTER_BUFFER_INCOMPLETE;      else         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);*/   jitter->loss_rate = .999*jitter->loss_rate + .001;   if (start_offset)      *start_offset = 0;   packet->timestamp = jitter->pointer_timestamp;   packet->span = jitter->tick_size;   jitter->pointer_timestamp += chunk_size;   packet->len = 0;      /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */      if (late_ratio_short > .1 || late_ratio_long > .03)   {      /* If too many packets are arriving late */      jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2];      jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2];      for (i=MAX_MARGIN-3;i>=0;i--)      {         jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i];         jitter->longterm_margin[i+1] = jitter->longterm_margin[i];               }      jitter->shortterm_margin[0] = 0;      jitter->longterm_margin[0] = 0;                  jitter->pointer_timestamp -= jitter->tick_size;      jitter->current_timestamp -= jitter->tick_size;      /*fprintf (stderr, "i");*/      /*fprintf (stderr, "interpolate (getting some slack)\n");*/   }   return JITTER_BUFFER_MISSING;}/** Get pointer timestamp of jitter buffer */int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter){   return jitter->pointer_timestamp;}void jitter_buffer_tick(JitterBuffer *jitter){   jitter->current_timestamp += jitter->tick_size;}/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset){   int i;   float late_ratio_short;   float late_ratio_long;   float ontime_ratio_short;   float ontime_ratio_long;   float early_ratio_short;   float early_ratio_long;      if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp))   {      jitter->current_timestamp = jitter->pointer_timestamp;      speex_warning("did you forget to call jitter_buffer_tick() by any chance?");   }   /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/   /* FIXME: This should be only what remaining of the current tick */   late_ratio_short = 0;   late_ratio_long = 0;   /* Count the proportion of packets that are late */   for (i=0;i<LATE_BINS;i++)   {      late_ratio_short += jitter->shortterm_margin[i];      late_ratio_long += jitter->longterm_margin[i];   }   /* Count the proportion of packets that are just on time */   ontime_ratio_short = jitter->shortterm_margin[LATE_BINS];   ontime_ratio_long = jitter->longterm_margin[LATE_BINS];   early_ratio_short = early_ratio_long = 0;   /* Count the proportion of packets that are early */   for (i=LATE_BINS+1;i<MAX_MARGIN;i++)   {      early_ratio_short += jitter->shortterm_margin[i];      early_ratio_long += jitter->longterm_margin[i];   }      /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */      if (late_ratio_short > .1 || late_ratio_long > .03)   {      /* If too many packets are arriving late */      jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2];      jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2];      for (i=MAX_MARGIN-3;i>=0;i--)      {         jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i];         jitter->longterm_margin[i+1] = jitter->longterm_margin[i];               }      jitter->shortterm_margin[0] = 0;      jitter->longterm_margin[0] = 0;                  jitter->pointer_timestamp -= jitter->tick_size;      jitter->current_timestamp -= jitter->tick_size;      jitter->interp_requested = 1;      return JITTER_BUFFER_ADJUST_INTERPOLATE;      } else if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8)   {      /* Many frames arriving early */      jitter->shortterm_margin[0] += jitter->shortterm_margin[1];      jitter->longterm_margin[0] += jitter->longterm_margin[1];      for (i=1;i<MAX_MARGIN-1;i++)      {         jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1];         jitter->longterm_margin[i] = jitter->longterm_margin[i+1];               }      jitter->shortterm_margin[MAX_MARGIN-1] = 0;      jitter->longterm_margin[MAX_MARGIN-1] = 0;            /*fprintf (stderr, "drop frame\n");*/      /*fprintf (stderr, "d");*/      jitter->pointer_timestamp += jitter->tick_size;      jitter->current_timestamp += jitter->tick_size;      return JITTER_BUFFER_ADJUST_DROP;   }      return JITTER_BUFFER_ADJUST_OK;}/* Used like the ioctl function to control the jitter buffer parameters */int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr){   int count, i;   switch(request)   {      case JITTER_BUFFER_SET_MARGIN:         jitter->buffer_margin = *(spx_int32_t*)ptr;         break;      case JITTER_BUFFER_GET_MARGIN:         *(spx_int32_t*)ptr = jitter->buffer_margin;         break;      case JITTER_BUFFER_GET_AVALIABLE_COUNT:         count = 0;         for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)         {            if (jitter->buf[i] && LE32(jitter->pointer_timestamp, jitter->timestamp[i]))            {               count++;            }         }         *(spx_int32_t*)ptr = count;         break;      default:         speex_warning_int("Unknown jitter_buffer_ctl request: ", request);         return -1;   }   return 0;}void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate){   jitter->dec = decoder;   speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);   jitter->packets = jitter_buffer_init(jitter->frame_size);   speex_bits_init(&jitter->current_packet);   jitter->valid_bits = 0;}void speex_jitter_destroy(SpeexJitter *jitter){   jitter_buffer_destroy(jitter->packets);   speex_bits_destroy(&jitter->current_packet);}void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp){   JitterBufferPacket p;   p.data = packet;   p.len = len;   p.timestamp = timestamp;   p.span = jitter->frame_size;   jitter_buffer_put(jitter->packets, &p);}void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp){   int i;   int ret;   char data[2048];   JitterBufferPacket packet;   packet.data = data;      if (jitter->valid_bits)   {      /* Try decoding last received packet */      ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);      if (ret == 0)      {         jitter_buffer_tick(jitter->packets);         return;      } else {         jitter->valid_bits = 0;      }   }   ret = jitter_buffer_get(jitter->packets, &packet, NULL);      if (ret != JITTER_BUFFER_OK)   {      /* No packet found */      /*fprintf (stderr, "lost/late frame\n");*/      /*Packet is late or lost*/      speex_decode_int(jitter->dec, NULL, out);   } else {      speex_bits_read_from(&jitter->current_packet, packet.data, packet.len);      /* Decode packet */      ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);      if (ret == 0)      {         jitter->valid_bits = 1;      } else {         /* Error while decoding */         for (i=0;i<jitter->frame_size;i++)            out[i]=0;      }   }   jitter_buffer_update_delay(jitter->packets, &packet, NULL);   jitter_buffer_tick(jitter->packets);}int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter){   return jitter_buffer_get_pointer_timestamp(jitter->packets);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -