Пример #1
0
static int sendRtcpSr(STREAM_XMIT_NODE_T *pStream, unsigned int idxDest) {
  int rc = 0;
  unsigned char buf[256];
  int len = 0;

  if(!pStream->pXmitAction->do_output_rtphdr) {
    return 0;
  }

  if((len = stream_rtcp_createsr(pStream->pRtpMulti, idxDest, buf, sizeof(buf))) < 0) {
    LOG(X_ERROR("Unable to create rtcp sr for destination[%d]"), idxDest);
    return -1;
  }

  //fprintf(stderr, "sendto rtcp sr [dest:%d] %s:%d %d pkt:%u,%u ts:%u\n", idxDest, inet_ntoa(pStream->saDstsRtcp[idxDest].sin_addr), ntohs(pStream->saDstsRtcp[idxDest].sin_port), len, pStream->pRtpMulti[idxDest].rtcp.sr.pktcnt,pStream->pRtpMulti[idxDest].rtcp.sr.octetcnt,htonl(pStream->pRtpMulti[idxDest].rtcp.sr.rtpts));

  if((rc = sendto(STREAM_RTCP_FD(pStream->pRtpMulti->pdests[idxDest]),
                  (void *) buf, len, 0,
                  (struct sockaddr *) &pStream->pRtpMulti->pdests[idxDest].saDstsRtcp,
                  sizeof(pStream->pRtpMulti->pdests[idxDest].saDstsRtcp))) != len) {

    LOG(X_ERROR("sendto (rtcp) %s:%d for %d bytes failed with "ERRNO_FMT_STR),
                inet_ntoa(pStream->pRtpMulti->pdests[idxDest].saDstsRtcp.sin_addr),
                ntohs(pStream->pRtpMulti->pdests[idxDest].saDstsRtcp.sin_port),
                len, ERRNO_FMT_ARGS);
    return -1;
  }


  return rc;
}
Пример #2
0
static int httplive_delete(HTTPLIVE_DATA_T *pLive) {
  char path[VSX_MAX_PATH_LEN];
  char buf[VSX_MAX_PATH_LEN];
  struct stat st;

  httplive_purgetsfiles(pLive, 0xffffffff);

  // 
  // Delete the playlist
  //
  if(snprintf(buf, sizeof(buf), "%s"HTTPLIVE_PL_NAME_EXT, pLive->fileprefix) >= 0) {
    mediadb_prepend_dir(pLive->dir, buf, path, sizeof(path));
    if(fileops_stat(path, &st) == 0 && fileops_DeleteFile(path) != 0) {
      LOG(X_ERROR("Failed to delete '%s'"), path);
    }
  }

  // 
  // Delete any multi-bitrate playlist
  //
  if(snprintf(buf, sizeof(buf), "%s"HTTPLIVE_PL_NAME_EXT, HTTPLIVE_MULTIBITRATE_NAME_PRFX) >= 0) {
    mediadb_prepend_dir(pLive->dir, buf, path, sizeof(path));
    if(fileops_stat(path, &st) == 0 && fileops_DeleteFile(path) != 0) {
      LOG(X_ERROR("Failed to delete '%s'"), path);
    }
  }

  return 0;
}
Пример #3
0
int srvlisten_startrtsplive(SRV_LISTENER_CFG_T *pListenCfg) {
  pthread_t ptdRtspLive;
  pthread_attr_t attrRtspLive;
  const char *s;
  int rc = 0;

  if(!pListenCfg || !pListenCfg->pConnPool || pListenCfg->max <= 0 || 
     !pListenCfg->pCfg || !pListenCfg->pCfg->cfgShared.pRtspSessions || 
     pListenCfg->pCfg->cfgShared.pRtspSessions->max <= 0) {
    return -1;
  }

  if((pListenCfg->netflags & NETIO_FLAG_SSL_TLS) && !netio_ssl_enabled(1)) {
    LOG(X_ERROR("SSL not enabled"));
    return -1;
  }

  if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') {
    snprintf(pListenCfg->tid_tag, sizeof(pListenCfg->tid_tag), "%s-rtsp", s);
  }
  pthread_attr_init(&attrRtspLive);
  pthread_attr_setdetachstate(&attrRtspLive, PTHREAD_CREATE_DETACHED);

  if(pthread_create(&ptdRtspLive,
                    &attrRtspLive,
                  (void *) srvlisten_rtsplive_proc,
                  (void *) pListenCfg) != 0) {

    LOG(X_ERROR("Unable to create rtsp listener thread"));
    return -1;
  }

  return rc;
}
Пример #4
0
int mp4_initMp4vTrack(const MP4_CONTAINER_T *pMp4, MP4_TRAK_MP4V_T *pMp4BoxSet) {

  if(!pMp4 || !pMp4BoxSet) {
    return -1;
  }

  if(!pMp4->pStream || !pMp4->pStream->cbCheckFd(pMp4->pStream)) {
    return -1;
  } 

  memset(pMp4BoxSet, 0, sizeof(MP4_TRAK_MP4V_T));

  if(pMp4->pStream->cbSeek(pMp4->pStream, 0, SEEK_SET) != 0) {
    return -1;
  }

  if((pMp4BoxSet->pMp4v = (BOX_MP4V_T *) mp4_loadTrack(pMp4->proot, &pMp4BoxSet->tk, 
                                  *((uint32_t *) "mp4v"), 1)) == NULL) {
    LOG(X_ERROR("No valid mp4v track found in %s"), pMp4->pStream->cbGetName(pMp4->pStream));
    return -1;
  }

  if((pMp4BoxSet->pEsds = (BOX_ESDS_T *) mp4_findBoxChild(
                        (BOX_T *)pMp4BoxSet->pMp4v, *((uint32_t *) "esds"))) == NULL) {
    LOG(X_ERROR("No valid esds track found in %s"), pMp4->pStream->cbGetName(pMp4->pStream));
    return -1;
  }

  return 0;
}
Пример #5
0
void xcode_ipc_close(XCODE_IPC_DESCR_T *pXcodeIpc) {
  struct shmid_ds buf;

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

  if(pXcodeIpc->shmid > 0) {
    if(pXcodeIpc->pmem) {
      shmdt(pXcodeIpc->pmem);
      pXcodeIpc->pmem = NULL;
    }
    shmctl(pXcodeIpc->shmid, IPC_RMID, &buf);
    pXcodeIpc->shmid = -1;
  }

  if(pXcodeIpc->sem_srv) {
    if(sem_close(pXcodeIpc->sem_srv) != 0) {
      LOG(X_ERROR("sem_close failed"));
    }
    pXcodeIpc->sem_srv = NULL;
    sem_unlink(XCODE_IPC_SEM_NAME_SRV);
  }
 
  if(pXcodeIpc->sem_cli) {
    if(sem_close(pXcodeIpc->sem_cli) != 0) {
      LOG(X_ERROR("sem_close failed"));
    }
    pXcodeIpc->sem_cli = NULL;
    sem_unlink(XCODE_IPC_SEM_NAME_CLI);
  }

}
Пример #6
0
void xcode_ipc_close(XCODE_IPC_DESCR_T *pIpc) {

  if(pIpc) {
    if(pIpc->shmid > 0) {
      shmdt(pIpc->pmem); 
      pIpc->shmid = 0;
    }

    if(pIpc->sem_srv) {
      if(sem_close(pIpc->sem_srv) != 0) {
        LOG(X_ERROR("sem_close srv failed"));
      }
      pIpc->sem_srv = NULL;
    }

    if(pIpc->sem_cli) {
      if(sem_close(pIpc->sem_cli) != 0) {
        LOG(X_ERROR("sem_close cli failed"));
      }
      pIpc->sem_cli = NULL;
    }

    free(pIpc);
    //fprintf(stderr, "close ipc ok\n");
  }

}
Пример #7
0
int mp4_initSamrTrack(const MP4_CONTAINER_T *pMp4, MP4_TRAK_SAMR_T *pMp4BoxSet) {

  if(!pMp4 || !pMp4BoxSet) {
    return -1;
  }

  if(!pMp4->pStream || !pMp4->pStream->cbCheckFd(pMp4->pStream)) {
    return -1;
  } 

  memset(pMp4BoxSet, 0, sizeof(MP4_TRAK_SAMR_T));

  if(pMp4->pStream->cbSeek(pMp4->pStream, 0, SEEK_SET) != 0) {
    return -1;
  }

  if((pMp4BoxSet->pSamr = (BOX_SAMR_T *) mp4_loadTrack(pMp4->proot, &pMp4BoxSet->tk, 
                                  *((uint32_t *) "samr"), 1)) == NULL) {
    LOG(X_ERROR("No valid samr track found in %s"), pMp4->pStream->cbGetName(pMp4->pStream));
    return -1;
  }

  if((pMp4BoxSet->pDamr = (BOX_DAMR_T *) mp4_findBoxChild(
                (BOX_T *)pMp4BoxSet->pSamr, *((uint32_t *) "damr"))) == NULL) {
    LOG(X_ERROR("No valid damr track found in %s"), pMp4->pStream->cbGetName(pMp4->pStream));
    return -1;
  }

  return 0;
}
Пример #8
0
static int parseIpPortStr(const char *localAddrStr, 
                          struct sockaddr_storage *pLocalAddr,
                          uint16_t localPorts[], size_t maxLocalPorts, int requirePort) {

  size_t numPortsAdded = 0; 
  int rc = 0;
  char host[512];
  char ports[128];
  char uri[512];

  host[0] = '\0';
  ports[0] = '\0';
  uri[0] = '\0';
  memset(localPorts, 0, sizeof(uint16_t) * maxLocalPorts);

  if((rc = strutil_parseAddress(localAddrStr, host, sizeof(host), ports, sizeof(ports), uri, sizeof(uri)) < 0)) {
    return rc;
  }

  if(net_getaddress(host, pLocalAddr) != 0 ||
     (pLocalAddr->ss_family != AF_INET6 && ((struct sockaddr_in *) pLocalAddr)->sin_addr.s_addr == INADDR_NONE)) {
    LOG(X_ERROR("Invalid address specified in '%s'"), localAddrStr);
    return -1;
  } else if(!requirePort && ports[0] == '\0') {
    LOG(X_ERROR("No port specified in '%s'"), localAddrStr);
    return -1;
  }

  if((numPortsAdded = capture_parsePortStr(ports, localPorts, maxLocalPorts, 1)) < 0) {
    LOG(X_ERROR("Invalid port specified in '%s'"), localAddrStr);
    return numPortsAdded;
  }

  return numPortsAdded;
}
Пример #9
0
static int dlts_netsock_onhandshake_completed(NETIO_SOCK_T *pnetsock) {
  int rc = 0;
  SRTP_PROTECTION_PROFILE *srtpProfile = NULL;
  unsigned char keys[DTLS_SRTP_KEYING_MATERIAL_SIZE];

  if(!(pnetsock->flags & NETIO_FLAG_SRTP)) {
    return 0;
  }

  if(!(srtpProfile = SSL_get_selected_srtp_profile(pnetsock->ssl.pCtxt))) {
    LOG(X_ERROR("DTLS-SRTP SSL_get_selected_srtp_profile failed, peer may not be DTLS-SRTP capable: %s"),
            ERR_reason_error_string(ERR_get_error()));
    return -1;
  }

  memset(keys, 0, sizeof(keys));
  if(SSL_export_keying_material(pnetsock->ssl.pCtxt, keys, sizeof(keys),
                             DTLS_SRTP_KEYS_LABEL, strlen(DTLS_SRTP_KEYS_LABEL), NULL, 0, 0) != 1) {
    LOG(X_ERROR("DTLS-SRTP SSL_export_keying_material failed: %s"),
            ERR_reason_error_string(ERR_get_error()));
    return -1;
  }

  //LOG(X_DEBUG("dlts_netsock_onhandshake_completed DTLS-SRTP handshake selected profile: '%s', master-keys: "), srtpProfile->name); LOGHEX_DEBUG(keys, sizeof(keys));

  if(pnetsock->ssl.dtlsKeysUpdateCtxt.cbKeyUpdateFunc) {
    pnetsock->ssl.dtlsKeysUpdateCtxt.cbKeyUpdateFunc(pnetsock->ssl.dtlsKeysUpdateCtxt.pCbData, pnetsock,
                                                     srtpProfile->name, pnetsock->ssl.dtlsKeysUpdateCtxt.dtls_serverkey,
                                                     pnetsock->ssl.dtlsKeysUpdateCtxt.is_rtcp,
                                                     keys, sizeof(keys));
  }

  return rc;
}
Пример #10
0
static int getSampleDuration(BOX_STTS_T *pStts, 
                              unsigned int *pidxSampleInStts,
                              unsigned int *pidxStts) {

  uint32_t sampleHz = 0;

  if(pStts->list.entrycnt == 0 || !pStts->list.pEntries) {
    LOG(X_ERROR("Invalid stts entry count: %u"), pStts->list.entrycnt);
    return -1;
  } else if(*pidxStts >= pStts->list.entrycnt) {
    LOG(X_ERROR("Invalid stts index referenced: %u/%u"), (*pidxStts)+1, pStts->list.entrycnt); 
    return -1;
  } else if(*pidxSampleInStts >= pStts->list.pEntries[*pidxStts].samplecnt) {
    LOG(X_ERROR("Invalid stts[%u] entry index referenced: %u/%u"), *pidxStts, 
                (*pidxSampleInStts)+1, pStts->list.pEntries[*pidxStts].samplecnt); 
    return -1;
  }

  sampleHz = pStts->list.pEntries[*pidxStts].sampledelta;
  (*pidxSampleInStts)++;
  if(*pidxSampleInStts >= pStts->list.pEntries[*pidxStts].samplecnt) {
    *pidxSampleInStts = 0;
    (*pidxStts)++;
  }

  return (int) sampleHz;
}
Пример #11
0
int capture_parseAuthUrl(const char **ppstr, AUTH_CREDENTIALS_STORE_T *pauth) {
  int rc = 0;
  const char *p;
  const char *pendcred = NULL;
  const char *pcolon = NULL;

  if(!ppstr || !(p = *ppstr)) {
    return -1;
  }

  //
  // Check if we have a username or pass
  //
  while(*p != '\0' && *p != '/' && *p != '@') {
    p++;
  }

  if(*p == '@') {
    pendcred = p;
    p = (*ppstr); 
    //
    // Check if we have a username and pass
    //
    while(*p != '\0' && *p != ':' && *p != '@') {
      p++;
    }
    if(*p == ':') {
      pcolon = p;
      p++;
      if(pauth) {
        if(pendcred - p >= sizeof(pauth->pass)) {
          LOG(X_ERROR("Auth password credentials too long in: %s"), *ppstr);
          return -1;
        }
        memcpy(pauth->pass, p, (pendcred - p));
        pauth->username[pendcred - p] = '\0';
      }
    } else {
      pcolon = pendcred;
    }

    if(pauth) {
      if(pcolon - (*ppstr) >= sizeof(pauth->username)) {
        LOG(X_ERROR("Auth username credentials too long in: %s"), *ppstr);
        return -1;
      }
      memcpy(pauth->username, *ppstr, (pcolon - *ppstr));
      pauth->username[pcolon - *ppstr] = '\0';
    }

  }

  if(pendcred) {
    (*ppstr) += (pendcred - *ppstr + 1);
  }

  return rc;
}
Пример #12
0
static int get_ts(HTTPLIVE_CLIENT_T *pClient, const char *puri) {
  int rc = 0;
  HTTP_PARSE_CTXT_T hdrCtxt;
  HTTP_RESP_T httpResp;
  const char *p = NULL;
  unsigned char *pdata;
  unsigned int contentLen = 0;
  char fulluri[256];
  unsigned char buf[RTP_JTBUF_PKT_BUFSZ_LOCAL + SOCKET_LIST_PREBUF_SZ];

  //LOG(X_DEBUG("Retrieving TS chunk '%s'"), puri);

  if(pClient->uriprefix[0] != '\0') {
    snprintf(fulluri, sizeof(fulluri), "%s%s", pClient->uriprefix, puri);
    puri = fulluri;
  }

  memset(&hdrCtxt, 0, sizeof(hdrCtxt));
  memset(&httpResp, 0, sizeof(httpResp));
  hdrCtxt.pnetsock = &pClient->netsock;
  hdrCtxt.pbuf = (char *) buf;
  hdrCtxt.szbuf = sizeof(buf);
  hdrCtxt.tmtms = 0;

  if((httpcli_gethdrs(&hdrCtxt, &httpResp, &pClient->sa, puri,
          http_getConnTypeStr(HTTP_CONN_TYPE_KEEPALIVE), 0, 0, pClient->hostbuf, NULL)) < 0) {
    return -1;
  }

  if(!(p = conf_find_keyval(httpResp.hdrPairs, HTTP_HDR_CONTENT_TYPE))) {
    LOG(X_ERROR("No "HTTP_HDR_CONTENT_TYPE" found in response"));
    return -1;
  } else if(!(strncasecmp(p, CONTENT_TYPE_MP2TS, strlen(CONTENT_TYPE_MP2TS)) &&
              strncasecmp(p, CONTENT_TYPE_OCTET_STREAM, strlen(CONTENT_TYPE_OCTET_STREAM)))) {
    LOG(X_ERROR("Unsupported %s: %s received in response for %s"),
               HTTP_HDR_CONTENT_TYPE, (p ? p : "<Not Found>"), puri);
    rc = -1;
  }

  if(!(pdata = http_get_contentlen_start(&httpResp, &hdrCtxt, buf, sizeof(buf), 
                                    0, &contentLen))) {
    rc = -1;
  }

  //fprintf(stderr, "TS contentlen:%d pdata:0x%x idxb:%d hdrslen:%d\n", contentLen, pdata, hdrCtxt.idxbuf, hdrCtxt.hdrslen);  

  if(rc >= 0 && pClient->pCfg->running == 0) {
    rc = http_recvloop(pClient->pCfg, &pClient->netsock, &pClient->sa, 
                       pClient->pStreamsOut, pClient->pStream, 
                       hdrCtxt.hdrslen, hdrCtxt.idxbuf - hdrCtxt.hdrslen, 
                       contentLen,
                       buf, sizeof(buf));
  }

  //fprintf(stderr, "TS DONE w rc:%d\n", rc);

  return rc;
}
Пример #13
0
int mediadb_mkdirfull(const char *root, const char *path) {

  size_t idxprev;
  struct stat st;
  size_t sz = 0;
  size_t len;
  char buf[VSX_MAX_PATH_LEN];

//  fprintf(stdout, "mkdirfull '%s' '%s'\n", root, path);

  if(!path) {
    return -1;
  }

  if(root) {
    sz = strlen(root);
  }

  buf[sizeof(buf) - 1] = '\0';
  idxprev = sz;
  len = strlen(path);
 
  for(; sz < len && sz < sizeof(buf); sz++) {
    if(path[sz] == DIR_DELIMETER)  {

      memset(buf, 0, sizeof(buf));
      strncpy(buf, path, sz);

//fprintf(stdout, "stat '%s'\n", buf);
      if(strlen(buf) > 0 && fileops_stat(buf, &st) != 0) {
        LOG(X_DEBUG("Creating dir '%s'"), buf);
        if(fileops_MkDir(buf, S_IRWXU | S_IRWXG | S_IRWXO ) < 0) {
          LOG(X_ERROR("Unable to create dir '%s'"), buf);
          return -1;
        }
      }

      while(path[sz] == DIR_DELIMETER) {
        sz++;
      }
      idxprev = sz;
//fprintf(stdout, "after'%s'\n", &path[sz]);
    }
  }
  

  if(sz > idxprev && fileops_stat(path, &st) != 0) {
    LOG(X_DEBUG("Creating dir '%s'"), path);
    if(fileops_MkDir(path, S_IRWXU | S_IRWXG | S_IRWXO ) < 0) {
      LOG(X_ERROR("Unable to create dir '%s'"), path);
      return -1;
    }
  }

  return 0;
}
Пример #14
0
int dtls_get_cert_fingerprint(const char *certPath, DTLS_FINGERPRINT_T *pFingerprint) {
  int rc = 0;
  unsigned int lenHash;
  X509 *pX509 = NULL;
  BIO *pBIO = NULL;
  const EVP_MD *pEvp = NULL;

  if(!certPath || !pFingerprint) {
    return -1;
  }

  pFingerprint->buf[0] = '\0';
  pFingerprint->len = 0;

  if(!(pEvp = dtlsFingerprintTypeToEVP(pFingerprint->type))) {
    LOG(X_ERROR("DTLS invalid fingerprint digest type"));
    return -1;
  }

  if(!(pBIO = BIO_new(BIO_s_file()))) {
    LOG(X_ERROR("DTLS BIO_new failed for '%s': %s"), certPath,  ERR_reason_error_string(ERR_get_error()));
    return -1;
  }

  if(rc >= 0 && BIO_read_filename(pBIO, certPath) != 1){
    LOG(X_ERROR("DTLS BIO_read_filename failed for '%s': %s"), certPath,  ERR_reason_error_string(ERR_get_error()));
    rc = -1;
  }

  if(rc >= 0 && !(pX509 = PEM_read_bio_X509(pBIO, NULL, 0, NULL))){
    LOG(X_ERROR("DTLS PEM_read_bio_X509 failed for '%s': %s"), certPath,  ERR_reason_error_string(ERR_get_error()));
    rc = -1;
  }

  lenHash = sizeof(pFingerprint->buf);

  if(rc >= 0 && (X509_digest(pX509, pEvp, pFingerprint->buf, &lenHash) != 1 || lenHash <= 0)) {
    LOG(X_ERROR("DTLS X509_digest failed for '%s': %s"), certPath,  ERR_reason_error_string(ERR_get_error()));
    rc = -1;
  } else {
    pFingerprint->len = lenHash;
    rc = pFingerprint->len;
  }

  //avc_dumpHex(stderr, buf, sizeof(buf), 1);

  if(pX509) {
    X509_free(pX509);
  }

  if(pBIO) {
    BIO_free_all(pBIO);
  }

  return rc;
}
Пример #15
0
int pktgen_GetLocalAdapterInfo(const char *dev,
                               unsigned char *pmacaddr, 
                               in_addr_t *pnetaddr) {
//#ifdef DISABLE_PCAP
//  return -1;
//#else // DISABLE_PCAP

  IP_ADAPTER_INFO adapterInfo[10];
  IP_ADAPTER_INFO *pAdapterInfo = NULL;
  unsigned long adaptersLen = sizeof(adapterInfo);
  unsigned int rc;

  memset(adapterInfo, 0, sizeof(adapterInfo));

  if((rc = GetAdaptersInfo(adapterInfo, &adaptersLen)) != ERROR_SUCCESS) {
    LOG(X_ERROR("GetAdaptersInfo Failed with code: %d"),  rc);
    return -1;
  }

  pAdapterInfo = adapterInfo;

  do {

    if(pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET) {
      if(!dev || (strstr(dev, pAdapterInfo->AdapterName) &&
         pAdapterInfo->AddressLength == ETH_ALEN)) {
        
        if(pmacaddr) {
          memcpy(pmacaddr, pAdapterInfo->Address, ETH_ALEN);
        }

        if(pnetaddr) {
          if((*pnetaddr = 
               inet_addr(pAdapterInfo->IpAddressList.IpAddress.String)) == INADDR_NONE) {
            LOG(X_ERROR("Cannot determinte IP address for adapter '%s'"), 
                pAdapterInfo->AdapterName);
            return -1;  
          } else if(dev || *pnetaddr != INADDR_ANY) {
            return 0;
          }
        } else {
          return 0;
        }
      }
    }

    pAdapterInfo = pAdapterInfo->Next;

  } while(pAdapterInfo);

  LOG(X_ERROR("Unable to find network adapter.  None matching name '%s'"), 
              dev ? dev : "<any>");

  return -1;
//#endif // DISABLE_PCAP
}
Пример #16
0
int net_recvnb(SOCKET sock, unsigned char *buf, unsigned int len, 
                      unsigned int mstmt, int peek, int *pclosed) {
  struct timeval tv;
  fd_set fdsetRd;
  int rc;
  int sockflags = 0;

#if !defined(__APPLE__) && !defined(WIN32)
  sockflags = MSG_NOSIGNAL;
#endif // __APPLE__

  if(sock == INVALID_SOCKET) {
    return -1;
  }

  if(peek) {
    sockflags |= MSG_PEEK;
  }

  if(pclosed) {
    *pclosed = 0;
  }

  tv.tv_sec = (mstmt / 1000);
  tv.tv_usec = (mstmt % 1000) * 1000;

  FD_ZERO(&fdsetRd);
  FD_SET(sock, &fdsetRd);

  if((rc = select(sock + 1, &fdsetRd, NULL, NULL, &tv)) > 0) {

    if((rc = recv(sock, (void *) buf, len, sockflags)) < 0) {
      LOG(X_ERROR("recv nonblock %d, sockflags: 0x%x returned %d "ERRNO_FMT_STR), 
          len, sockflags, rc, ERRNO_FMT_ARGS);
    } else if(rc == 0) {
      LOG(X_WARNING("recv nonblock %d - connection has been closed."), len);
      if(pclosed) {
        *pclosed = 1;
      }
      // Do not return 0, since that is what select will return if timeout has expired
      return -1;
    } else {
      VSX_DEBUG_NET( LOG(X_DEBUG("NET - net_recvnb %s %d/%d bytes, fd: %d"), peek ? "peeked" : "got", rc, len, sock) );
    }

  } else if(rc == 0) {
    //fprintf(stderr, "TMT EXPIRED sock:%d tv:%d,%d, mstmt:%d\n", sock, tv.tv_sec, tv.tv_usec, mstmt);
    // timeout expired
  } else {
    LOG(X_ERROR("select socket:%d returned: %d"), sock, rc);
  }

  return rc;
}
Пример #17
0
static int mp4_extractAacAud(const MP4_CONTAINER_T *pMp4, const char *path, 
                      float fStart, float fDuration) {
  FILE_STREAM_T fStreamOut;
  MP4_TRAK_MP4A_T mp4BoxSet;
  ESDS_CBDATA_WRITE_SAMPLE_T esdsDescr;
  unsigned char buf[4096];
  uint64_t startHz = 0;
  uint64_t durationHz = 0;
  int rc = 0;

  if(!pMp4|| !pMp4->pStream || pMp4->pStream == FILEOPS_INVALID_FP) {
    return -1;
  }

  LOG(X_DEBUG("Extracting aac audio from %s"), pMp4->pStream->cbGetName(pMp4->pStream));

  esdsDescr.bs.buf = buf;
  esdsDescr.bs.sz = sizeof(buf);
  esdsDescr.bs.idx = 0;

  if(mp4_initMp4aTrack(pMp4, &mp4BoxSet) < 0) {
    return -1;
  }

  if(mp4BoxSet.pEsds->config.objtypeid != ESDS_OBJTYPE_MP4A) {
    LOG(X_ERROR("Unsupported mp4a esds object type descriptor: %u"), 
                mp4BoxSet.pEsds->config.objtypeid);
    return -1;
  } else if(esds_decodeDecoderSp(mp4BoxSet.pEsds->specific.startcodes, 
        (mp4BoxSet.pEsds->specific.type.length > sizeof(mp4BoxSet.pEsds->specific.startcodes) ?
        sizeof(mp4BoxSet.pEsds->specific.startcodes) : mp4BoxSet.pEsds->specific.type.length), 
        &esdsDescr.decoderCfg) != 0) {
    LOG(X_ERROR("Failed to decode mp4a esds decoder specific data for type descriptor: %u"), 
                mp4BoxSet.pEsds->config.type.descriptor);
    return -1;
  }

  durationHz = (uint64_t) (fDuration * mp4BoxSet.tk.pMdhd->timescale);
  startHz = (uint64_t) (fStart * mp4BoxSet.tk.pMdhd->timescale);

  if((fStreamOut.fp = fileops_Open(path, O_RDWR | O_CREAT)) == FILEOPS_INVALID_FP) {
    LOG(X_CRITICAL("Unable to open file for writing: %s"), path);
    return -1;
  }
  fStreamOut.offset = 0;

  esdsDescr.pStreamOut = &fStreamOut;
  rc = mp4_readSamplesFromTrack(&mp4BoxSet.tk, pMp4->pStream, esds_cbWriteSample_mp4wrap, 
                                &esdsDescr, startHz, durationHz);

  fileops_Close(fStreamOut.fp);

  return rc;
}
Пример #18
0
static SILK_ENCODER_CODEC_CTXT_T *encoder_silk_alloc() {
  SILK_ENCODER_CODEC_CTXT_T *pSilk;
  SKP_int32 encSizeBytes;

  if(!(pSilk = (SILK_ENCODER_CODEC_CTXT_T *) calloc(1, sizeof(SILK_ENCODER_CODEC_CTXT_T)))) {
    return NULL;
  }

  if(encoder_load_dynamic(pSilk) < 0) {
    return NULL;
  }

  pSilk->pts = 0;

  //if(SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes ) != 0) {
  if(pSilk->fGetEncoderSize(&encSizeBytes) != 0) {
    LOG(X_ERROR("SKP_Silk_SDK_Get_Encoder_Size failed"));
    encoder_silk_free(pSilk);
    return NULL;
  }

  if(!(pSilk->psEnc = malloc(encSizeBytes))) {
    encoder_silk_free(pSilk);
    return NULL;
  }

  return pSilk;
}
Пример #19
0
static MP4_CONTAINER_T *cap_http_mp4_open(const char *path, CAP_ASYNC_DESCR_T *pCapCfg) {
  MP4_CONTAINER_T *pMp4 = NULL;

  if(!path || !pCapCfg) {
    return NULL;
  }

  //
  // Used to open an mp4 container which may have an mdat box that is dynamically growing
  //

  //fprintf(stderr, "OPENING MP4 FOR STREAMING '%s'\n", path);

  if((pMp4 = mp4_open(path, 1)) == NULL) {
    LOG(X_ERROR("Failed to read downloaded mp4 path %s"), path);
    return NULL;
  }

  //
  // Change the read data file callback to handle the dynamically growing MDAT
  //
  pMp4->pStream->pUserData = pCapCfg;
  pMp4->pStream->cbRead = mp4_cbReadDataFileLive;
  pMp4->pStream->cbSeek = mp4_cbSeekDataFileLive;

  return pMp4;
}
Пример #20
0
int dtls_netsock_setmtu(NETIO_SOCK_T *pnetsock, int mtu) {

  if(!pnetsock || !pnetsock->ssl.pCtxt) {
    return -1;
  } else if(mtu <= 0) {
    return 0;
  } else {
#if defined(__linux__) 

    if(mtu < 228) {
      LOG(X_ERROR("Cannot set DTLS MTU %d below minimum %d"), 228);
      return -1;
    }

    pthread_mutex_lock(&((STREAM_DTLS_CTXT_T *) pnetsock->ssl.pDtlsCtxt)->mtx);

    LOG(X_DEBUG("Setting DTLS MTU %d (netsock: 0x%x)"), mtu, pnetsock);
    // openSSL MTU may be broken on Mac, but may work on Linux
    //SSL_set_options(pnetsock->ssl.pCtxt, SSL_OP_NO_QUERY_MTU); //TODO: setting this makes the socket mtu 0, and the ssl/d1_both.c:268 assert crashes the app 
    SSL_set_mtu(pnetsock->ssl.pCtxt, mtu);
    //SSL_set_mtu(pnetsock->ssl.pCtxt, mtu - 28);

    pthread_mutex_unlock(&((STREAM_DTLS_CTXT_T *) pnetsock->ssl.pDtlsCtxt)->mtx);

#endif // (__linux__) 
    return 0;
  }

}
Пример #21
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;
}
Пример #22
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;
}
Пример #23
0
int capture_parsePortStr(const char *str,
                 uint16_t localPorts[], 
                 size_t maxLocalPorts,
                 int noDup) {

  const char *p, *p2, *pdata;
  size_t numPortsAdded = 0; 
  char buf[64];
  int rc;

  p = str;

  while(p && numPortsAdded < maxLocalPorts) {

    if((p2 = strstr(p, ","))) {
      pdata = strutil_safe_copyToBuf(buf, sizeof(buf), p, p2);
    } else {
      pdata = p;
    }

    if((rc = addPorts(pdata, localPorts, &numPortsAdded, maxLocalPorts, noDup)) < 0) {
      LOG(X_ERROR("Invalid port specified in '%s'"), str);
      return rc;
    }

    if((p = p2)) {
      p++;
    }
  }

  return numPortsAdded;
}
Пример #24
0
int flvsrv_send_vidframe(FLVSRV_CTXT_T *pFlvCtxt, const OUTFMT_FRAME_DATA_T *pFrame, int keyframe) {
  BYTE_STREAM_T bstmp;
  uint32_t timestamp32 = 0;
  unsigned char *pData = NULL;
  unsigned int lenData = 0;
  int rc;

  //
  // Compute the frame timestamp in ms, relative from the start
  //
  if(OUTFMT_PTS(pFrame)  > pFlvCtxt->av.vid.tm0) {
    timestamp32  = (OUTFMT_PTS(pFrame) - pFlvCtxt->av.vid.tm0) / 90.0f;
  }
  //pFlvCtxt->av.vid.tmprev = timestamp32; // this may be wrong... tmprev is a 90KHz pts

  pFlvCtxt->out.prevtagidx = pFlvCtxt->out.bs.idx;
  memcpy(&bstmp, &pFlvCtxt->out.bs, sizeof(bstmp));
  pFlvCtxt->out.bs.idx += FLV_TAG_HDR_SZ_NOPREV;

  if((rc = flvsrv_create_vidframe_h264(&pFlvCtxt->out.bs, &pFlvCtxt->av.vid, pFrame, 
                                        NULL, NULL, keyframe)) < 0) {
    return rc;
  }


  pData = &pFlvCtxt->av.vid.tmpFrame.buf[pFlvCtxt->av.vid.tmpFrame.idx];
  lenData = rc;
  //LOGHEX_DEBUG(pData, MIN(16, lenData));
  //LOG(X_DEBUG("0x%x len:%d"), pData[4] & NAL_TYPE_MASK, lenData);
  if(pFlvCtxt->av.vid.tmpFrame.idx + lenData + 4 > pFlvCtxt->av.vid.tmpFrame.sz) {
    LOG(X_ERROR("flvsrv video frame size %d is too large for %d"), lenData, pFlvCtxt->av.vid.tmpFrame.sz);
    return -1;
  }
  pFlvCtxt->av.vid.tsLastWrittenFrame = timestamp32;

  //
  // Now that the data length is known, fill in the 11 byte flv header
  //
  flv_write_taghdr(&bstmp, FLV_TAG_VIDEODATA, 
                   lenData + pFlvCtxt->out.bs.idx - pFlvCtxt->out.prevtagidx - FLV_TAG_HDR_SZ_NOPREV, 
                   timestamp32); 

  pFlvCtxt->writeErrDescr = "video header";
  if((rc = pFlvCtxt->cbWrite(pFlvCtxt, pFlvCtxt->out.bs.buf, pFlvCtxt->out.bs.idx)) < 0) {
    return rc;
  }

  //
  // 4 byte previous tag size field
  //
  *((uint32_t *) &pData[lenData]) = htonl(lenData + pFlvCtxt->out.bs.idx - pFlvCtxt->out.prevtagidx);
  lenData += 4;

  pFlvCtxt->writeErrDescr = "video payload";
  if((rc = pFlvCtxt->cbWrite(pFlvCtxt, pData, lenData)) < 0) {
    return rc;
  }

  return rc;
}
Пример #25
0
int procdb_delete(SYS_PROCLIST_T *pProcs, const char *name, const char *id, int lock) {
  int rc = -1;
  SYS_PROC_T *pProc = NULL;
  SYS_PROC_T *pProcPrev = NULL;

  if(!pProcs || !name) {
    return -1;
  }

  if(!id) {
    id = "";
  }

  if(lock) {
    pthread_mutex_lock(&pProcs->mtx); 
  }

  pProc = pProcs->procs;

  while(pProc) {

   if(!strcasecmp(pProc->name, name) && !strcasecmp(pProc->id, id)) {
   
      if(pProcPrev) {
        pProcPrev->pnext = pProc->pnext;
      }
      if(pProcs->procs == pProc) {
        pProcs->procs = pProc->pnext;
      }

      LOG(X_DEBUG("Removing process '%s' pid:%d flags:0x%x"), 
          pProc->name, pProc->pid, pProc->flags);

      if(pProcs->activeInstances > 0) {
        pProcs->activeInstances--;
      }
      if(pProc->isXcoded && pProcs->activeXcodeInstances > 0) {
        pProcs->activeXcodeInstances--;
      }

      free(pProc);
      rc = 0;
      break;

    } else { 
      pProcPrev = pProc;
      pProc = pProc->pnext;
    }
  }

  if(lock) {
    pthread_mutex_unlock(&pProcs->mtx); 
  }

  if(rc != 0) {
    LOG(X_ERROR("Failed to remove process '%s'"), pProc->name);
  }

  return rc;
}
Пример #26
0
static int getSamplesInChunk(BOX_STSC_T *pStsc, unsigned int idxChunk, unsigned int *pidxStsc) {

  //
  //     1th based first chunk, samples per chunk, 1th based idx in stsd
  // { stsc[0]: 0x1 0x1e 0x1 , stsc[1]: 0xf2 0x3 0x1 }
  //

  if(*pidxStsc >= pStsc->entrycnt) {
    return -1;
  } 

  if(pStsc->pEntries[*pidxStsc].sampledescidx != 1) {
    LOG(X_ERROR("stsc[%d].sampledescidx=%d (!= 1) not implemented!"), 
          *pidxStsc, pStsc->pEntries[*pidxStsc].sampledescidx);
    return -1;
  }

  if(*pidxStsc < pStsc->entrycnt-1) {
    if(idxChunk >= pStsc->pEntries[(*pidxStsc) + 1].firstchunk - 1) {
      (*pidxStsc)++;
    }
  }

  return pStsc->pEntries[*pidxStsc].sampleperchunk;
}
Пример #27
0
const STREAM_DEVICE_T *devtype_finddevice(const char *userAgent, int matchany) {
  const STREAM_DEVICE_T *pdev = NULL;

  if(!g_devtypes) {
    //devtype_init();
    LOG(X_ERROR("Device database not configured"));
    return NULL;
  }

  pdev = g_devtypes;
  while(pdev) {

    //
    // if matchany is set, any default empty match can be made (last fall-thru device)
    // match & match2 is an 'and' based match
    //
    if(matchany || pdev->strmatch[0] != '\0' || pdev->strmatch[1] != '\0') {

      if(pdev->strmatch[0] == '\0' || (userAgent && strcasestr(userAgent, pdev->strmatch))) {
        if(pdev->strmatch2[0] == '\0' || 
          (userAgent && strcasestr(userAgent, pdev->strmatch2))) {
          return pdev;
        }
      }
    }
    pdev = pdev->pnext;
  }

  if(matchany) {
    return pdev;
  } else {
    return NULL;
  }  
}
Пример #28
0
static int create_and_write_mpd(MPD_CREATE_CTXT_T *pCtxt, 
                                const MPD_ADAPTATION_T *pAdaptationList,
                                DASH_MPD_TYPE_T mpdType, 
                                int outidx,
                                int idxmax,
                                unsigned int mediaSequenceIndex,
                                int mediaSequenceMin) {
  int rc = 0;
  int idxbuf = 0;
  FILE_HANDLE fp;
  char buf[4096];
  char mpdpath[VSX_MAX_PATH_LEN];

  //
  // Create the .mpd xml file contents
  //
  if((idxbuf = mpd_doc_create(mpdType, pAdaptationList, pCtxt, 
                              outidx, mediaSequenceIndex, buf, sizeof(buf))) <= 0) {
    return -1;
  }

  //
  // Write the .mpd xml file to disk 
  //
  if((rc = write_mpd_path(pCtxt, outidx, mpdType, mpdpath, sizeof(mpdpath))) < 0) {
    return rc;
  }

  if((fp = fileops_Open(mpdpath, O_RDWR | O_CREAT)) == FILEOPS_INVALID_FP) {
    LOG(X_ERROR("Failed to open DASH mpd '%s' for writing"), mpdpath);
    return -1;
  }

  if((rc = fileops_WriteBinary(fp, (unsigned char *) buf, idxbuf)) < 0) {
    LOG(X_ERROR("Failed to write %d to DASH mpd '%s'"), idxbuf, mpdpath);
  }

  fileops_Close(fp);

  if(rc >= 0) {
    LOG(X_DEBUG("Updated DASH playlist '%s' (%d - %d)"), mpdpath, mediaSequenceMin, idxmax);
  } else {
    LOG(X_ERROR("Failed to update DASH playlist '%s' (%d - %d)"), mpdpath, mediaSequenceMin, idxmax);
  }

  return rc;
}
Пример #29
0
int strutil_convertDstStr(const char *dstArg, char dstHost[], size_t szHost,
                         uint16_t dstPorts[], size_t numDstPorts, 
                         char dstUri[], size_t szUri) {
  int numPorts = 0;

  if(!dstArg) {
    LOG(X_ERROR("No destination host specified"));
    return -1;
  } else if((numPorts = getHostAndPorts(dstArg, dstHost, szHost, dstPorts, numDstPorts, 0, dstUri, szUri)) < 0) {
    return -1;
  } else  if((numPorts == 0 || dstPorts[0] == 0) && inet_addr(dstHost) != INADDR_NONE) {
    LOG(X_ERROR("No destination port given"));
    return -1;
  }

  return numPorts;
}
Пример #30
0
int xcode_frame_aud(IXCODE_AUDIO_CTXT_T *pIn, unsigned char *bufIn, unsigned int lenIn,
                    unsigned char *bufOut, unsigned int lenOut) {
  XCODE_IPC_MEM_T *pMem;
  IXCODE_AUDIO_CTXT_T *pXcodeA;
  int rc, rcorig;

  if(!pIn->common.pIpc) {
    return -1;
  }

  pMem = ((XCODE_IPC_DESCR_T *) pIn->common.pIpc)->pmem;
  pXcodeA = &pMem->hdr.ctxt.aud;

  if(lenIn + lenOut > XCODE_IPC_MEM_DATASZ(pMem)) {
    LOG(X_ERROR("shared mem buffer size %d too small for %d + %d"),
                XCODE_IPC_MEM_DATASZ(pMem), lenIn, lenOut); 
    return -1;
  } 

  pXcodeA->common.inpts90Khz = pIn->common.inpts90Khz;
  pXcodeA->common.outpts90Khz = pIn->common.outpts90Khz;
  pXcodeA->common.decodeInIdx = pIn->common.decodeInIdx;
  pXcodeA->common.decodeOutIdx = pIn->common.decodeOutIdx;
  pXcodeA->common.encodeInIdx = pIn->common.encodeInIdx;
  pXcodeA->common.encodeOutIdx = pIn->common.encodeOutIdx;
  pXcodeA->pts = pIn->pts;

  // The following may not have been set during init
  //pXcodeA->cfgChannelsIn = pIn->cfgChannelsIn;
  //pXcodeA->cfgSampleRateIn = pIn->cfgSampleRateIn;

  if(bufIn) {
    memcpy(XCODE_IPC_MEM_DATA(pMem), bufIn, lenIn);
  }
  pMem->hdr.cmdrc = lenIn;
  pMem->hdr.offsetOut = lenIn;

  if((rc = rcorig = xcode_call_ipc(pIn->common.pIpc, XCODE_IPC_CMD_ENCODE_AUD)) != -1) {
    pIn->common.inpts90Khz = pXcodeA->common.inpts90Khz;
    pIn->common.outpts90Khz = pXcodeA->common.outpts90Khz;
    pIn->common.decodeInIdx = pXcodeA->common.decodeInIdx;
    pIn->common.decodeOutIdx = pXcodeA->common.decodeOutIdx;
    pIn->common.encodeInIdx = pXcodeA->common.encodeInIdx;
    pIn->common.encodeOutIdx = pXcodeA->common.encodeOutIdx;
    pIn->pts = pXcodeA->pts;

    if(rcorig > (int) (XCODE_IPC_MEM_DATASZ(pMem) - lenIn)) {
      rc = XCODE_IPC_MEM_DATASZ(pMem) - lenIn;
      LOG(X_WARNING("Encoded audio frame length truncated from %d to %d"), rcorig, rc);
    } else if(rc > (int) lenOut) {
      rc = lenOut;
      LOG(X_WARNING("Encoded audio frame length truncated from %d to %d"), rcorig, rc);
    }
    memcpy(bufOut, XCODE_IPC_MEM_DATA(pMem) + lenIn, rc);
  }

  return rc;
}