]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Fix H264 packet merging, fixes #2480
authorJaroslav Kysela <perex@perex.cz>
Sun, 16 Nov 2014 15:08:09 +0000 (16:08 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sun, 16 Nov 2014 15:08:09 +0000 (16:08 +0100)
src/htsp_server.c
src/parsers/parsers.c

index ea84572c702c1203ab57b1fbef1a451bb67bd534..2f3f6e163a8b8d0c2b9fa2697ad2e91fe1b393aa 100644 (file)
@@ -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)
index 1a590f9876a55e89ec27d1aa1d045296e15786c9..a637941a08180674090bb4fdc07e41b8986d336c 100644 (file)
@@ -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;