]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
mpeg2audio: handle the mpeg layer number changes
authorJaroslav Kysela <perex@perex.cz>
Mon, 3 Apr 2017 19:10:05 +0000 (21:10 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 3 Apr 2017 19:10:05 +0000 (21:10 +0200)
src/api/api_service.c
src/dvr/dvr_rec.c
src/htsp_server.c
src/input/mpegts/dvb_psi.c
src/parsers/parsers.c
src/service.c
src/service.h
src/streaming.h

index a4d7d2cbdc01a363dbcc3d1ef91ac486357013df..9ad85512658c7de03c14c92efb9b544440c54d7f 100644 (file)
@@ -83,6 +83,8 @@ api_service_streams_get_one ( elementary_stream_t *es, int use_filter )
     htsmsg_add_u32(e, "ancillary_id",   es->es_ancillary_id);
   } else if (SCT_ISAUDIO(es->es_type)) {
     htsmsg_add_u32(e, "audio_type",     es->es_audio_type);
+    if (es->es_audio_version)
+      htsmsg_add_u32(e, "audio_version", es->es_audio_version);
   } else if (SCT_ISVIDEO(es->es_type)) {
     htsmsg_add_u32(e, "width",          es->es_width);
     htsmsg_add_u32(e, "height",         es->es_height);
index 24d70c34efc140e28669174f22362a620ed997ae..3dc174b83637cd89b4ed46a20c62f6de4709fbda 100644 (file)
@@ -1009,6 +1009,8 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
 
     if(SCT_ISAUDIO(ssc->ssc_type)) {
       htsmsg_add_u32(e, "audio_type", ssc->ssc_audio_type);
+      if(ssc->ssc_audio_version)
+        htsmsg_add_u32(e, "audio_version", ssc->ssc_audio_version);
       if(ssc->ssc_sri)
        snprintf(sr, sizeof(sr), "%d", sri_to_rate(ssc->ssc_sri));
       else
index ea786f02f154c0656978c60d9c782a2274f960e7..7f66dd8f526ff69ed2b762b73e4357ed9cbe8e13 100644 (file)
@@ -4010,6 +4010,8 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss)
     if (SCT_ISAUDIO(ssc->ssc_type))
     {
       htsmsg_add_u32(c, "audio_type", ssc->ssc_audio_type);
+      if (ssc->ssc_audio_version)
+        htsmsg_add_u32(c, "audio_version", ssc->ssc_audio_version);
       if (ssc->ssc_channels)
         htsmsg_add_u32(c, "channels", ssc->ssc_channels);
       if (ssc->ssc_sri)
index bd833ad4937a48939f2f2e3e7a813f3ab1da513d..514ab31dea08cb616326afaaaf2f71ffac8a92ec 100644 (file)
@@ -1004,19 +1004,21 @@ dvb_cat_callback
 /* PMT update reason flags */
 #define PMT_UPDATE_PCR                (1<<0)
 #define PMT_UPDATE_NEW_STREAM         (1<<1)
-#define PMT_UPDATE_LANGUAGE           (1<<2)
-#define PMT_UPDATE_AUDIO_TYPE         (1<<3)
-#define PMT_UPDATE_FRAME_DURATION     (1<<4)
-#define PMT_UPDATE_COMPOSITION_ID     (1<<5)
-#define PMT_UPDATE_ANCILLARY_ID       (1<<6)
-#define PMT_UPDATE_STREAM_DELETED     (1<<7)
-#define PMT_UPDATE_NEW_CA_STREAM      (1<<8)
-#define PMT_UPDATE_NEW_CAID           (1<<9)
-#define PMT_UPDATE_CA_PROVIDER_CHANGE (1<<10)
-#define PMT_UPDATE_PARENT_PID         (1<<11)
-#define PMT_UPDATE_CAID_DELETED       (1<<12)
-#define PMT_UPDATE_CAID_PID           (1<<13)
-#define PMT_REORDERED                 (1<<14)
+#define PMT_UPDATE_STREAM_CHANGE      (1<<2)
+#define PMT_UPDATE_STREAM_DELETED     (1<<3)
+#define PMT_UPDATE_LANGUAGE           (1<<4)
+#define PMT_UPDATE_AUDIO_TYPE         (1<<5)
+#define PMT_UPDATE_AUDIO_VERSION      (1<<6)
+#define PMT_UPDATE_FRAME_DURATION     (1<<7)
+#define PMT_UPDATE_COMPOSITION_ID     (1<<8)
+#define PMT_UPDATE_ANCILLARY_ID       (1<<9)
+#define PMT_UPDATE_NEW_CA_STREAM      (1<<10)
+#define PMT_UPDATE_NEW_CAID           (1<<11)
+#define PMT_UPDATE_CA_PROVIDER_CHANGE (1<<12)
+#define PMT_UPDATE_PARENT_PID         (1<<13)
+#define PMT_UPDATE_CAID_DELETED       (1<<14)
+#define PMT_UPDATE_CAID_PID           (1<<15)
+#define PMT_REORDERED                 (1<<16)
 
 int
 dvb_pmt_callback
@@ -2228,7 +2230,7 @@ psi_parse_pmt
   int tt_position;
   int video_stream;
   const char *lang;
-  uint8_t audio_type;
+  uint8_t audio_type, audio_version;
   mpegts_mux_t *mux = mt->mt_mux;
   caid_t *c, *cn;
 
@@ -2293,6 +2295,7 @@ psi_parse_pmt
     tt_position = 1000;
     lang = NULL;
     audio_type = 0;
+    audio_version = 0;
     video_stream = 0;
 
     switch(estype) {
@@ -2305,6 +2308,7 @@ psi_parse_pmt
     case 0x03:
     case 0x04:
       hts_stream_type = SCT_MPEG2AUDIO;
+      audio_version = 2; /* Assume Layer 2 */
       break;
 
     case 0x06:
@@ -2415,7 +2419,11 @@ psi_parse_pmt
         st = service_stream_create((service_t*)t, pid, hts_stream_type);
       }
 
-      st->es_type = hts_stream_type;
+      if (st->es_type != hts_stream_type) {
+        update |= PMT_UPDATE_STREAM_CHANGE;
+        st->es_type = hts_stream_type;
+        st->es_audio_version = audio_version;
+      }
 
       st->es_delete_me = 0;
 
@@ -2441,6 +2449,15 @@ psi_parse_pmt
       if(st->es_audio_type != audio_type) {
         update |= PMT_UPDATE_AUDIO_TYPE;
         st->es_audio_type = audio_type;
+        st->es_audio_version = audio_version;
+      }
+
+      /* FIXME: it might make sense that PMT info has greater priority */
+      /*        but we use this field only for MPEG1/2/3 audio which */
+      /*        is detected in the parser code */
+      if(audio_version && !st->es_audio_version) {
+        update |= PMT_UPDATE_AUDIO_VERSION;
+        st->es_audio_version = audio_version;
       }
 
       if(composition_id != -1 && st->es_composition_id != composition_id) {
@@ -2469,7 +2486,6 @@ psi_parse_pmt
       }
     }
 
-
     if(st->es_delete_me) {
       service_stream_destroy((service_t*)t, st);
       update |= PMT_UPDATE_STREAM_DELETED;
@@ -2481,16 +2497,19 @@ psi_parse_pmt
 
   if(update) {
     tvhdebug(mt->mt_subsys, "%s: Service \"%s\" PMT (version %d) updated"
-     "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+     "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
      mt->mt_name,
      service_nicename((service_t*)t), version,
      update&PMT_UPDATE_PCR               ? ", PCR PID changed":"",
      update&PMT_UPDATE_NEW_STREAM        ? ", New elementary stream":"",
+     update&PMT_UPDATE_STREAM_CHANGE     ? ", Changed elementary stream":"",
+     update&PMT_UPDATE_STREAM_DELETED    ? ", Stream deleted":"",
      update&PMT_UPDATE_LANGUAGE          ? ", Language changed":"",
+     update&PMT_UPDATE_AUDIO_TYPE        ? ", Audio type changed":"",
+     update&PMT_UPDATE_AUDIO_VERSION     ? ", Audio version changed":"",
      update&PMT_UPDATE_FRAME_DURATION    ? ", Frame duration changed":"",
      update&PMT_UPDATE_COMPOSITION_ID    ? ", Composition ID changed":"",
      update&PMT_UPDATE_ANCILLARY_ID      ? ", Ancillary ID changed":"",
-     update&PMT_UPDATE_STREAM_DELETED    ? ", Stream deleted":"",
      update&PMT_UPDATE_NEW_CA_STREAM     ? ", New CA stream":"",
      update&PMT_UPDATE_NEW_CAID          ? ", New CAID":"",
      update&PMT_UPDATE_CA_PROVIDER_CHANGE? ", CA provider changed":"",
@@ -2515,6 +2534,11 @@ psi_parse_pmt
   if (service_has_audio_or_video((service_t *)t))
     dvb_service_autoenable(t, "PAT and PMT");
 
+  /* FIXME: Move pending_restart handling to another place? */
+  if (atomic_set(&t->s_pending_restart, 0) && !ret)
+    tvhdebug(mt->mt_subsys, "%s: Service \"%s\" forced restart",
+             mt->mt_name, service_nicename((service_t*)t));
+
   *_update = update;
   return ret;
 }
index e567391e19ddda953a5c7ff074fc9ab5dfc89a1b..736b604c956c0eec7b72edf65ba8561e6ca26c4a 100644 (file)
@@ -688,6 +688,11 @@ parse_mpa123(service_t *t, elementary_stream_t *st)
     default: fsize = 0;
     }
 
+    if (fsize && st->es_audio_version != layer) {
+      st->es_audio_version = layer;
+      atomic_set(&t->s_pending_restart, 1);
+    }
+
     duration = 90000 * 1152 / sr;
     channels = ((h >> 6) & 3) == 3 ? 1 : 2;
     dts = st->es_curdts;
index 7a760b8c511c170da9576535f595804f47d2c87c..6d1fd8d6cac6f690261e030dcda3e601bec2a35c 100644 (file)
@@ -1448,7 +1448,6 @@ refresh:
   descrambler_service_start(t);
 }
 
-
 /**
  * Generate a message containing info about all components
  */
@@ -1478,6 +1477,7 @@ service_build_stream_start(service_t *t)
 
     memcpy(ssc->ssc_lang, st->es_lang, 4);
     ssc->ssc_audio_type = st->es_audio_type;
+    ssc->ssc_audio_version = st->es_audio_version;
     ssc->ssc_composition_id = st->es_composition_id;
     ssc->ssc_ancillary_id = st->es_ancillary_id;
     ssc->ssc_pid = st->es_pid;
@@ -1977,8 +1977,11 @@ void service_save ( service_t *t, htsmsg_t *m )
     if(st->es_lang[0])
       htsmsg_add_str(sub, "language", st->es_lang);
 
-    if (SCT_ISAUDIO(st->es_type))
+    if (SCT_ISAUDIO(st->es_type)) {
       htsmsg_add_u32(sub, "audio_type", st->es_audio_type);
+      if (st->es_audio_version)
+        htsmsg_add_u32(sub, "audio_version", st->es_audio_version);
+    }
 
     if(st->es_type == SCT_CA) {
       caid_t *c;
@@ -2177,6 +2180,8 @@ void service_load ( service_t *t, htsmsg_t *c )
       if (SCT_ISAUDIO(type)) {
         if(!htsmsg_get_u32(c, "audio_type", &u32))
           st->es_audio_type = u32;
+        if(!htsmsg_get_u32(c, "audio_version", &u32))
+          st->es_audio_version = u32;
       }
 
       if(!htsmsg_get_u32(c, "position", &u32))
index 9a5c13fe792e3b75a7e9a488452ed947b070f95c..daba9b43dbf9a96f7f7badc16e3b09035300139b 100644 (file)
@@ -70,6 +70,7 @@ typedef struct elementary_stream {
 
   char es_lang[4];           /* ISO 639 2B 3-letter language code */
   uint8_t es_audio_type;     /* Audio type */
+  uint8_t es_audio_version;  /* Audio version/layer */
 
   uint16_t es_composition_id;
   uint16_t es_ancillary_id;
@@ -441,6 +442,7 @@ typedef struct service {
    */
   int s_streaming_live;
   int s_running;
+  int s_pending_restart;
 
   // Live status
 #define TSS_LIVE             0x01
index b35647d50ebedd24f023afe037c65e2aca69194e..832055c5d477620e12c75cace341044416995245 100644 (file)
@@ -29,6 +29,7 @@ typedef struct streaming_start_component {
   int ssc_type;
   char ssc_lang[4];
   uint8_t ssc_audio_type;
+  uint8_t ssc_audio_version;
   uint16_t ssc_composition_id;
   uint16_t ssc_ancillary_id;
   uint16_t ssc_pid;