]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
HTSP: Include video frame duration in streamingStart message
authorAndreas Öman <andreas@lonelycoder.com>
Wed, 24 Oct 2012 10:58:47 +0000 (12:58 +0200)
committerAndreas Öman <andreas@lonelycoder.com>
Thu, 25 Oct 2012 11:06:05 +0000 (13:06 +0200)
src/htsp.c
src/parser_h264.c
src/parser_h264.h
src/parsers.c
src/parsers.h
src/psi.c
src/service.c

index 4225b77427df987f9e804239edb750d270809f11..507f49735f675ed07ee7e3c9cf543e1a505b5b73 100644 (file)
@@ -1880,9 +1880,12 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss)
 
     if(ssc->ssc_type == SCT_MPEG2VIDEO || ssc->ssc_type == SCT_H264) {
       if(ssc->ssc_width)
-             htsmsg_add_u32(c, "width", ssc->ssc_width);
+        htsmsg_add_u32(c, "width", ssc->ssc_width);
       if(ssc->ssc_height)
-             htsmsg_add_u32(c, "height", ssc->ssc_height);
+        htsmsg_add_u32(c, "height", ssc->ssc_height);
+      if(ssc->ssc_frameduration)
+        htsmsg_add_u32(c, "duration", hs->hs_90khz ? ssc->ssc_frameduration :
+                       ts_rescale(ssc->ssc_frameduration, 1000000));
       if (ssc->ssc_aspect_num)
         htsmsg_add_u32(c, "aspect_num", ssc->ssc_aspect_num);
       if (ssc->ssc_aspect_den)
index 07bed03b44cc298d9ad12b436d098f5741dea2bf..67a823048e5111c7642dad3c953b3d960313393c 100644 (file)
@@ -352,7 +352,7 @@ h264_decode_pic_parameter_set(elementary_stream_t *st, bitstream_t *bs)
 
 int
 h264_decode_slice_header(elementary_stream_t *st, bitstream_t *bs, int *pkttype,
-                        int *duration, int *isfield)
+                        int *isfield)
 {
   h264_private_t *p;
   int slice_type, pps_id, sps_id;
@@ -402,22 +402,20 @@ h264_decode_slice_header(elementary_stream_t *st, bitstream_t *bs, int *pkttype,
 
   *isfield = field;
 
-  if(p->sps[sps_id].time_scale != 0) {
-    int d = timebase * p->sps[sps_id].units_in_tick / p->sps[sps_id].time_scale;
-    *duration = d;
-  } else {
-    *duration = 0;
-  }
+  int d = 0;
+  if(p->sps[sps_id].time_scale != 0)
+    d = timebase * p->sps[sps_id].units_in_tick / p->sps[sps_id].time_scale;
 
   if(p->sps[sps_id].cbpsize != 0)
     st->es_vbv_size = p->sps[sps_id].cbpsize;
 
   st->es_vbv_delay = -1;
 
-  if(p->sps[sps_id].width && p->sps[sps_id].height && !st->es_buf.sb_err)
-    parser_set_stream_vsize(st, p->sps[sps_id].width, 
-                           p->sps[sps_id].height *
-                           (2 - p->sps[sps_id].mbs_only_flag));
+  if(p->sps[sps_id].width && p->sps[sps_id].height && d && !st->es_buf.sb_err)
+    parser_set_stream_vparam(st, p->sps[sps_id].width,
+                             p->sps[sps_id].height *
+                             (2 - p->sps[sps_id].mbs_only_flag),
+                             d);
 
   if(p->sps[sps_id].aspect_num && p->sps[sps_id].aspect_den) {
 
index af92a56944499de1f862ee00a87c7d2b11b9866b..5e78b43670b13dcb6c1336aa98e8b5cca9b5ce30 100644 (file)
@@ -28,6 +28,6 @@ int h264_decode_seq_parameter_set(struct elementary_stream *st, bitstream_t *bs)
 int h264_decode_pic_parameter_set(struct elementary_stream *st, bitstream_t *bs);
 
 int h264_decode_slice_header(struct elementary_stream *st, bitstream_t *bs,
-                            int *pkttype, int *duration, int *isfield);
+                            int *pkttype, int *isfield);
 
 #endif /* PARSER_H264_H_ */
index 9b4768d98c501d924ecabef874280ec351f1a8c9..9adc8b20dcf8eb126dbd4c7b92b6805569e6e364 100644 (file)
@@ -904,16 +904,18 @@ parse_mpeg2video_pic_start(service_t *t, elementary_stream_t *st, int *frametype
  *
  */
 void
-parser_set_stream_vsize(elementary_stream_t *st, int width, int height)
+parser_set_stream_vparam(elementary_stream_t *st, int width, int height,
+                         int duration)
 {
   int need_save = 0;
 
-  if(st->es_width == 0 && st->es_height == 0) {
+  if(st->es_width == 0 && st->es_height == 0 && st->es_frame_duration == 0) {
     need_save = 1;
     st->es_meta_change = 0;
 
-  } else if(st->es_width != width || st->es_height != height) {
-    
+  } else if(st->es_width != width || st->es_height != height ||
+            st->es_frame_duration != duration) {
+
     st->es_meta_change++;
     if(st->es_meta_change == 2)
       need_save = 1;
@@ -925,6 +927,7 @@ parser_set_stream_vsize(elementary_stream_t *st, int width, int height)
   if(need_save) {
     st->es_width = width;
     st->es_height = height;
+    st->es_frame_duration = duration;
     service_request_save(st->es_service, 1);
   }
 }
@@ -969,7 +972,7 @@ parse_mpeg2video_seq_start(service_t *t, elementary_stream_t *st,
   st->es_aspect_num = mpeg2_aspect[aspect][0];
   st->es_aspect_den = mpeg2_aspect[aspect][1];
 
-  st->es_frame_duration = mpeg2video_framedurations[read_bits(bs, 4)];
+  int duration = mpeg2video_framedurations[read_bits(bs, 4)];
 
   v = read_bits(bs, 18) * 400;
   skip_bits(bs, 1);
@@ -977,7 +980,7 @@ parse_mpeg2video_seq_start(service_t *t, elementary_stream_t *st,
   v = read_bits(bs, 10) * 16 * 1024 / 8;
   st->es_vbv_size = v;
 
-  parser_set_stream_vsize(st, width, height);
+  parser_set_stream_vparam(st, width, height, duration);
   return 0;
 }
 
@@ -1157,8 +1160,7 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len,
 {
   const uint8_t *buf = st->es_buf.sb_data + sc_offset;
   uint32_t sc = st->es_startcode;
-  int64_t d;
-  int l2, pkttype, duration, isfield;
+  int l2, pkttype, isfield;
   bitstream_t bs;
   int ret = 0;
 
@@ -1169,12 +1171,6 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len,
       if(plen >= 0xffe9) st->es_incomplete =1;
       parse_pes_header(t, st, buf + 6, len - 6);
     }
-    if(st->es_prevdts != PTS_UNSET && st->es_curdts != PTS_UNSET) {
-      d = (st->es_curdts - st->es_prevdts) & 0x1ffffffffLL;
-
-      if(d < 90000)
-       st->es_frame_duration = d;
-    }
     st->es_prevdts = st->es_curdts;
     return 1;
   }
@@ -1211,23 +1207,23 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len,
 
     case 5: /* IDR+SLICE */
     case 1:
-      if(st->es_curpkt != NULL || st->es_frame_duration == 0)
-       break;
-
       l2 = len - 3 > 64 ? 64 : len - 3;
       void *f = h264_nal_deescape(&bs, buf + 3, l2);
       /* we just want the first stuff */
 
-      if(h264_decode_slice_header(st, &bs, &pkttype, &duration, &isfield)) {
+      if(h264_decode_slice_header(st, &bs, &pkttype, &isfield)) {
        free(f);
        return 1;
       }
       free(f);
 
+      if(st->es_curpkt != NULL || st->es_frame_duration == 0)
+       break;
+
       st->es_curpkt = pkt_alloc(NULL, 0, st->es_curpts, st->es_curdts);
       st->es_curpkt->pkt_frametype = pkttype;
       st->es_curpkt->pkt_field = isfield;
-      st->es_curpkt->pkt_duration = duration ?: st->es_frame_duration;
+      st->es_curpkt->pkt_duration = st->es_frame_duration;
       st->es_curpkt->pkt_commercial = t->s_tt_commercial_advice;
       break;
 
index 947b6fd6dadc90f1543a0eaa2b624cce309e87c7..826daaed3be7c0109e87b1b89596e6d3bfe78822 100644 (file)
@@ -31,7 +31,8 @@ void parse_mpeg_ps(struct service *t, struct elementary_stream *st,
 void parser_enqueue_packet(struct service *t, struct elementary_stream *st,
                           th_pkt_t *pkt);
 
-void parser_set_stream_vsize(struct elementary_stream *st, int width, int height);
+void parser_set_stream_vparam(struct elementary_stream *st, int width, int height,
+                              int duration);
 
 extern const unsigned int mpeg2video_framedurations[16];
 
index 9763a50a0318e7a6d384273c43a0aab5eaa78af1..ff298fad16536ab0d147a602205c57bb840870dc 100644 (file)
--- a/src/psi.c
+++ b/src/psi.c
@@ -998,6 +998,8 @@ psi_save_service_settings(htsmsg_t *m, service_t *t)
        htsmsg_add_u32(sub, "width", st->es_width);
        htsmsg_add_u32(sub, "height", st->es_height);
       }
+      if(st->es_frame_duration)
+        htsmsg_add_u32(sub, "duration", st->es_frame_duration);
     }
     
     htsmsg_add_msg(m, "stream", sub);
@@ -1141,6 +1143,9 @@ psi_load_service_settings(htsmsg_t *m, service_t *t)
 
       if(!htsmsg_get_u32(c, "height", &u32))
        st->es_height = u32;
+
+      if(!htsmsg_get_u32(c, "duration", &u32))
+        st->es_frame_duration = u32;
     }
 
   }
index 1f8fe5655fee6996fbf05afe22a522c5d6041057..07805d3e57a0be6588a1d8aba9c82f1c45fedd0c 100644 (file)
@@ -902,6 +902,7 @@ service_build_stream_start(service_t *t)
     ssc->ssc_pid = st->es_pid;
     ssc->ssc_width = st->es_width;
     ssc->ssc_height = st->es_height;
+    ssc->ssc_frameduration = st->es_frame_duration;
   }
 
   t->s_setsourceinfo(t, &ss->ss_si);