Esempio n. 1
0
static STREAM_STATS_T *stream_stats_create(const struct sockaddr_in *psaRemote,
        unsigned int numWr, unsigned int numRd,
        int rangeMs1, int rangeMs2) {
    STREAM_STATS_T *pStats = NULL;
    unsigned int idx;
    unsigned int periodMs;
    int rangeMs;
    int rc = 0;

    if(!(pStats = (STREAM_STATS_T *) avc_calloc(1, sizeof(STREAM_STATS_T)))) {
        return NULL;
    }

    pStats->active = 1;

    for(idx = 0; idx < THROUGHPUT_STATS_BURSTRATES_MAX; idx++) {

        rangeMs = idx == 0 ? rangeMs1 : rangeMs2;
        if(rangeMs <= 0) {
            continue;
        }

        periodMs = rangeMs / 10;
        rangeMs = periodMs * 10;

        if(rc >= 0 && numWr > 0) {
            // This is used for UDP / RTP output or general TCP based flow queue writing
            rc = burstmeter_init(&pStats->throughput_rt[0].bitratesWr[idx], periodMs, rangeMs);
        }
        if(rc >= 0 && numWr > 1) {
            // This is used for UDP / RTCP output
            rc = burstmeter_init(&pStats->throughput_rt[1].bitratesWr[idx], periodMs, rangeMs);
        }
        if(rc >= 0 && numRd > 0) {
            // This is used for general TCP based flow queue reading
            rc = burstmeter_init(&pStats->throughput_rt[0].bitratesRd[idx], periodMs, rangeMs);
        }
        if(rc < 0) {
            stream_stats_destroy(&pStats, NULL);
            return NULL;
        }

    }

    if(psaRemote) {
        memcpy(&pStats->saRemote, psaRemote, sizeof(pStats->saRemote));
    }
    pStats->numWr = numWr;
    pStats->numRd  = numRd;

    pthread_mutex_init(&pStats->mtx, NULL);

    return pStats;

}
Esempio n. 2
0
int streamxmit_init(STREAM_RTP_DEST_T *pDest, const STREAM_DEST_CFG_T *pDestCfg) {
  unsigned int numPkts = 0;
  unsigned int szPkt;
  int iTmp;
  STREAM_XMIT_QUEUE_T *pAsyncQ = NULL;
  PKTQUEUE_T *pQ = NULL;
  STREAM_STATS_MONITOR_T *pMonitor = NULL;

  if(!pDest || !pDestCfg) {
    return -1;
  }

  pAsyncQ = &pDest->asyncQ;

  if(pDestCfg->pFbReq && pDestCfg->pFbReq->nackRtpRetransmit) {
    pAsyncQ->doRtcpNack = 1; 
  }

  pAsyncQ->doAsyncXmit = 0;  // TODO: implement for packet output smoothing
  //
  // We run if we are to do async RTP xmit 
  // or we support RTP-retransmissions for video (using RTCP NACK notifications) 
  //
  if(!pAsyncQ->doAsyncXmit && (!pAsyncQ->doRtcpNack || pDest->pRtpMulti->isaud)) {
    return 0;
  }

  if(pAsyncQ->doRtcpNack) {

    //
    // Compute an RTP retransmission queue size
    //
    if(pDest->pRtpMulti->pStreamerCfg->xcode.vid.common.cfgDo_xcode &&
      pDest->pRtpMulti->pStreamerCfg->xcode.vid.out[pDestCfg->xcodeOutidx].cfgBitRateOut > 0 &&
      pDest->pRtpMulti->init.maxPayloadSz > 0) {

      iTmp = (pDest->pRtpMulti->pStreamerCfg->xcode.vid.out[pDestCfg->xcodeOutidx].cfgBitRateOut / 
       (8 * 10 * pDest->pRtpMulti->init.maxPayloadSz) + 2) * 10;

      numPkts = MIN(150, MAX(50, iTmp));
    } else {
      numPkts = 100;
    }

//TODO: really only need burstmeter when capping retransmission traffic
    burstmeter_init(&pAsyncQ->retransmissionMeter, 1, 1000);

//pAsyncQ->retransmissionKbpsMax = 30;

  } else {
    numPkts = 40;
  }
  szPkt = pDest->pRtpMulti->init.maxPayloadSz + RTP_HEADER_LEN + DTLS_OVERHEAD_SIZE + 64;

  // No locking!... should rely on pAsyncQ->mtx
  if(!(pQ = pktqueue_create(numPkts, szPkt, 0, 0, 0, sizeof(STREAMXMIT_PKT_HDR_T), 0, 1))) {
    return -1;
  }

  LOG(X_DEBUG("Created RTP %soutput packet queue size: %dB x %dpkts"), pAsyncQ->doRtcpNack ? "NACK " : "", 
              szPkt, numPkts);

  pQ->cfg.overwriteType = PKTQ_OVERWRITE_OK;
  pQ->cfg.id = STREAMER_QID_NACK;
  pktqueue_setrdr(pQ, 0);
  pthread_mutex_init(&pAsyncQ->mtx, NULL);
  pAsyncQ->nackHistoryMs = RTP_RETRANSMIT_HISTORY_MS;
  pAsyncQ->pQ = pQ;

  //
  // Start the RTP output queue processor thread
  //
  if(pDestCfg->pMonitor && pDestCfg->pMonitor->active) {
    pMonitor = pDestCfg->pMonitor; 
  }
  streamxmit_async_start(pDest->pRtpMulti, pMonitor, 0);

  return 0;
}