http streaming: added a 'raw' container that works just like the passthrough muxer, but doesn't inject pmt/pat
this is used when subscribing to a complete dvb mux
This commit is contained in:
parent
048856342f
commit
cdd6c6c7d3
5 changed files with 56 additions and 30 deletions
|
@ -1299,7 +1299,11 @@ dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi,
|
|||
const char *client)
|
||||
{
|
||||
th_subscription_t *s;
|
||||
streaming_message_t *sm;
|
||||
streaming_start_t *ss;
|
||||
int r;
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
char buf[100];
|
||||
|
||||
s = subscription_create(INT32_MAX, name, st, SUBSCRIPTION_RAW_MPEGTS,
|
||||
NULL, hostname, username, client);
|
||||
|
@ -1308,10 +1312,36 @@ dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi,
|
|||
s->ths_tdmi = tdmi;
|
||||
LIST_INSERT_HEAD(&tdmi->tdmi_subscriptions, s, ths_tdmi_link);
|
||||
|
||||
dvb_fe_tune(tdmi, "Full mux subscription");
|
||||
r = dvb_fe_tune(tdmi, "Full mux subscription");
|
||||
|
||||
pthread_mutex_lock(&tda->tda_delivery_mutex);
|
||||
|
||||
streaming_target_connect(&tda->tda_streaming_pad, &s->ths_input);
|
||||
|
||||
if(r) {
|
||||
sm = streaming_msg_create_code(SMT_NOSTART, SM_CODE_NO_INPUT);
|
||||
streaming_target_deliver(s->ths_output, sm);
|
||||
} else {
|
||||
ss = calloc(1, sizeof(streaming_start_t));
|
||||
ss->ss_num_components = 0;
|
||||
ss->ss_refcount = 1;
|
||||
|
||||
ss->ss_si.si_type = S_MPEG_TS;
|
||||
ss->ss_si.si_device = strdup(tdmi->tdmi_adapter->tda_rootpath);
|
||||
ss->ss_si.si_adapter = strdup(tdmi->tdmi_adapter->tda_displayname);
|
||||
ss->ss_si.si_service = strdup("Full mux subscription");
|
||||
|
||||
if(tdmi->tdmi_network != NULL)
|
||||
ss->ss_si.si_network = strdup(tdmi->tdmi_network);
|
||||
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
ss->ss_si.si_mux = strdup(buf);
|
||||
|
||||
|
||||
sm = streaming_msg_create_data(SMT_START, ss);
|
||||
streaming_target_deliver(s->ths_output, sm);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&tda->tda_delivery_mutex);
|
||||
|
||||
notify_reload("subscriptions");
|
||||
|
|
|
@ -36,6 +36,7 @@ static struct strtab container_audio_mime[] = {
|
|||
{ "audio/x-mpegts", MC_MPEGTS },
|
||||
{ "audio/mpeg", MC_MPEGPS },
|
||||
{ "application/octet-stream", MC_PASS },
|
||||
{ "application/octet-stream", MC_RAW },
|
||||
};
|
||||
|
||||
|
||||
|
@ -48,6 +49,7 @@ static struct strtab container_video_mime[] = {
|
|||
{ "video/x-mpegts", MC_MPEGTS },
|
||||
{ "video/mpeg", MC_MPEGPS },
|
||||
{ "application/octet-stream", MC_PASS },
|
||||
{ "application/octet-stream", MC_RAW },
|
||||
};
|
||||
|
||||
|
||||
|
@ -60,6 +62,7 @@ static struct strtab container_name[] = {
|
|||
{ "mpegts", MC_MPEGTS },
|
||||
{ "mpegps", MC_MPEGPS },
|
||||
{ "pass", MC_PASS },
|
||||
{ "raw", MC_RAW },
|
||||
};
|
||||
|
||||
|
||||
|
@ -72,6 +75,7 @@ static struct strtab container_audio_file_suffix[] = {
|
|||
{ "ts", MC_MPEGTS },
|
||||
{ "mpeg", MC_MPEGPS },
|
||||
{ "bin", MC_PASS },
|
||||
{ "bin", MC_RAW },
|
||||
};
|
||||
|
||||
|
||||
|
@ -84,6 +88,7 @@ static struct strtab container_video_file_suffix[] = {
|
|||
{ "ts", MC_MPEGTS },
|
||||
{ "mpeg", MC_MPEGPS },
|
||||
{ "bin", MC_PASS },
|
||||
{ "bin", MC_RAW },
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef enum {
|
|||
MC_MPEGTS = 2,
|
||||
MC_MPEGPS = 3,
|
||||
MC_PASS = 4,
|
||||
MC_RAW = 5,
|
||||
} muxer_container_type_t;
|
||||
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct pass_muxer {
|
|||
char *pm_filename;
|
||||
|
||||
/* TS muxing */
|
||||
uint8_t pm_injection;
|
||||
uint8_t *pm_pat;
|
||||
uint8_t *pm_pmt;
|
||||
uint16_t pm_pmt_version;
|
||||
|
@ -221,7 +222,9 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb)
|
|||
pass_muxer_t *pm = (pass_muxer_t*)m;
|
||||
int rem;
|
||||
|
||||
if(pm->pm_pat != NULL) {
|
||||
if(pm->pm_pat != NULL &&
|
||||
pm->pm_pmt != NULL &&
|
||||
pm->pm_injection) {
|
||||
// Inject pmt and pat into the stream
|
||||
rem = pm->pm_pc % TS_INJECTION_RATE;
|
||||
if(!rem) {
|
||||
|
@ -324,7 +327,7 @@ pass_muxer_create(muxer_container_type_t mc)
|
|||
{
|
||||
pass_muxer_t *pm;
|
||||
|
||||
if(mc != MC_PASS)
|
||||
if(mc != MC_PASS && mc != MC_RAW)
|
||||
return NULL;
|
||||
|
||||
pm = calloc(1, sizeof(pass_muxer_t));
|
||||
|
@ -338,7 +341,8 @@ pass_muxer_create(muxer_container_type_t mc)
|
|||
pm->m_close = pass_muxer_close;
|
||||
pm->m_destroy = pass_muxer_destroy;
|
||||
pm->pm_fd = -1;
|
||||
|
||||
pm->pm_injection = (mc == MC_PASS);
|
||||
|
||||
return (muxer_t *)pm;
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ page_static_file(http_connection_t *hc, const char *remain, void *opaque)
|
|||
*/
|
||||
static void
|
||||
http_stream_run(http_connection_t *hc, streaming_queue_t *sq,
|
||||
const char *name, muxer_container_type_t mc, int raw)
|
||||
const char *name, muxer_container_type_t mc)
|
||||
{
|
||||
streaming_message_t *sm;
|
||||
int run = 1;
|
||||
|
@ -167,11 +167,9 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq,
|
|||
int err = 0;
|
||||
socklen_t errlen = sizeof(err);
|
||||
|
||||
if (!raw) {
|
||||
mux = muxer_create(mc);
|
||||
if(muxer_open_stream(mux, hc->hc_fd))
|
||||
run = 0;
|
||||
}
|
||||
mux = muxer_create(mc);
|
||||
if(muxer_open_stream(mux, hc->hc_fd))
|
||||
run = 0;
|
||||
|
||||
/* reduce timeout on write() for streaming */
|
||||
tp.tv_sec = 5;
|
||||
|
@ -207,16 +205,6 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq,
|
|||
TAILQ_REMOVE(&sq->sq_queue, sm, sm_link);
|
||||
pthread_mutex_unlock(&sq->sq_mutex);
|
||||
|
||||
if (raw) {
|
||||
if (sm->sm_type == SMT_MPEGTS) {
|
||||
pktbuf_t *pb = sm->sm_data;
|
||||
if (tvh_write(hc->hc_fd, pb->pb_data, pb->pb_size))
|
||||
run = 0;
|
||||
}
|
||||
streaming_msg_free(sm);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(sm->sm_type) {
|
||||
case SMT_MPEGTS:
|
||||
case SMT_PACKET:
|
||||
|
@ -280,12 +268,10 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq,
|
|||
}
|
||||
}
|
||||
|
||||
if(started)
|
||||
muxer_close(mux);
|
||||
|
||||
if(mux != NULL){
|
||||
if(started)
|
||||
muxer_close(mux);
|
||||
muxer_destroy(mux);
|
||||
}
|
||||
muxer_destroy(mux);
|
||||
}
|
||||
|
||||
|
||||
|
@ -587,7 +573,7 @@ http_stream_service(http_connection_t *hc, service_t *service)
|
|||
else
|
||||
qsize = 1500000;
|
||||
|
||||
if(mc == MC_PASS) {
|
||||
if(mc == MC_PASS || mc == MC_RAW) {
|
||||
streaming_queue_init2(&sq, SMT_PACKET, qsize);
|
||||
gh = NULL;
|
||||
tsfix = NULL;
|
||||
|
@ -609,7 +595,7 @@ http_stream_service(http_connection_t *hc, service_t *service)
|
|||
name = strdupa(service->s_ch ?
|
||||
service->s_ch->ch_name : service->s_nicename);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
http_stream_run(hc, &sq, name, mc, 0);
|
||||
http_stream_run(hc, &sq, name, mc);
|
||||
pthread_mutex_lock(&global_lock);
|
||||
subscription_unsubscribe(s);
|
||||
}
|
||||
|
@ -644,7 +630,7 @@ http_stream_tdmi(http_connection_t *hc, th_dvb_mux_instance_t *tdmi)
|
|||
http_arg_get(&hc->hc_args, "User-Agent"));
|
||||
name = strdupa(tdmi->tdmi_identifier);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
http_stream_run(hc, &sq, name, MC_PASS, 1);
|
||||
http_stream_run(hc, &sq, name, MC_RAW);
|
||||
pthread_mutex_lock(&global_lock);
|
||||
subscription_unsubscribe(s);
|
||||
|
||||
|
@ -685,7 +671,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch)
|
|||
else
|
||||
qsize = 1500000;
|
||||
|
||||
if(mc == MC_PASS) {
|
||||
if(mc == MC_PASS || mc == MC_RAW) {
|
||||
streaming_queue_init2(&sq, SMT_PACKET, qsize);
|
||||
gh = NULL;
|
||||
tsfix = NULL;
|
||||
|
@ -707,7 +693,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch)
|
|||
if(s) {
|
||||
name = strdupa(ch->ch_name);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
http_stream_run(hc, &sq, name, mc, 0);
|
||||
http_stream_run(hc, &sq, name, mc);
|
||||
pthread_mutex_lock(&global_lock);
|
||||
subscription_unsubscribe(s);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue