JNIEXPORT jint JNICALL Java_net_butterflytv_rtmp_1client_RTMPMuxer_close(JNIEnv *env, jobject instance) { rtmp_close(); return 0; }
extern "C" int Java_com_dttv_dtlive_utils_LiveJniLib_native_1stream_1release(JNIEnv *env, jobject thiz) { if(rtmp_handle) rtmp_close(rtmp_handle); if(flvmux_handle) flvmux_close(flvmux_handle); rtmp_handle = NULL; return 0; }
JNIEXPORT jint JNICALL Java_net_butterflytv_rtmp_1client_RTMPMuxer_close(JNIEnv *env, jobject thiz) { jfieldID fid = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, thiz), "rtmp", "J"); jlong raw_rtmp = (*env)->GetLongField(env, thiz, fid); RTMP *rtmp = (RTMP*)(*(void**)&raw_rtmp); if(rtmp == NULL) { return -10000; } rtmp_close(rtmp); raw_rtmp = 0; (*env)->SetLongField(env, thiz, fid, raw_rtmp); return 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; }
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)); }
static void http_flv_close(CAP_HTTP_FLV_T *pState) { rtmp_close(&pState->client.ctxt); }