Ejemplo n.º 1
0
int flvsrv_record_start(FLVSRV_CTXT_T *pFlvCtxt, STREAMER_OUTFMT_T *pLiveFmt) {
  int rc = 0;
  unsigned int numQFull = 0;

  if(!pFlvCtxt || !pLiveFmt) {
    return -1;
  }

  //
  // Add a livefmt cb
  //
  pFlvCtxt->pRecordOutFmt = outfmt_setCb(pLiveFmt, flvsrv_addFrame, pFlvCtxt, 
                                         &pLiveFmt->qCfg, NULL, 0, 0, &numQFull);

  if(pFlvCtxt->pRecordOutFmt) {

   if(flvsrv_init(pFlvCtxt, pLiveFmt->qCfg.growMaxPktLen) < 0) {
      return rc;
    }
    pFlvCtxt->cbWrite = flvsrv_cbWriteDataFile;

    LOG(X_INFO("Starting flvlive recording[%d] %d/%d to %s"), pFlvCtxt->pRecordOutFmt->cbCtxt.idx, 
        numQFull + 1, pLiveFmt->max, pFlvCtxt->recordFile.filename);

  } else {
    LOG(X_ERROR("No flvlive recording resource available (max:%d)"), (pLiveFmt ? pLiveFmt->max : 0));
  }

  return rc;
}
Ejemplo n.º 2
0
int flvsrv_cbWriteDataFile(void *pArg, const unsigned char *pData, unsigned int len) {
  int rc = 0;
  FLVSRV_CTXT_T *pFlvCtxt = (FLVSRV_CTXT_T *) pArg;

  //fprintf(stderr, "CB FLV RECORD len:%d\n", len);

  if(pFlvCtxt->recordFile.fp == FILEOPS_INVALID_FP) {

    if(capture_openOutputFile(&pFlvCtxt->recordFile, pFlvCtxt->overwriteFile, NULL) < 0) {

      // Do not call outfmt_removeCb since we're invoked from the cb thread
      //outfmt_removeCb(pFlvCtxt->pRecordOutFmt);
      pFlvCtxt->pRecordOutFmt->do_outfmt = 0;
      pFlvCtxt->pRecordOutFmt = NULL;

      return -1;
    }
    LOG(X_INFO("Created flv recording output file %s"), pFlvCtxt->recordFile.filename);
   
  }

  if((rc = WriteFileStream(&pFlvCtxt->recordFile, pData, len)) < 0) {
    LOG(X_ERROR("Failed to write flv %s %u bytes, total: %llu)"),
               (pFlvCtxt->writeErrDescr ? pFlvCtxt->writeErrDescr : ""), len, pFlvCtxt->totXmit);
  } else {
    pFlvCtxt->totXmit += len;
  }

  return rc;
}
Ejemplo n.º 3
0
static void srvlisten_rtmplive_proc(void *pArg) {

  SRV_LISTENER_CFG_T *pListenCfg = (SRV_LISTENER_CFG_T *) pArg;
  NETIO_SOCK_T netsocksrv;
  struct sockaddr_in  sa;
  int rc = 0;
  char buf[SAFE_INET_NTOA_LEN_MAX];

  logutil_tid_add(pthread_self(), pListenCfg->tid_tag);

  memset(&sa, 0, sizeof(sa));
  memset(&netsocksrv, 0, sizeof(netsocksrv));
  sa.sin_family = PF_INET;
  sa.sin_addr = pListenCfg->sain.sin_addr;
  sa.sin_port = pListenCfg->sain.sin_port;
  netsocksrv.flags = pListenCfg->netflags;

  if((NETIOSOCK_FD(netsocksrv) = net_listen(&sa, 5)) == INVALID_SOCKET) {
    logutil_tid_remove(pthread_self());
    return;
  }

  pthread_mutex_lock(&pListenCfg->mtx);
  pListenCfg->pnetsockSrv = &netsocksrv; 
  pthread_mutex_unlock(&pListenCfg->mtx);

  LOG(X_INFO("rtmp %sserver available at rtmp://%s:%d max:%d"), 
           ((pListenCfg->netflags & NETIO_FLAG_SSL_TLS) ? "(SSL) " : ""), 
           net_inet_ntoa(sa.sin_addr, buf), ntohs(sa.sin_port), pListenCfg->max);

  //
  // Service any client connections on the live listening port
  //
  rc = srvlisten_loop(pListenCfg, srv_rtmp_proc);

  pthread_mutex_lock(&pListenCfg->mtx);
  pListenCfg->pnetsockSrv = NULL; 
  netio_closesocket(&netsocksrv);
  pthread_mutex_unlock(&pListenCfg->mtx);

  LOG(X_WARNING("rtmp listener thread exiting with code: %d"), rc);

  logutil_tid_remove(pthread_self());

  return;
}
Ejemplo n.º 4
0
  T operator()(RawArray<const T,2> x) const {
    // Temporary arrays and views
    GEODE_ASSERT(x.sizes()==vec(n+3,d));

    // Collect quadrature points
    Array<T,2> tq(n,quads,uninit);
    Array<T,3> xq(n,quads,d,uninit);
    Array<T,3> vq(n,quads,d,uninit);
    for (int i=0;i<n;i++) {
      T_INFO(i)
      for (int q=0;q<quads;q++) {
        const T s = samples[q];
        tq(i,q) = t1+dt*s;
        SPLINE_INFO(s)
        for (int a=0;a<d;a++) {
          X_INFO(i,a)
          xq(i,q,a) = a0*x0+a1*x1+a2*x2+a3*x3;
          vq(i,q,a) = b0*x0+b1*x1+b2*x2+b3*x3;
        }
      }
    }

    // Compute energy
    const auto Uq_ = U(tq.reshape_own(n*quads),NdArray<const T>(qshape,xq.flat),NdArray<const T>(qshape,vq.flat));
    GEODE_ASSERT(Uq_.size()==n*quads);
    const auto Uq = Uq_.reshape(n,quads);

    // Accumulate
    T sum = 0;
    for (int i=0;i<n;i++) {
      const T dt = t[i+2]-t[i+1];
      for (int q=0;q<quads;q++)
        sum += weights[q]*dt*Uq(i,q);
    }
    return sum;
  }
