Пример #1
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;
}
Пример #2
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));

}