Fix H264 packet merging, fixes #2480
This commit is contained in:
parent
fcd16fa0d8
commit
e065cf6823
2 changed files with 20 additions and 46 deletions
|
@ -198,14 +198,12 @@ typedef struct htsp_subscription {
|
|||
|
||||
int hs_queue_depth;
|
||||
|
||||
#define NUM_FILTERED_STREAMS (32*16)
|
||||
#define NUM_FILTERED_STREAMS (64*8)
|
||||
|
||||
uint32_t hs_filtered_streams[16]; // one bit per stream
|
||||
uint64_t hs_filtered_streams[8]; // one bit per stream
|
||||
|
||||
int hs_first;
|
||||
|
||||
int hs_merge_meta_compomentidx;
|
||||
|
||||
} htsp_subscription_t;
|
||||
|
||||
|
||||
|
@ -229,7 +227,7 @@ static void
|
|||
htsp_disable_stream(htsp_subscription_t *hs, unsigned int id)
|
||||
{
|
||||
if(id < NUM_FILTERED_STREAMS)
|
||||
hs->hs_filtered_streams[id / 32] |= 1 << (id & 31);
|
||||
hs->hs_filtered_streams[id / 64] |= 1 << (id & 63);
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,7 +235,7 @@ static void
|
|||
htsp_enable_stream(htsp_subscription_t *hs, unsigned int id)
|
||||
{
|
||||
if(id < NUM_FILTERED_STREAMS)
|
||||
hs->hs_filtered_streams[id / 32] &= ~(1 << (id & 31));
|
||||
hs->hs_filtered_streams[id / 64] &= ~(1 << (id & 63));
|
||||
}
|
||||
|
||||
|
||||
|
@ -245,11 +243,10 @@ static inline int
|
|||
htsp_is_stream_enabled(htsp_subscription_t *hs, unsigned int id)
|
||||
{
|
||||
if(id < NUM_FILTERED_STREAMS)
|
||||
return !(hs->hs_filtered_streams[id / 32] & (1 << (id & 31)));
|
||||
return !(hs->hs_filtered_streams[id / 64] & (1 << (id & 63)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -2908,21 +2905,6 @@ const static char frametypearray[PKT_NTYPES] = {
|
|||
[PKT_B_FRAME] = 'B',
|
||||
};
|
||||
|
||||
static th_pkt_t *merge_pkt(th_pkt_t *pkt, size_t payloadlen)
|
||||
{
|
||||
th_pkt_t *n = pkt_alloc(NULL, 0, 0, 0);
|
||||
*n = *pkt;
|
||||
n->pkt_refcount = 1;
|
||||
n->pkt_meta = NULL;
|
||||
n->pkt_payload = pktbuf_alloc(NULL, payloadlen);
|
||||
memcpy(pktbuf_ptr(n->pkt_payload),
|
||||
pktbuf_ptr(pkt->pkt_meta), pktbuf_len(pkt->pkt_meta));
|
||||
memcpy(pktbuf_ptr(n->pkt_payload) + pktbuf_len(pkt->pkt_meta),
|
||||
pktbuf_ptr(pkt->pkt_payload), pktbuf_len(pkt->pkt_payload));
|
||||
pkt_ref_dec(pkt);
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a htsmsg from a th_pkt and enqueue it on our HTSP service
|
||||
*/
|
||||
|
@ -2974,19 +2956,11 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt)
|
|||
uint32_t dur = hs->hs_90khz ? pkt->pkt_duration : ts_rescale(pkt->pkt_duration, 1000000);
|
||||
htsmsg_add_u32(m, "duration", dur);
|
||||
|
||||
if (pkt->pkt_meta &&
|
||||
hs->hs_merge_meta_compomentidx == pkt->pkt_componentindex) {
|
||||
payloadlen = pktbuf_len(pkt->pkt_meta) + pktbuf_len(pkt->pkt_payload);
|
||||
pkt = merge_pkt(pkt, payloadlen);
|
||||
/* do it only once */
|
||||
hs->hs_merge_meta_compomentidx = -1;
|
||||
} else {
|
||||
payloadlen = pktbuf_len(pkt->pkt_payload);
|
||||
}
|
||||
/**
|
||||
* Since we will serialize directly we use 'binptr' which is a binary
|
||||
* object that just points to data, thus avoiding a copy.
|
||||
*/
|
||||
payloadlen = pktbuf_len(pkt->pkt_payload);
|
||||
htsmsg_add_binptr(m, "payload", pktbuf_ptr(pkt->pkt_payload), payloadlen);
|
||||
htsp_send(htsp, m, pkt->pkt_payload, &hs->hs_q, payloadlen);
|
||||
atomic_add(&hs->hs_s->ths_bytes_out, payloadlen);
|
||||
|
@ -3059,8 +3033,6 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss)
|
|||
|
||||
tvhdebug("htsp", "%s - subscription start", hs->hs_htsp->htsp_logname);
|
||||
|
||||
hs->hs_merge_meta_compomentidx = -1;
|
||||
|
||||
for(i = 0; i < ss->ss_num_components; i++) {
|
||||
const streaming_start_component_t *ssc = &ss->ss_components[i];
|
||||
if (SCT_ISVIDEO(ssc->ssc_type)) {
|
||||
|
@ -3121,13 +3093,6 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss)
|
|||
pktbuf_len(ssc->ssc_gh));
|
||||
|
||||
htsmsg_add_msg(streams, NULL, c);
|
||||
|
||||
if (ssc->ssc_type == SCT_H264 && hs->hs_htsp->htsp_version < 17) {
|
||||
if (hs->hs_merge_meta_compomentidx < 0)
|
||||
hs->hs_merge_meta_compomentidx = ssc->ssc_index;
|
||||
else
|
||||
tvherror("htsp", "multiple H264 video streams?");
|
||||
}
|
||||
}
|
||||
|
||||
htsmsg_add_msg(m, "streams", streams);
|
||||
|
@ -3147,7 +3112,7 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss)
|
|||
}
|
||||
|
||||
/**
|
||||
* Send a 'subscriptionStart' stop
|
||||
* Send a 'subscriptionStop' stop
|
||||
*/
|
||||
static void
|
||||
htsp_subscription_stop(htsp_subscription_t *hs, const char *err)
|
||||
|
|
|
@ -1230,18 +1230,27 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len,
|
|||
if (st->es_incomplete)
|
||||
return 4;
|
||||
th_pkt_t *pkt = st->es_curpkt;
|
||||
size_t metalen = 0;
|
||||
|
||||
if(pkt != NULL) {
|
||||
if(st->es_global_data) {
|
||||
pkt->pkt_meta = pktbuf_make(st->es_global_data,
|
||||
st->es_global_data_len);
|
||||
metalen = st->es_global_data_len);
|
||||
st->es_global_data = NULL;
|
||||
st->es_global_data_len = 0;
|
||||
}
|
||||
|
||||
pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data,
|
||||
st->es_buf.sb_ptr - 4);
|
||||
sbuf_steal_data(&st->es_buf);
|
||||
if (metalen) {
|
||||
pkt->pkt_payload = pktbuf_alloc(NULL, metalen + st->es_buf.sb_ptr - 4);
|
||||
memcpy(pktbuf_ptr(pkt->pkt_payload), pktbuf_ptr(pkt->pkt_meta), metalen);
|
||||
memcpy(pktbuf_ptr(pkt->pkt_payload) + metalen, st->es_buf.sb_data, st->es_buf.sb_ptr - 4);
|
||||
sbuf_reset(&st->es_buf, 16000);
|
||||
} else {
|
||||
pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data,
|
||||
st->es_buf.sb_ptr - 4);
|
||||
sbuf_steal_data(&st->es_buf);
|
||||
}
|
||||
|
||||
parser_deliver(t, st, pkt, st->es_buf.sb_err);
|
||||
|
||||
st->es_curpkt = NULL;
|
||||
|
|
Loading…
Add table
Reference in a new issue