Ejemplo n.º 5
0
int mp4_extractRaw(const MP4_CONTAINER_T *pMp4, const char *outPrfx, 
                   float fStart, float fDuration, int overwrite,
                   int extractVid, int extractAud) {

  BOX_HDLR_T *pBoxHdlr;
  BOX_T *pBoxTrak;
  BOX_T *pBox;
  MP4_TRAK_T mp4Trak;
  char *outPath = NULL;
  size_t szPath;
  FILE_HANDLE fp;
  int rc = 0;

  if(!pMp4|| !pMp4->pStream || !pMp4->pStream->cbCheckFd(pMp4->pStream) ||
     !outPrfx) {
    return -1;
  } else if(!extractVid && !extractAud) {
    return -1;
  }

  if(!(pBoxTrak = mp4_findBoxInTree(pMp4->proot, *((uint32_t *) "moov"))) || 
     !(pBoxTrak = pBoxTrak->child)) {
    LOG(X_ERROR("No tracks found in mp4"));
    return -1;
  }

  while(pBoxTrak) {

    if(pBoxTrak->type != *((uint32_t *) "trak") ||
       !(pBoxHdlr = (BOX_HDLR_T *) mp4_findBoxInTree(pBoxTrak, *((uint32_t *) "hdlr")))) {

      pBoxTrak = pBoxTrak->pnext;
      continue;
    }

    memset(&mp4Trak, 0, sizeof(MP4_TRAK_T));
    mp4Trak.pTrak = pBoxTrak;
    pBox = fillTrack(&mp4Trak, 0);

    if(!pBox) {
      pBoxTrak = pBoxTrak->pnext;
      continue;
    }

    szPath = strlen(outPrfx);
    outPath = (char *) avc_calloc(1, szPath + 8);
    memcpy(outPath, outPrfx, szPath);
    rc = 0;

    if(pBoxHdlr->handlertype == *((uint32_t *) "soun") ||
       pBoxHdlr->handlertype == *((uint32_t *) "sdsm")) {

      if(extractAud) {
        if(mp4_findBoxInTree(pBoxTrak,  *((uint32_t *) "mp4a"))) {
          strncpy(&outPath[szPath], ".aac", 7);
        } else {
          LOG(X_WARNING("Unknown audio track %c%c%c%c written as raw output"), 
                ((unsigned char *)&pBox->type)[0], ((unsigned char *)&pBox->type)[1],
                ((unsigned char *)&pBox->type)[2], ((unsigned char *)&pBox->type)[3]);
          strncpy(&outPath[szPath], ".araw", 7);
        }
      } else {
        pBox = NULL;
      }    

    } else if(pBoxHdlr->handlertype == *((uint32_t *) "vide")) {

      if(extractVid) {
        if(mp4_findBoxInTree(pBoxTrak,  *((uint32_t *) "avc1"))) {
          strncpy(&outPath[szPath], ".h264", 7);
        } else if(mp4_findBoxInTree(pBoxTrak,  *((uint32_t *) "mp4v"))) {
          strncpy(&outPath[szPath], ".mpg4", 7);
        } else {
          LOG(X_WARNING("Unknown video track %c%c%c%c written as raw output"), 
                ((unsigned char *)&pBox->type)[0], ((unsigned char *)&pBox->type)[1],
                ((unsigned char *)&pBox->type)[2], ((unsigned char *)&pBox->type)[3]);
          strncpy(&outPath[szPath], ".vraw", 7);
        }
      } else {
        pBox = NULL;
      }    

    } else {
      pBox = NULL; 
    }

    if(pBox) {

      if(!overwrite && (fp = fileops_Open(outPath, O_RDONLY)) != FILEOPS_INVALID_FP) {
         fileops_Close(fp);
         LOG(X_ERROR("File %s already exists.  Will not overwrite."), outPath);
         free(outPath);
         pBoxTrak = pBoxTrak->pnext;
         continue;
      }

      if(pBox->type == *((uint32_t *) "avc1")) {
        rc = mp4_extractAvcVid(pMp4, outPath, fStart, fDuration);
      } else if(pBox->type == *((uint32_t *) "mp4v")) {
        rc = mp4_extractMp4Vid(pMp4, outPath, fStart, fDuration);
      } else if(pBox->type == *((uint32_t *) "mp4a")) {
        rc = mp4_extractAacAud(pMp4, outPath, fStart, fDuration);
      } else {
        rc = extractGenericTrak(pMp4, &mp4Trak, outPath, fStart, fDuration);
      }

      if(rc == 0) {
        LOG(X_INFO("Created %s"), outPath);
      }
      free(outPath);

    }

    pBoxTrak = pBoxTrak->pnext;
  }


  return rc;
} 
Ejemplo n.º 6
0
int stream_udp(STREAM_XMIT_NODE_T *pList, double durationSec) {
  STREAM_XMIT_NODE_T *pStream;
  COLLECT_STREAM_PKTDATA_T collectPkt;
  int triedXmit;
  unsigned int idxDest;
  TIME_VAL tmstart, tm1, tmnow;
  TIME_VAL tmprevbwdescr;
  int rc;
  int sz;
  int szPkt;
  unsigned int szData;
  const unsigned char *pData;
  unsigned int szDataPayload;
  const unsigned char *pDataPayload;
  uint64_t totBytes = 0;
  unsigned int totPkts = 0;
  unsigned int bytes = 0;
  unsigned int pkts = 0;
  unsigned int bytes2 = 0;
  unsigned int pkts2 = 0;
  //char dstStr[64];
#ifndef WIN32
  unsigned int countIterations = 0;
#endif // WIN32

  if(!pList 
#if defined(VSX_HAVE_LICENSE)
   || !pList->pLic
#endif // VSX_HAVE_LICENSE
     ) {
    return -1;
  }

  //snprintf(dstStr, sizeof(dstStr), "%s:%d", inet_ntoa(pList->pRtpMulti->pdests[0].saDsts.sin_addr), 
  //            ntohs(pList->pRtpMulti->pdests[0].saDsts.sin_port));

  tmstart = tmnow = timer_GetTime();
  tm1 = tmstart;
  tmprevbwdescr = tmstart;


  while(*pList->prunning == STREAMER_STATE_RUNNING && !g_proc_exit) {

    pStream = pList;
    triedXmit = 0;

    while(pStream) {

      if((rc = pStream->cbCanSend(pStream->pCbData)) > 0) {

        pData = stream_rtp_data(pStream->pRtpMulti);
        szData = stream_rtp_datalen(pStream->pRtpMulti);

        if(szData >= RTP_HEADER_LEN) {
          pDataPayload = pData + RTP_HEADER_LEN;
          szDataPayload = szData - RTP_HEADER_LEN;
        } else {
          pDataPayload = NULL;
          szDataPayload = 0;
        }

        if(pStream->pXmitAction->do_stream) {
          triedXmit = 1;

          totPkts++;
          pkts++;
          pkts2++;

          if(pStream->pXmitAction->do_output) {

            szPkt = 0;
            for(idxDest = 0; idxDest < pStream->pRtpMulti->numDests; idxDest++) {
  
              if(pStream->pXmitDestRc[idxDest] != 0) {
                continue;
              }
              if(pStream->rawSend) {
                if(pktgen_Queue(pData, szData) != 0) {
                  pStream->pXmitDestRc[idxDest] = -1; 
                  sz = -1;
                } else {
                  sz = szData;
                }
              } else {

                //
                // Check and send an rtcp sender report
                //
                if(*pStream->pfrtcp_sr_intervalsec > 0 &&
                  (tmnow - pStream->pRtpMulti->pdests[idxDest].tmLastRtcpSr) / TIME_VAL_MS  > 
                         *pStream->pfrtcp_sr_intervalsec * 1000) {
                  sendRtcpSr(pStream, idxDest);
                  pStream->pRtpMulti->pdests[idxDest].tmLastRtcpSr = tmnow;
                } 

                if((sz = sendPktUdpRtp(pStream, idxDest, pData, szData)) < 0) {
                  pStream->pXmitDestRc[idxDest] = sz; 
                }
              }
              if(szPkt == 0 && sz > 0) {
                szPkt = sz; 
              }
            } // end of for

            // Exit if there are no good transmitters in the list
            if(pStream->pXmitAction->do_output && szPkt == 0) {
              return -1;
            }

          } else {    // if do_output
            szPkt = szData;
          }

          if(!pStream->pXmitAction->do_output_rtphdr && szPkt > RTP_HEADER_LEN) {
            szPkt -= RTP_HEADER_LEN;
          }

          totBytes += szPkt;
          bytes += szPkt;

          //
          // Add the packet data to any outbound avclive subscribers
          //
          // TODO: do not hardcode szData > RTP_HEADER_LEN rtp hdr len
          if(pStream->pLiveQ && pStream->pLiveQ->numActive > 0 && szDataPayload > 0) {
            pthread_mutex_lock(&pStream->pLiveQ->mtx);
            for(sz = 0; (unsigned int) sz < pStream->pLiveQ->max; sz++) {
              if(pStream->pLiveQ->pQs[sz]) {
                pktqueue_addpkt(pStream->pLiveQ->pQs[sz], pDataPayload, szDataPayload, NULL, 0);
              }
            }
            pthread_mutex_unlock(&pStream->pLiveQ->mtx);
          }
          bytes2 += szPkt;

        } else {

          // preserve rtp sequence number during 'live pause'
          //pStream->pRtp->m_pRtp->sequence_num = 
          //  htons(htons(pStream->pRtp->m_pRtp->sequence_num) - 1);

          //During 'live pause', update the last seq #
          //if(pStream->pXmitAction->prior_do_stream && pStream->prtp_sequence_at_end) {
          //  *pStream->prtp_sequence_at_end = pStream->pRtp->m_pRtp->sequence_num;
          //}
          //fprintf(stderr, "not streaming\n");

        }

        //
        // Record output stream
        //
        if(pStream->pXmitAction->do_record_post && pStream->pXmitCbs->cbRecord && 
           pStream->pXmitCbs->pCbRecordData) {

          memset(&collectPkt, 0, sizeof(collectPkt));
          collectPkt.payload.pData = (unsigned char *) pDataPayload;
          PKTCAPLEN(collectPkt.payload) = szDataPayload;
          if((sz = pStream->pXmitCbs->cbRecord(pStream->pXmitCbs->pCbRecordData, &collectPkt)) < 0) {
            return -1;
          }
          if(triedXmit == 0) {
            triedXmit = 1;
          }
        }

        //
        // Call post processing function, such as http live streaming
        // callback to segment and package output ts files 
        //
        if(pStream->pXmitAction->do_httplive && pStream->pXmitCbs->cbPostProc &&
           pStream->pXmitCbs->pCbPostProcData && pStream->pXmitAction->do_stream) {

          if((sz = pStream->pXmitCbs->cbPostProc(pStream->pXmitCbs->pCbPostProcData, 
                                                pDataPayload, szDataPayload)) < 0) {
            return -1;
          }
          if(triedXmit == 0) {
            triedXmit = 1;
          }
        }


        //if(pStream->pXmitAction->do_stream != pStream->pXmitAction->prior_do_stream) {
        //  pStream->pXmitAction->prior_do_stream = pStream->pXmitAction->do_stream;
        //}


        pStream->pRtpMulti->payloadLen = 0;

        if((rc = pStream->cbPreparePkt(pStream->pCbData)) < 0) {
          return -1;
        }
        //fprintf(stderr, "streamer prepare pkt returned %d\n", rc);

      } else if(rc < 0) {
        LOG(X_DEBUG("Stream ending, sent: %"LL64"u bytes %u pkts"), totBytes, totPkts); 
        return -1;
      } else {
        //fprintf(stderr, "streamer cansend rc:%d\n", rc);
      } 

      pStream = pStream->pNext;
    } // while(pStream)

    pktgen_SendQueued();


    if(triedXmit == 0) {

#ifdef WIN32

      //sl1 = timer_GetTime();

      //Sleep(1) may sleep past its short bedtime on win32, even from a thread w/ SCHED_RR
      //However, sleep(0) uses alot more cpu slices
      //TODO: make this a WaitForSingleObject for any registered pktqueue writers
      

      if(pList->pSleepQ) {
        //TODO: this does not return if a pkt has been queued and no subsequent pkt arrives
        pktqueue_waitforunreaddata(pList->pSleepQ);
        //pthread_cond_wait(pList->pCond, pList->pMtxCond);
      } else {
        Sleep(1);
      }

    } else {
      // On windows Sleep 0 relinquishes execution for any waiting threads
      Sleep(0);

#else // WIN32

      VSX_DEBUG2(tmnow = timer_GetTime())

      usleep(1000);
      countIterations = 0;

      VSX_DEBUGLOG3("stream_udp slept for %lld ns\n", timer_GetTime() - tmnow);

    } else {

      if(countIterations++ > 10000) {
        // During continuous xmit, sleep to prevent unresponsive system
        usleep(1);
        countIterations = 0;
      } 
#endif // WIN32

    } 

    tmnow = timer_GetTime();

    if(pList->pBwDescr && (tmnow / TIME_VAL_US) > (tmprevbwdescr / TIME_VAL_US) + 1) {
      pList->pBwDescr->intervalMs = (float)(tmnow - tmprevbwdescr)/ TIME_VAL_MS;
      pList->pBwDescr->pkts = pkts2;
      pList->pBwDescr->bytes = bytes2;
      TV_FROM_TIMEVAL(pList->pBwDescr->updateTv, tmnow);
      //pList->pBwDescr->updateTv.tv_sec = tmnow / TIME_VAL_US;
      //pList->pBwDescr->updateTv.tv_usec = tmnow % TIME_VAL_US;
      bytes2 = 0;
      pkts2 = 0;
      tmprevbwdescr = tmnow;
    }

    if(durationSec > 0 && tmnow > tmstart + (durationSec * TIME_VAL_US)) {
      LOG(X_DEBUG("Stream duration %.1f sec limit reached"), durationSec);
      *pList->prunning = STREAMER_STATE_FINISHED;
    }

#if defined (VSX_HAVE_LICENSE)
    // Check if stream time is limited
    if(!(pList->pLic->capabilities & LIC_CAP_STREAM_TIME_UNLIMITED)) {
      if(tmnow > tmstart + (STREAM_LIMIT_SEC * TIME_VAL_US)) {
        LOG(X_INFO("Stream time limited.  Stopping stream transmission after %d sec"), 
                 (int) (tmnow - tmstart) / TIME_VAL_US);
        *pList->prunning = STREAMER_STATE_FINISHED;
        if(!(g_proc_exit_flags & PROC_EXIT_FLAG_NO_EXIT_ON_STREAM_TIME_LIMITED)) {
          g_proc_exit = 1;
        }
      }
    }
#endif // VSX_HAVE_LICENSE

#if defined(LITE_VERSION)
    if(tmnow > tmstart + (STREAM_LIMIT_LITE_SEC * TIME_VAL_US)) {
      LOG(X_INFO("Stream time limited.  Stopping stream transmission after %d sec"),
               (int) (tmnow - tmstart) / TIME_VAL_US);
      *pList->prunning = STREAMER_STATE_FINISHED;
      if(!(g_proc_exit_flags & PROC_EXIT_FLAG_NO_EXIT_ON_STREAM_TIME_LIMITED)) {
        g_proc_exit = 1;
      }
    }
#endif // (LITE_VERSION)

/*
    if(0 && pList->verbosity > 1 && tv2.tv_sec > tv1.tv_sec+3) {

      elapsedMs0 = ((tv2.tv_sec - tv0.tv_sec) * 1000) + 
                   ((tv2.tv_usec - tv0.tv_usec) /1000);
      elapsedMs1 = ((tv2.tv_sec - tv1.tv_sec) * 1000) + 
                   ((tv2.tv_usec - tv1.tv_usec) /1000);

      fprintf(stdout, "%u", elapsedMs0/1000);
         
      if(durationSec != 0) {
        fprintf(stdout, "/%.1f", durationSec);
      }

      fprintf(stdout, " sec, %s %.1fKb/s %.1fpkts/s (total: %u pkts, %.1fKB, %.1fKb/s)",
           dstStr,
           (double)(bytes  / 128.0f / ((double)elapsedMs1/1000.0f)),
           (double)(pkts/ ((double)elapsedMs1/1000.0f)),
                         totPkts, (double)totBytes/1024.0f,
                           (double)(totBytes /  128.0f / ((double)elapsedMs0/1000.0f))); 
      fprintf(stdout, "\n");

      bytes = 0;
      pkts = 0;
      tv1.tv_sec = tv2.tv_sec;
      tv1.tv_usec = tv2.tv_usec;
    }
 */  
  }
Ejemplo n.º 7
0
static void srvlisten_media_proc(void *pArg) {

  SRV_LISTENER_CFG_T *pListenCfg = (SRV_LISTENER_CFG_T *) pArg;
  NETIO_SOCK_T netsocksrv;
  struct sockaddr_storage sa;
  CLIENT_CONN_T *pConnTmp;
  char tmp[128];
  char bufses[32];
  const int backlog = NET_BACKLOG_DEFAULT;
  unsigned int tsMax = 0;
  unsigned int flvMax = 0;
  unsigned int mkvMax = 0;
  unsigned int rtmpMax = 0;
  unsigned int rtspMax = 0;
  int haveAuth = 0;
  int haveRtmpAuth = 0;
  int haveRtspAuth = 0;
  int haveToken = 0;
  int rc = 0;

  logutil_tid_add(pthread_self(), pListenCfg->tid_tag);

  if((pListenCfg->urlCapabilities & (URL_CAP_TSLIVE | URL_CAP_TSHTTPLIVE | URL_CAP_FLVLIVE |
                                     URL_CAP_MKVLIVE | URL_CAP_LIVE | URL_CAP_STATUS | URL_CAP_MOOFLIVE |
                                     URL_CAP_PIP | URL_CAP_CONFIG | URL_CAP_BROADCAST |
                                     URL_CAP_RTMPLIVE | URL_CAP_RTMPTLIVE | URL_CAP_RTSPLIVE)) == 0) {

    LOG(X_WARNING("Server listener exiting because no capabilities enabled on %s:%d"),
         FORMAT_NETADDR(pListenCfg->sa, tmp, sizeof(tmp)), ntohs(INET_PORT(pListenCfg->sa)));
    logutil_tid_remove(pthread_self());
    return;
  } else if(!(pConnTmp = (CLIENT_CONN_T *) pListenCfg->pConnPool->pElements)) {
    return;
  }

  memset(&netsocksrv, 0, sizeof(netsocksrv));
  memcpy(&sa, &pListenCfg->sa, sizeof(pListenCfg->sa));
  netsocksrv.flags = pListenCfg->netflags;

  if((NETIOSOCK_FD(netsocksrv) = net_listen((const struct sockaddr *) &sa, backlog)) == INVALID_SOCKET) {
    logutil_tid_remove(pthread_self());
    return;
  }

  pthread_mutex_lock(&pListenCfg->mtx);
  pListenCfg->pnetsockSrv = &netsocksrv;
  pthread_mutex_unlock(&pListenCfg->mtx);

  if(pListenCfg->pAuthStore && IS_AUTH_CREDENTIALS_SET(pListenCfg->pAuthStore)) {
    haveAuth = 1;
  }
  if(pListenCfg->pAuthTokenId && pListenCfg->pAuthTokenId[0] != '\0') {
    haveToken = 1;
  }

  tsMax = pConnTmp->pStreamerCfg0->liveQs[0].max;
  flvMax = pConnTmp->pStreamerCfg0->action.liveFmts.out[STREAMER_OUTFMT_IDX_FLV].max;
  mkvMax = pConnTmp->pStreamerCfg0->action.liveFmts.out[STREAMER_OUTFMT_IDX_MKV].max;
  rtmpMax = pConnTmp->pStreamerCfg0->action.liveFmts.out[STREAMER_OUTFMT_IDX_RTMP].max;
  rtspMax = pConnTmp->pStreamerCfg0->pRtspSessions->max;

  if(HAVE_URL_CAP_RTMP(pListenCfg->urlCapabilities)) {

    if(IS_AUTH_CREDENTIALS_SET(&pConnTmp->pStreamerCfg0->creds[STREAMER_AUTH_IDX_RTMP].stores[pListenCfg->idxCfg])) {
      //
      // RTMP server streaming credentials not implemented 
      //
      //haveRtmpAuth = 1;
    }

    LOG(X_INFO("rtmp %s%s available at "URL_RTMP_FMT_STR"%s max:%d"),
       ((pListenCfg->netflags & NETIO_FLAG_PLAINTEXT) && (pListenCfg->netflags & NETIO_FLAG_SSL_TLS) ) ? "(SSL) " :
       ((pListenCfg->netflags & NETIO_FLAG_SSL_TLS) ? "(SSL only) " : ""),
           ((pListenCfg->urlCapabilities & URL_CAP_RTMPTLIVE) && !(pListenCfg->urlCapabilities & URL_CAP_RTMPLIVE) ?
            "(tunneled only) " : ((pListenCfg->urlCapabilities & URL_CAP_RTMPTLIVE) ? "(tunneled) " : "")),
           URL_PROTO_FMT2_ARGS(
               (pListenCfg->netflags & NETIO_FLAG_SSL_TLS),
                 FORMAT_NETADDR(sa, tmp, sizeof(tmp))), ntohs(INET_PORT(sa)),
           (haveRtmpAuth ? " (Using auth)" : ""), rtmpMax);
  }

  if(pListenCfg->urlCapabilities & URL_CAP_RTSPLIVE) {

    if(IS_AUTH_CREDENTIALS_SET(&pConnTmp->pStreamerCfg0->creds[STREAMER_AUTH_IDX_RTSP].stores[pListenCfg->idxCfg])) {
      haveRtspAuth = 1;
    }

    if(pListenCfg->pCfg->prtspsessiontimeout && *pListenCfg->pCfg->prtspsessiontimeout != 0) {
      snprintf(bufses, sizeof(bufses), ", timeout:%u sec", *pListenCfg->pCfg->prtspsessiontimeout);
    } else {
      bufses[0] = '\0';
    }

    LOG(X_INFO("rtsp %s available at "URL_RTSP_FMT_STR"%s max:%d%s"),
       ((pListenCfg->netflags & NETIO_FLAG_PLAINTEXT) && (pListenCfg->netflags & NETIO_FLAG_SSL_TLS) ) ? "(SSL) " :
       ((pListenCfg->netflags & NETIO_FLAG_SSL_TLS) ? "(SSL only) " : ""),
             URL_PROTO_FMT2_ARGS(
                 (pListenCfg->netflags & NETIO_FLAG_SSL_TLS),
                   FORMAT_NETADDR(sa, tmp, sizeof(tmp))), ntohs(INET_PORT(sa)),
             (haveRtspAuth ? " (Using auth)" : ""), rtspMax, bufses);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_ROOTHTML)) {
    LOG(X_INFO("broadcast interface available at "URL_HTTP_FMT_STR"%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_ROOT_URL,
           (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), pListenCfg->max);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_LIVE)) {
    LOG(X_INFO("live available at "URL_HTTP_FMT_STR"%s%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_LIVE_URL,
           (haveAuth ? " (Using auth)" : ""),
           (haveToken ? " (Using token)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), pListenCfg->max);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_TSLIVE)) {
    LOG(X_INFO("tslive available at "URL_HTTP_FMT_STR"%s%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_TSLIVE_URL,
           (haveAuth ? " (Using auth)" : ""),
           (haveToken ? " (Using token)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), tsMax);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_TSHTTPLIVE)) {
    LOG(X_INFO("httplive available at "URL_HTTP_FMT_STR"%s%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_HTTPLIVE_URL,
           (haveAuth ? " (Using auth)" : ""),
           (haveToken ? " (Using token)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), pListenCfg->max);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_FLVLIVE)) {
    LOG(X_INFO("flvlive available at "URL_HTTP_FMT_STR"%s%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_FLVLIVE_URL,
           (haveAuth ? " (Using auth)" : ""),
           (haveToken ? " (Using token)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), flvMax);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_MKVLIVE)) {
    LOG(X_INFO("mkvlive available at "URL_HTTP_FMT_STR"%s%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_MKVLIVE_URL,
           (haveAuth ? " (Using auth)" : ""),
           (haveToken ? " (Using token)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), mkvMax);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_MOOFLIVE)) {
    LOG(X_INFO("dash available at "URL_HTTP_FMT_STR"%s%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_DASH_URL,
           (haveAuth ? " (Using auth)" : ""),
           (haveToken ? " (Using token)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), pListenCfg->max);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_STATUS)) {
    LOG(X_INFO("status available at "URL_HTTP_FMT_STR"%s%s%s"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_STATUS_URL,
            (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""));
  }

  if((pListenCfg->urlCapabilities & URL_CAP_PIP)) {
    LOG(X_INFO("pip available at "URL_HTTP_FMT_STR"%s%s%s"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_PIP_URL,
            (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""));
  }

  if((pListenCfg->urlCapabilities & URL_CAP_CONFIG)) {
    LOG(X_INFO("config available at "URL_HTTP_FMT_STR"%s%s%s"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, FORMAT_NETADDR(sa, tmp, sizeof(tmp))), VSX_CONFIG_URL,
            (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""));
  }

  //fprintf(stderr, "LISTENER THREAD %s %s:%d active:%d cap: 0x%x\n", pListenCfg->netflags & NETIO_FLAG_SSL_TLS ? "SSL" : "", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), pListenCfg->active, pListenCfg->urlCapabilities);

  //
  // Service any client connections on the live listening port
  //
  rc = srvlisten_loop(pListenCfg, srv_cmd_proc);

  pthread_mutex_lock(&pListenCfg->mtx);
  pListenCfg->pnetsockSrv = NULL; 
  netio_closesocket(&netsocksrv);
  pthread_mutex_unlock(&pListenCfg->mtx);

  LOG(X_WARNING("HTTP listener thread exiting with code: %d"), rc);

  logutil_tid_remove(pthread_self());

  return;
}
Ejemplo n.º 8
0
int srv_rtmp_proc(CLIENT_CONN_T *pConn, const unsigned char *prebuf, unsigned int prebufsz, int istunneled) {
  int rc = 0;
  STREAMER_CFG_T *pStreamerCfg = NULL;
  STREAMER_OUTFMT_T *pLiveFmt = NULL;
  STREAM_STATS_T *pstats = NULL;
  RTMP_CTXT_T rtmpCtxt;
  unsigned int numQFull = 0;
  char tmps[2][128];
  OUTFMT_CFG_T *pOutFmt = NULL;

  if(!pConn) {
    return -1;
  }

  if(!HAVE_URL_CAP_RTMP(pConn->pListenCfg->urlCapabilities)) {
    LOG(X_ERROR("Listener %s:%d not enabled for rtmp%s%s stream to %s:%d"), 
          FORMAT_NETADDR(pConn->pListenCfg->sa, tmps[1], sizeof(tmps[1])), ntohs(INET_PORT(pConn->pListenCfg->sa)),
          istunneled > 0 ? "t" : "",      
          (pConn->sd.netsocket.flags & NETIO_FLAG_SSL_TLS) ? "s" : "", 
          FORMAT_NETADDR(pConn->sd.sa, tmps[0], sizeof(tmps[0])), ntohs(INET_PORT(pConn->sd.sa)));
    return -1;
  }

  pStreamerCfg = GET_STREAMER_FROM_CONN(pConn);

  if(pStreamerCfg && pStreamerCfg->action.liveFmts.out[STREAMER_OUTFMT_IDX_RTMP].do_outfmt) {

    pLiveFmt = &pStreamerCfg->action.liveFmts.out[STREAMER_OUTFMT_IDX_RTMP];

    if(pStreamerCfg->pMonitor && pStreamerCfg->pMonitor->active) {
      if(!(pstats = stream_monitor_createattach(pStreamerCfg->pMonitor,
             (const struct sockaddr *) &pConn->sd.sa, STREAM_METHOD_RTMP, STREAM_MONITOR_ABR_NONE))) {
      }
    }

    //
    // Add a livefmt cb
    //
    pOutFmt = outfmt_setCb(pLiveFmt, rtmp_addFrame, &rtmpCtxt, &pLiveFmt->qCfg, pstats, 
                           1, pStreamerCfg->frameThin, &numQFull);

  } 

  if(pOutFmt) {

    memset(&rtmpCtxt, 0, sizeof(rtmpCtxt));

    rtmp_init(&rtmpCtxt, MAX(pLiveFmt->qCfg.maxPktLen, pLiveFmt->qCfg.growMaxPktLen));
    rtmpCtxt.pSd = &pConn->sd;
    rtmpCtxt.novid = pStreamerCfg->novid;
    rtmpCtxt.noaud = pStreamerCfg->noaud;
    rtmpCtxt.av.vid.pStreamerCfg = pStreamerCfg;
    rtmpCtxt.av.aud.pStreamerCfg = pStreamerCfg;
    rtmpCtxt.pAuthTokenId = pConn->pListenCfg->pAuthTokenId;
    if(pstats) {
      rtmpCtxt.pStreamMethod = &pstats->method;
    }
    rtmpCtxt.pOutFmt = pOutFmt;
    rtmpCtxt.prebufdata = (unsigned char *) prebuf;
    rtmpCtxt.prebufsz = prebufsz;

    if(!(pConn->pListenCfg->urlCapabilities & URL_CAP_RTMPLIVE)) {
      rtmpCtxt.donotunnel = 1;
    }
    if((pConn->pListenCfg->urlCapabilities & URL_CAP_RTMPTLIVE)) {
      rtmpCtxt.dohttptunnel = 1;
    }

    //
    // Unpause the outfmt callback mechanism now that rtmp_init was called
    //
    outfmt_pause(pOutFmt, 0);

    LOG(X_INFO("Starting rtmp%s%s stream[%d] %d/%d to %s:%d"), 
          istunneled > 0 ? "t" : "",      
          (pConn->sd.netsocket.flags & NETIO_FLAG_SSL_TLS) ? "s" : "", pOutFmt->cbCtxt.idx, numQFull + 1, 
          pLiveFmt->max, FORMAT_NETADDR(pConn->sd.sa, tmps[0], sizeof(tmps[0])), ntohs(INET_PORT(pConn->sd.sa)));

    rtmp_handle_conn(&rtmpCtxt);

    LOG(X_INFO("Ending rtmp%s%s stream[%d] to %s:%d"), 
         istunneled > 0 ? "t" : "",      
         (pConn->sd.netsocket.flags & NETIO_FLAG_SSL_TLS) ? "s" : "", pOutFmt->cbCtxt.idx, 
         FORMAT_NETADDR(pConn->sd.sa, tmps[0], sizeof(tmps[0])), ntohs(INET_PORT(pConn->sd.sa)));

    //
    // Remove the livefmt cb
    //
    outfmt_removeCb(pOutFmt);

    rtmp_close(&rtmpCtxt);

  } else {

    if(pstats) {
      //
      // Destroy automatically detaches the stats from the monitor linked list
      //
      stream_stats_destroy(&pstats, NULL);
    }

    LOG(X_WARNING("No rtmp resource available (max:%d) for %s:%d"), 
        (pLiveFmt ? pLiveFmt->max : 0),
        FORMAT_NETADDR(pConn->sd.sa, tmps[0], sizeof(tmps[0])), ntohs(INET_PORT(pConn->sd.sa)));

    rc = -1;
  }

  netio_closesocket(&pConn->sd.netsocket);

  LOG(X_DEBUG("RTMP connection thread ended %s:%d"), FORMAT_NETADDR(pConn->sd.sa, tmps[0], sizeof(tmps[0])), 
                                                     ntohs(INET_PORT(pConn->sd.sa)));

  return rc;
}
Ejemplo n.º 9
0
static void srvlisten_rtsplive_proc(void *pArg) {

  SRV_LISTENER_CFG_T *pListenCfg = (SRV_LISTENER_CFG_T *) pArg;
  CLIENT_CONN_T *pConn = NULL;
  NETIO_SOCK_T netsocksrv;
  struct sockaddr_in  sa;
  int haveRtspAuth = 0;
  char buf[SAFE_INET_NTOA_LEN_MAX];
  char bufses[32];
  int rc = 0;

  logutil_tid_add(pthread_self(), pListenCfg->tid_tag);

  memset(&sa, 0, sizeof(sa));
  memset(&netsocksrv, 0, sizeof(netsocksrv));
  sa.sin_family = PF_INET;
  sa.sin_addr = pListenCfg->sain.sin_addr;
  sa.sin_port = pListenCfg->sain.sin_port;
  netsocksrv.flags = pListenCfg->netflags;

  if((NETIOSOCK_FD(netsocksrv) = net_listen(&sa, 5)) == INVALID_SOCKET) {
    logutil_tid_remove(pthread_self());
    return;
  }

   pConn = (CLIENT_CONN_T *) pListenCfg->pConnPool->pElements;
    if(pConn) {
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_RTSP].stores[pListenCfg->idxCfg])) {
      haveRtspAuth = 1;
    }
  }

  pthread_mutex_lock(&pListenCfg->mtx);
  pListenCfg->pnetsockSrv = &netsocksrv;
  pthread_mutex_unlock(&pListenCfg->mtx);

  if(pListenCfg->pCfg->prtspsessiontimeout && *pListenCfg->pCfg->prtspsessiontimeout != 0) {
    snprintf(bufses, sizeof(bufses), ", timeout:%u sec", *pListenCfg->pCfg->prtspsessiontimeout);
  } else {
    bufses[0] = '\0';
  }

  LOG(X_INFO("rtsp %sserver available at "URL_RTSP_FMT_STR"%s max:%d%s"),
           ((pListenCfg->netflags & NETIO_FLAG_SSL_TLS) ? "(SSL) " : ""),
           URL_RTSP_FMT2_ARGS(
               (pListenCfg->netflags & NETIO_FLAG_SSL_TLS),
                 net_inet_ntoa(sa.sin_addr, buf)), ntohs(sa.sin_port), 
           (haveRtspAuth ? " (Using auth)" : ""),
           pListenCfg->max, bufses);

  //
  // Service any client connections on the rtsp listening port
  //
  rc = srvlisten_loop(pListenCfg, srv_rtsp_proc);

  pthread_mutex_lock(&pListenCfg->mtx);
  pListenCfg->pnetsockSrv = NULL; 
  netio_closesocket(&netsocksrv);
  pthread_mutex_unlock(&pListenCfg->mtx);

  LOG(X_DEBUG("rtsp listener thread exiting with code: %d"), rc);

  logutil_tid_remove(pthread_self());

  return ;
}
Ejemplo n.º 10
0
static void srvlisten_http_proc(void *pArg) {

  SRV_LISTENER_CFG_T *pListenCfg = (SRV_LISTENER_CFG_T *) pArg;
  NETIO_SOCK_T netsocksrv;
  struct sockaddr_in  sa;
  CLIENT_CONN_T *pConn;
  unsigned int tsMax = 0;
  unsigned int flvMax = 0;
  unsigned int mkvMax = 0;
/*
  int haveMkvAuth = 0; 
  int haveFlvAuth = 0; 
  int haveTsliveAuth = 0; 
  int haveHttpliveAuth = 0; 
  int haveMoofAuth = 0; 
  int haveConfigAuth = 0; 
  int havePipAuth = 0; 
  int haveStatusAuth = 0; 
  int haveRootAuth = 0; 
*/
  int haveAuth = 0;
  int rc = 0;
  char buf[SAFE_INET_NTOA_LEN_MAX];

  logutil_tid_add(pthread_self(), pListenCfg->tid_tag);

  if((pListenCfg->urlCapabilities & (URL_CAP_TSLIVE | URL_CAP_TSHTTPLIVE | URL_CAP_FLVLIVE |
                                     URL_CAP_MKVLIVE | URL_CAP_LIVE | URL_CAP_STATUS | URL_CAP_MOOFLIVE |
                                     URL_CAP_PIP | URL_CAP_CONFIG | URL_CAP_BROADCAST)) == 0) {
    LOG(X_WARNING("http listener exiting because no capabilities enabled on %s:%d"),
        inet_ntoa(pListenCfg->sain.sin_addr), ntohs(pListenCfg->sain.sin_port));
    logutil_tid_remove(pthread_self());
    return;
  }

  memset(&sa, 0, sizeof(sa));
  memset(&netsocksrv, 0, sizeof(netsocksrv));
  sa.sin_family = PF_INET;
  sa.sin_addr = pListenCfg->sain.sin_addr;
  sa.sin_port = pListenCfg->sain.sin_port;
  netsocksrv.flags = pListenCfg->netflags;

  if((NETIOSOCK_FD(netsocksrv) = net_listen(&sa, 5)) == INVALID_SOCKET) {
    logutil_tid_remove(pthread_self());
    return;
  }

  pthread_mutex_lock(&pListenCfg->mtx);
  pListenCfg->pnetsockSrv = &netsocksrv;
  pthread_mutex_unlock(&pListenCfg->mtx);

  if(pListenCfg->pAuthStore && IS_AUTH_CREDENTIALS_SET(pListenCfg->pAuthStore)) {
    haveAuth = 1;
  }

  pConn = (CLIENT_CONN_T *) pListenCfg->pConnPool->pElements;
  if(pConn) {
    tsMax = pConn->pStreamerCfg0->liveQs[0].max;
    flvMax = pConn->pStreamerCfg0->action.liveFmts.out[STREAMER_OUTFMT_IDX_FLV].max;
    mkvMax = pConn->pStreamerCfg0->action.liveFmts.out[STREAMER_OUTFMT_IDX_MKV].max;

/*
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_FLV].stores[pListenCfg->idxCfg])) {
      haveFlvAuth = 1;
    }
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_MKV].stores[pListenCfg->idxCfg])) {
      haveMkvAuth = 1;
    }
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_TSLIVE].stores[pListenCfg->idxCfg])) {
      haveTsliveAuth = 1;
    }
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_HTTPLIVE].stores[pListenCfg->idxCfg])) {
      haveHttpliveAuth = 1; 
    }
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_MOOFLIVE].stores[pListenCfg->idxCfg])) {
      haveMoofAuth = 1; 
    }
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_CONFIG].stores[pListenCfg->idxCfg])) {
      haveConfigAuth = 1; 
    }
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_PIP].stores[pListenCfg->idxCfg])) {
      havePipAuth = 1; 
    }
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_STATUS].stores[pListenCfg->idxCfg])) {
      haveStatusAuth = 1; 
    }
    if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds[STREAMER_AUTH_IDX_ROOT].stores[pListenCfg->idxCfg])) {
      haveRootAuth = 1; 
    }
*/

    //if(IS_AUTH_CREDENTIALS_SET(&pConn->pStreamerCfg0->creds.auths[STREAMER_AUTH_IDX_ROOT])) {
    //  LOG(X_DEBUG("LIVE/ROOT AUTH ON")); 
    //}
  }

  if((pListenCfg->urlCapabilities & URL_CAP_ROOTHTML)) {
    LOG(X_INFO("broadcast interface available at "URL_HTTP_FMT_STR"%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_ROOT_URL,
           //(haveRootAuth ? " (Using auth)" : ""),
           (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), pListenCfg->max);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_LIVE)) {
    LOG(X_INFO("live available at "URL_HTTP_FMT_STR"%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_LIVE_URL,
           //(haveRootAuth ? " (Using auth)" : ""),
           (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), pListenCfg->max);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_TSLIVE)) {
    LOG(X_INFO("tslive available at "URL_HTTP_FMT_STR"%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_TSLIVE_URL,
           //(haveTsliveAuth ? " (Using auth)" : ""),
           (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), tsMax);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_TSHTTPLIVE)) {
    LOG(X_INFO("httplive available at "URL_HTTP_FMT_STR"%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_HTTPLIVE_URL,
           //(haveHttpliveAuth ? " (Using auth)" : ""),
           (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), pListenCfg->max);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_FLVLIVE)) {
    LOG(X_INFO("flvlive available at "URL_HTTP_FMT_STR"%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_FLVLIVE_URL,
           //(haveFlvAuth ? " (Using auth)" : ""),
           (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), flvMax);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_MKVLIVE)) {
    LOG(X_INFO("mkvlive available at "URL_HTTP_FMT_STR"%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_MKVLIVE_URL,
           //(haveMkvAuth ? " (Using auth)" : ""),
           (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), mkvMax);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_MOOFLIVE)) {
    LOG(X_INFO("dash available at "URL_HTTP_FMT_STR"%s%s%s max:%d"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_DASH_URL,
           // (haveMoofAuth ? " (Using auth)" : ""),
           (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""), pListenCfg->max);
  }

  if((pListenCfg->urlCapabilities & URL_CAP_STATUS)) {
    LOG(X_INFO("status available at "URL_HTTP_FMT_STR"%s%s%s"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_STATUS_URL,
            //(haveStatusAuth ? " (Using auth)" : ""),
            (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""));
  }

  if((pListenCfg->urlCapabilities & URL_CAP_PIP)) {
    LOG(X_INFO("pip available at "URL_HTTP_FMT_STR"%s%s%s"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_PIP_URL,
            //(havePipAuth ? " (Using auth)" : ""),
            (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""));
  }

  if((pListenCfg->urlCapabilities & URL_CAP_CONFIG)) {
    LOG(X_INFO("config available at "URL_HTTP_FMT_STR"%s%s%s"), 
           URL_HTTP_FMT_ARGS2(pListenCfg, net_inet_ntoa(sa.sin_addr, buf)), VSX_CONFIG_URL,
            //(haveConfigAuth ? " (Using auth)" : ""),
            (haveAuth ? " (Using auth)" : ""),
           (pListenCfg->pCfg->cfgShared.livepwd ? " (Using password)" : ""));
  }

  //fprintf(stderr, "LISTENER THREAD %s %s:%d active:%d cap: 0x%x\n", pListenCfg->netflags & NETIO_FLAG_SSL_TLS ? "SSL" : "", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), pListenCfg->active, pListenCfg->urlCapabilities);

  //
  // Service any client connections on the live listening port
  //
  rc = srvlisten_loop(pListenCfg, srv_cmd_proc);

  pthread_mutex_lock(&pListenCfg->mtx);
  pListenCfg->pnetsockSrv = NULL; 
  netio_closesocket(&netsocksrv);
  pthread_mutex_unlock(&pListenCfg->mtx);

  LOG(X_WARNING("HTTP listener thread exiting with code: %d"), rc);

  logutil_tid_remove(pthread_self());

  return;
}
Ejemplo n.º 11
0
static void srv_rtmp_proc(void *pfuncarg) {
  CLIENT_CONN_T *pConn = (CLIENT_CONN_T *) pfuncarg;
  STREAMER_CFG_T *pStreamerCfg = NULL;
  STREAMER_OUTFMT_T *pLiveFmt = NULL;
  STREAM_STATS_T *pstats = NULL;
  RTMP_CTXT_T rtmpCtxt;
  unsigned int numQFull = 0;
  char buf[SAFE_INET_NTOA_LEN_MAX];
  OUTFMT_CFG_T *pOutFmt = NULL;

  pStreamerCfg = GET_STREAMER_FROM_CONN(pConn);

  if(pStreamerCfg && pStreamerCfg->action.liveFmts.out[STREAMER_OUTFMT_IDX_RTMP].do_outfmt) {

    pLiveFmt = &pStreamerCfg->action.liveFmts.out[STREAMER_OUTFMT_IDX_RTMP];

    if(pStreamerCfg->pMonitor && pStreamerCfg->pMonitor->active) {
      if(!(pstats = stream_monitor_createattach(pStreamerCfg->pMonitor,
                      &pConn->sd.sain, STREAM_METHOD_RTMP, STREAM_MONITOR_ABR_NONE))) {
      }
    }

    //
    // Add a livefmt cb
    //
    pOutFmt = outfmt_setCb(pLiveFmt, rtmp_addFrame, &rtmpCtxt, &pLiveFmt->qCfg, pstats, 1, pStreamerCfg->frameThin, &numQFull);

  } 

  if(pOutFmt) {

    memset(&rtmpCtxt, 0, sizeof(rtmpCtxt));

    rtmp_init(&rtmpCtxt, MAX(pLiveFmt->qCfg.maxPktLen, pLiveFmt->qCfg.growMaxPktLen));
    rtmpCtxt.pSd = &pConn->sd;
    rtmpCtxt.novid = pStreamerCfg->novid;
    rtmpCtxt.noaud = pStreamerCfg->noaud;
    rtmpCtxt.av.vid.pStreamerCfg = pStreamerCfg;
    rtmpCtxt.av.aud.pStreamerCfg = pStreamerCfg;

    //
    // Unpause the outfmt callback mechanism now that rtmp_init was called
    //
    outfmt_pause(pOutFmt, 0);

    LOG(X_INFO("Starting rtmp stream[%d] %d/%d to %s:%d"), pOutFmt->cbCtxt.idx, numQFull + 1, 
           pLiveFmt->max,
           net_inet_ntoa(pConn->sd.sain.sin_addr, buf), ntohs(pConn->sd.sain.sin_port));

    rtmp_handle_conn(&rtmpCtxt);

    LOG(X_INFO("Ending rtmp stream[%d] to %s:%d"), pOutFmt->cbCtxt.idx,
           net_inet_ntoa(pConn->sd.sain.sin_addr, buf), ntohs(pConn->sd.sain.sin_port));

    //
    // Remove the livefmt cb
    //
    outfmt_removeCb(pOutFmt);

    rtmp_close(&rtmpCtxt);

  } else {

    if(pstats) {
      //
      // Destroy automatically detaches the stats from the monitor linked list
      //
      stream_stats_destroy(&pstats, NULL);
    }

    LOG(X_WARNING("No rtmp resource available (max:%d) for %s:%d"), 
        (pLiveFmt ? pLiveFmt->max : 0),
       net_inet_ntoa(pConn->sd.sain.sin_addr, buf), ntohs(pConn->sd.sain.sin_port));

  }

  netio_closesocket(&pConn->sd.netsocket);

  LOG(X_DEBUG("RTMP connection thread ended %s:%d"), net_inet_ntoa(pConn->sd.sain.sin_addr, buf),
                                        ntohs(pConn->sd.sain.sin_port));

}
Ejemplo n.º 12
0
static int xcode_ipc_dispatch(XCODE_IPC_DESCR_T *pXcodeIpc) {
  int errcnt = 0;
  IXCODE_OUTBUF_T outbuf;
#ifdef WIN32
  int rc;
#endif // WIN32

  while(errcnt < SEM_MAX_ERRORS) {

#if defined(WIN32)
    if((rc = WaitForSingleObject(pXcodeIpc->hSemSrv, INFINITE)) == WAIT_FAILED) {
      LOG(X_ERROR("WaitForSingleObject failed (error: %d)"), GetLastError());
#else // WIN32
    if(sem_wait(pXcodeIpc->sem_srv) != 0) {
      LOG(X_ERROR("sem_wait failed with error: %d"), errno);
#endif // WIN32
      errcnt++;
      continue;
    } else if(errcnt > 0) {
      errcnt = 0;
    }

    //fprintf(stderr, "ipc exec cmd: %d ...\n", pXcodeIpc->pmem->hdr.cmd);

    switch(pXcodeIpc->pmem->hdr.cmd) {
      case XCODE_IPC_CMD_INIT_VID:
        pXcodeIpc->pmem->hdr.cmdrc = ixcode_init_vid(&pXcodeIpc->pmem->hdr.ctxt.vid);
        break;
      case XCODE_IPC_CMD_INIT_AUD:
        pXcodeIpc->pmem->hdr.cmdrc = ixcode_init_aud(&pXcodeIpc->pmem->hdr.ctxt.aud);
        break;
      case XCODE_IPC_CMD_CLOSE_VID:
        ixcode_close_vid(&pXcodeIpc->pmem->hdr.ctxt.vid);
        pXcodeIpc->pmem->hdr.cmdrc = 0;
        break;
      case XCODE_IPC_CMD_CLOSE_AUD:
        ixcode_close_aud(&pXcodeIpc->pmem->hdr.ctxt.aud);
        pXcodeIpc->pmem->hdr.cmdrc = 0;
        break;
      case XCODE_IPC_CMD_ENCODE_VID:
        memset(&outbuf, 0, sizeof(outbuf));
        outbuf.buf = XCODE_IPC_MEM_DATA(pXcodeIpc->pmem); 
        outbuf.lenbuf = XCODE_IPC_MEM_DATASZ(pXcodeIpc->pmem);
        pXcodeIpc->pmem->hdr.cmdrc = ixcode_frame_vid(&pXcodeIpc->pmem->hdr.ctxt.vid,
              XCODE_IPC_MEM_DATA(pXcodeIpc->pmem), (unsigned int) pXcodeIpc->pmem->hdr.cmdrc, 
              &outbuf);
        break;
      case XCODE_IPC_CMD_ENCODE_AUD:
        if(pXcodeIpc->pmem->hdr.offsetOut > XCODE_IPC_MEM_DATASZ(pXcodeIpc->pmem)) {
          pXcodeIpc->pmem->hdr.cmdrc = IXCODE_RC_ERROR;
        } else {
          pXcodeIpc->pmem->hdr.cmdrc = ixcode_frame_aud(&pXcodeIpc->pmem->hdr.ctxt.aud,
              XCODE_IPC_MEM_DATA(pXcodeIpc->pmem), (unsigned int) pXcodeIpc->pmem->hdr.cmdrc,
              XCODE_IPC_MEM_DATA(pXcodeIpc->pmem) + pXcodeIpc->pmem->hdr.offsetOut, 
              XCODE_IPC_MEM_DATASZ(pXcodeIpc->pmem) - pXcodeIpc->pmem->hdr.offsetOut);
        }
        break;
      default:
        LOG(X_ERROR("Invalid ipc command: %d"), pXcodeIpc->pmem->hdr.cmd);
        pXcodeIpc->pmem->hdr.cmdrc = IXCODE_RC_ERROR;
    }

    if(pXcodeIpc->pmem->hdr.cmdrc < IXCODE_RC_OK) {
      LOG(X_ERROR("ipc exec cmd: %d rc: %d"), pXcodeIpc->pmem->hdr.cmd, 
                                              pXcodeIpc->pmem->hdr.cmdrc);
    }

    pXcodeIpc->pmem->hdr.cmd = XCODE_IPC_CMD_NONE;

#if defined(WIN32)
    if(ReleaseSemaphore(pXcodeIpc->hSemCli, 1, NULL) == 0) {
      LOG(X_ERROR("sem_post failed with error: %d"), GetLastError());
#else
    if(sem_post(pXcodeIpc->sem_cli) != 0) {
      LOG(X_ERROR("sem_post failed with error: %d"), errno);
#endif // WIN32
    }

  }

  return 0;
}



static void usage(int argc, char *argv[]) {
  fprintf(stdout, "usage: %s \n", argv[0]);
  fprintf(stdout, "Used in conjunction with OpenVSX to transcode video\n\n");
}

int main(int argc, char *argv[]) {
  XCODE_IPC_DESCR_T xcodeIpc;
  int rc;

  fprintf(stdout, "\n"XCODE_BANNER" "ARCH"\n\n", BUILD_INFO_NUM);

  if(argc > 1) {
    usage(argc, argv);
    return 0;
  }

  logger_Init(NULL, NULL, 0, 0, LOG_FLAG_USESTDERR | LOG_FLAG_FLUSHOUTPUT);
  logger_SetFile("log", "vsx-xcode", LOGGER_MAX_FILES, LOGGER_MAX_FILE_SZ,
                      LOG_OUTPUT_DEFAULT | LOG_FLAG_USELOCKING);
  logger_SetLevel(S_DEBUG);
  logger_AddStderr(S_DEBUG, LOG_OUTPUT_DEFAULT_STDERR);

  LOG(X_INFO("vsx-xcode starting"));

  memset(&xcodeIpc, 0, sizeof(xcodeIpc));
  g_pXcodeIpc = &xcodeIpc;

  xcodeIpc.sz = XCODE_IPC_MEM_SZ;

#if !defined(WIN32)
  xcodeIpc.key = XCODE_IPC_SHMKEY;
  signal(SIGINT, sig_handler);
  signal(SIGTERM, sig_handler);
  signal(SIGKILL, sig_handler);
#endif // WIN32

  rc = xcode_ipc_init(&xcodeIpc);

  if(rc == 0) {
    xcode_ipc_dispatch(&xcodeIpc);
  }

  xcode_ipc_close(&xcodeIpc);

  return 0;
}
Ejemplo n.º 13
0
int streamer_run_tonet(STREAM_XMIT_NODE_T *pList, double durationSec) {
  STREAM_XMIT_NODE_T *pStream;
  int triedXmit;
  TIME_VAL tmstartOutput = 0;
  TIME_VAL tmstart, tmnow;
  int haveTmstartOutput = 0;
  int rc;

#if defined(VSX_HAVE_TURN)
  int pendingTurnRelays = 1;
  int pendingTurnRelays0;
  NET_PROGRESS_T progTurn;
  memset(&progTurn, 0, sizeof(progTurn));
#else // (VSX_HAVE_TURN)
  int pendingTurnRelays = 0;
#endif // (VSX_HAVE_TURN)

#if defined(VSX_HAVE_SSL_DTLS)
  TIME_VAL tmstartRtpHandshakeDone = 0;
  int giveupRtcpHandshakes = 0;
  int pendingDtlsRtpHandshakes = 1;
  NET_PROGRESS_T progRtp;
  NET_PROGRESS_T progRtcp;
  DTLS_TIMEOUT_CFG_T dtlsTimeouts;

  setDtlsTimeouts(&dtlsTimeouts, pList);
  memset(&progRtp, 0, sizeof(progRtp));
  memset(&progRtcp, 0, sizeof(progRtcp));
#else
  int pendingDtlsRtpHandshakes = 0;
#endif // (VSX_HAVE_SSL_DTLS)


#ifndef WIN32
  unsigned int countIterations = 0;
#endif // WIN32

  if(!pList 
#if defined(VSX_HAVE_LICENSE)
    || !pList->pLic
#endif // VSX_HAVE_LICENSE
    ) {
    return -1;
  }

  tmstart = tmnow = timer_GetTime();

  while(*pList->prunning == STREAMER_STATE_RUNNING && !g_proc_exit) {

    pStream = pList;
    triedXmit = 0;

    while(pStream) {

#if defined(VSX_HAVE_TURN)

      pendingTurnRelays0 = pendingTurnRelays;

      if(pendingTurnRelays > 0 && (pendingTurnRelays = do_turn_relays(pStream, &progTurn)) < 0) {
        LOG(X_ERROR("Giving up waiting for output transmission after TURN relay setup failure"));
        return -1; 
      }

      if(pendingTurnRelays == 0 && pendingTurnRelays0 != pendingTurnRelays && progTurn.numTotal > 0) {
        LOG(X_INFO("Starting output transmission after creating TURN relay(s)"));
      }

      //LOG(X_DEBUG("pendingTurnRelays:%d, %d/%d, numerror:%d"), pendingTurnRelays, progTurn.numCompleted, progTurn.numTotal, progTurn.numError); 
#endif // (VSX_HAVE_TURN)

#if defined(VSX_HAVE_SSL_DTLS)
      //if(pStream->pRtpMulti->pStreamerCfg->xcode.vid.pip.active) 
      //LOG(X_DEBUG("loop... pendingDtlsRtpHandshakes:%d, rtp:%d - %d, rtcp:%d - %d, giveupRtcpHandshakes:%d, tm:%lld ms"), pendingDtlsRtpHandshakes, progRtp.numTotal,  progRtp.numCompleted, progRtcp.numTotal,  progRtcp.numCompleted, giveupRtcpHandshakes, (timer_GetTime() - tmstart) / TIME_VAL_MS);

      //LOG(X_DEBUG("streamer2: pendingTurnRelays;%d, completed:%d/%d, pendingDtlsRtpHandshakes:%d"), pendingTurnRelays, progTurn.numCompleted, progTurn.numTotal, pendingDtlsRtpHandshakes);

      if(pendingTurnRelays == 0 && pendingDtlsRtpHandshakes > 0 && 
         (pendingDtlsRtpHandshakes = do_dtls_handshakes(pStream, tmstart, &tmstartRtpHandshakeDone, 
                                                     &progRtp, &progRtcp, &dtlsTimeouts)) < 0) {
        return -1;
      } else if(pendingDtlsRtpHandshakes == 0 && pendingTurnRelays == 0) {

        if(!haveTmstartOutput) {
          tmstartOutput = timer_GetTime();
          haveTmstartOutput = 1;
        }

        if(progRtcp.numTotal - progRtcp.numCompleted > 0 && !giveupRtcpHandshakes) {

          if(tmstartRtpHandshakeDone == 0) {
            tmstartRtpHandshakeDone = timer_GetTime();
          }

          if(((tmnow = timer_GetTime()) - tmstartRtpHandshakeDone) / TIME_VAL_MS > 
             dtlsTimeouts.handshakeRtcpAdditionalGiveupMs) {
            LOG(X_ERROR("Aborting DTLS RTCP handshaking after %lld ms"), (tmnow - tmstart) / TIME_VAL_MS);
            giveupRtcpHandshakes = 1;
          } else {
            do_dtls_handshakes(pStream, tmstart, &tmstartRtpHandshakeDone, NULL, &progRtcp, &dtlsTimeouts);
          }  

          //LOG(X_DEBUG("loop... calling do_dtls_handshakes Rtcp.numDtls:%d - Rtcp.numDtlsCompleted"), progRtcp.numTotal, progRtcp.numCompleted);
        }
#endif // (VSX_HAVE_SSL_DTLS)

        //if(pStream->pRtpMulti->pStreamerCfg->xcode.vid.pip.active) 
        //LOG(X_DEBUG("Calling cbCanSend"));
        if((rc = pStream->cbCanSend(pStream->pCbData)) > 0) {

          if((rc = pStream->cbPreparePkt(pStream->pCbData)) < 0) {
            return -1;
          } else if(rc > 0) {
            triedXmit = 1;
          }

        } else if(rc == -2) {
          // all programs have ended
          return 0;
        } else if(rc < 0) {
          return -1;
        } else {
          //fprintf(stderr, "streamer cansend rc:%d\n", rc);
        }   

#if defined(VSX_HAVE_SSL_DTLS)
      }
#endif // (VSX_HAVE_SSL_DTLS)

      pStream = pStream->pNext;
    } // while(pStream)

    if(triedXmit == 0) {

#ifdef WIN32

      //sl1 = timer_GetTime();

      //Sleep(1) may sleep past its short bedtime on win32, even from a thread w/ SCHED_RR
      //However, sleep(0) uses alot more cpu slices
      //TODO: make this a WaitForSingleObject for any registered pktqueue writers
      
      if(pList->pSleepQ) {
        //TODO: this does not return if a pkt has been queued and no subsequent pkt arrives
        pktqueue_waitforunreaddata(pList->pSleepQ);
      } else {
        Sleep(1);
      }

    } else {
      // On windows Sleep 0 relinquishes execution for any waiting threads
      Sleep(0);

#else // WIN32


      VSX_DEBUG2(tmnow = timer_GetTime());

      //fprintf(stderr, "usleep...\n");
      if(pendingDtlsRtpHandshakes > 0 || pendingTurnRelays > 0) {
        usleep(10000);
      } else {
        usleep(1000);
      }
      //fprintf(stderr, "usleep done...\n");

      countIterations = 0;

      VSX_DEBUG_STREAMAV( LOG(X_DEBUGV("stream_readframes slept for %lld ns"), timer_GetTime() - tmnow));

      //fprintf(stderr, "%lld --woke up from streamer2 zzz...\n", timer_GetTime() / TIME_VAL_MS);
    } else {
      //fprintf(stderr, "stream_readframes not sleeping count:%d tried:%d\n", countIterations, triedXmit);

      //fprintf(stderr, "no usleep...%d\n", countIterations);
      if(countIterations++ > 10000) {
        // During continuous xmit, sleep to prevent unresponsive system
        usleep(1);
        countIterations = 0;
      } 
#endif // WIN32

    } 

    tmnow = timer_GetTime();

#if defined(TEST_KILL)
//static int raiseSig=0; if(!raiseSig && haveTmstartOutput && tmnow > tmstartOutput + (4* TIME_VAL_US)) { raise(SIGINT); }
static int raiseSig=0; if(!raiseSig && haveTmstartOutput && tmnow > tmstartOutput + (19* TIME_VAL_US)) { g_proc_exit=1;if(g_proc_exit_cond){pthread_cond_broadcast(g_proc_exit_cond);} }
#endif // TEST_KILL

    if(haveTmstartOutput && durationSec > 0 && tmnow > tmstartOutput + (durationSec * TIME_VAL_US)) {
      LOG(X_DEBUG("Stream duration %.1f sec limit reached"), durationSec);
      //*pList->prunning = STREAMER_STATE_FINISHED;
      return 0;
    }

#if defined(VSX_HAVE_LICENSE)
    // Check if stream time is limited
    if(!(pList->pLic->capabilities & LIC_CAP_STREAM_TIME_UNLIMITED)) {

      if(haveTmstartOutput && tmnow > tmstartOutput + (STREAM_LIMIT_SEC * TIME_VAL_US)) {
        LOG(X_INFO("Stream time limited.  Stopping stream transmission after %d sec"), 
                 (int) (tmnow - tmstartOutput) / TIME_VAL_US);
        *pList->prunning = STREAMER_STATE_FINISHED;
        if(!(g_proc_exit_flags & PROC_EXIT_FLAG_NO_EXIT_ON_STREAM_TIME_LIMITED)) {
          g_proc_exit = 1;
        }
      }
    }
#endif // VSX_HAVE_LICENSE

/*
LOG(X_DEBUG("pList: 0x%x, pip.active:%d, overlay.havePip:%d"), pList, pList->pRtpMulti->pStreamerCfg->xcode.vid.pip.active,  pList->pRtpMulti->pStreamerCfg->xcode.vid.overlay.havePip);
if(pList->pRtpMulti->pStreamerCfg->xcode.vid.pip.active && haveTmstartOutput && tmnow > tmstartOutput + (5 * TIME_VAL_US)) {
  *pList->prunning = STREAMER_STATE_FINISHED;
  if(!(g_proc_exit_flags & PROC_EXIT_FLAG_NO_EXIT_ON_STREAM_TIME_LIMITED)) {
    g_proc_exit = 1;
  }
}
*/

#if defined(LITE_VERSION)
    if(haveTmstartOutput && tmnow > tmstartOutput + (STREAM_LIMIT_LITE_SEC * TIME_VAL_US)) {
      LOG(X_INFO("Stream time limited.  Stopping stream transmission after %d sec"),
               (int) (tmnow - tmstartOutput) / TIME_VAL_US);
      *pList->prunning = STREAMER_STATE_FINISHED;
      if(!(g_proc_exit_flags & PROC_EXIT_FLAG_NO_EXIT_ON_STREAM_TIME_LIMITED)) {
        g_proc_exit = 1;
      }
    }
#endif // (LITE_VERSION)

  }
Ejemplo n.º 14
0
static void stream_monitor_proc(void *pArg) {
    MONITOR_START_WRAP_T startWrap;
    STREAM_STATS_MONITOR_T *pMonitor = NULL;
    FILE *fp = NULL;
    unsigned int intervalMs;
    TIME_VAL tvNext, tv;

    memcpy(&startWrap, pArg, sizeof(startWrap));
    pMonitor = startWrap.pMonitor;

    logutil_tid_add(pthread_self(), startWrap.tid_tag);

    pMonitor->runMonitor = 1;
    if((intervalMs = pMonitor->dumpIntervalMs) <= 0) {
        intervalMs = STREAM_STATS_DUMP_MS;
    }

    //
    // Set the output file path
    //
    if(pMonitor->statfilepath) {
        if(!strcasecmp(pMonitor->statfilepath, "stdout")) {
            fp = stdout;
        } else if(!strcasecmp(pMonitor->statfilepath, "stderr")) {
            fp = stderr;
        } else if(!(fp = fopen(pMonitor->statfilepath, "w"))) {
            LOG(X_ERROR("Failed top open stats file %s for writing"), pMonitor->statfilepath);
            pMonitor->runMonitor = -1;
        }
    } else {
        //fp = stdout;
    }

    if(pMonitor->runMonitor == 1) {
        tvNext = timer_GetTime() + (intervalMs * TIME_VAL_MS);
        LOG(X_INFO("Started %sstream output monitor %s%s"),
            pMonitor->pAbr ? "ABR " : "",
            pMonitor->statfilepath ? "to " : "",
            pMonitor->statfilepath ? pMonitor->statfilepath : "");
    }

    while(pMonitor->runMonitor == 1 && !g_proc_exit) {

        if((tv = timer_GetTime()) >= tvNext) {

            stream_monitor_dump(fp, pMonitor);

            tvNext += (intervalMs * TIME_VAL_MS);
        }

        usleep(100000);

    }

    if(fp) {
        fclose(fp);
    }

    pMonitor->runMonitor = -1;
    pthread_mutex_destroy(&pMonitor->mtx);
    pMonitor->active = -1;

    logutil_tid_remove(pthread_self());

}