]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
DVR: Add track info to the DVR entry (associated to filename)
authorJaroslav Kysela <perex@perex.cz>
Thu, 1 Oct 2015 19:14:58 +0000 (21:14 +0200)
committerJaroslav Kysela <perex@perex.cz>
Thu, 1 Oct 2015 19:14:58 +0000 (21:14 +0200)
src/dvr/dvr_rec.c
src/htsmsg.c
src/htsmsg.h
src/muxer.h
src/muxer/muxer_libav.c
src/muxer/muxer_mkv.c
src/muxer/muxer_pass.c
src/streaming.h
src/webui/webui.c

index f0b885469fdbd959922ca7341f79286b22615d52..8fa3a4f629c18ed53ff71f1365dd93b65634ca24 100644 (file)
@@ -796,11 +796,15 @@ static int
 dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
 {
   const source_info_t *si = &ss->ss_si;
+  streaming_start_t *ss_copy;
   const streaming_start_component_t *ssc;
-  int i;
+  char res[11], asp[6], sr[6], ch[7];
   dvr_config_t *cfg = de->de_config;
   profile_chain_t *prch = de->de_chain;
+  htsmsg_t *info, *e;
+  htsmsg_field_t *f;
   muxer_t *muxer;
+  int i;
 
   if (!cfg) {
     dvr_rec_fatal_error(de, "Unable to determine config profile");
@@ -835,15 +839,17 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
     return -1;
   }
 
-  if(muxer_init(muxer, ss, lang_str_get(de->de_title, NULL))) {
+  ss_copy = streaming_start_copy(ss);
+
+  if(muxer_init(muxer, ss_copy, lang_str_get(de->de_title, NULL))) {
     dvr_rec_fatal_error(de, "Unable to init file");
-    return -1;
+    goto _err;
   }
 
   if(cfg->dvr_tag_files) {
     if(muxer_write_meta(muxer, de->de_bcast, de->de_comment)) {
       dvr_rec_fatal_error(de, "Unable to write meta data");
-      return -1;
+      goto _err;
     }
   }
 
@@ -869,15 +875,20 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
         "sample rate",
         "channels");
 
-  for(i = 0; i < ss->ss_num_components; i++) {
-    ssc = &ss->ss_components[i];
+  info = htsmsg_create_list();
+  for(i = 0; i < ss_copy->ss_num_components; i++) {
+    ssc = &ss_copy->ss_components[i];
 
-    char res[11];
-    char asp[6];
-    char sr[6];
-    char ch[7];
+    if(ssc->ssc_muxer_disabled)
+      continue;
+
+    e = htsmsg_create_map();
+    htsmsg_add_str(e, "type", streaming_component_type2txt(ssc->ssc_type));
+    if (ssc->ssc_lang && ssc->ssc_lang[0])
+       htsmsg_add_str(e, "language", ssc->ssc_lang);
 
     if(SCT_ISAUDIO(ssc->ssc_type)) {
+      htsmsg_add_u32(e, "audio_type", ssc->ssc_audio_type);
       if(ssc->ssc_sri)
        snprintf(sr, sizeof(sr), "%d", sri_to_rate(ssc->ssc_sri));
       else
@@ -890,8 +901,7 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
       else
        snprintf(ch, sizeof(ch), "%d", ssc->ssc_channels);
     } else {
-      sr[0] = 0;
-      ch[0] = 0;
+      sr[0] = ch[0] = 0;
     }
 
     if(SCT_ISVIDEO(ssc->ssc_type)) {
@@ -900,18 +910,25 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
                 ssc->ssc_width, ssc->ssc_height);
       else
        strcpy(res, "?");
-    } else {
-      res[0] = 0;
-    }
 
-    if(SCT_ISVIDEO(ssc->ssc_type)) {
       if(ssc->ssc_aspect_num &&  ssc->ssc_aspect_den)
        snprintf(asp, sizeof(asp), "%d:%d",
                 ssc->ssc_aspect_num, ssc->ssc_aspect_den);
       else
        strcpy(asp, "?");
+
+      htsmsg_add_u32(e, "width",      ssc->ssc_width);
+      htsmsg_add_u32(e, "height",     ssc->ssc_height);
+      htsmsg_add_u32(e, "duration",   ssc->ssc_frameduration);
+      htsmsg_add_u32(e, "aspect_num", ssc->ssc_aspect_num);
+      htsmsg_add_u32(e, "aspect_den", ssc->ssc_aspect_den);
     } else {
-      asp[0] = 0;
+      res[0] = asp[0] = 0;
+    }
+
+    if (SCT_ISSUBTITLE(ssc->ssc_type)) {
+      htsmsg_add_u32(e, "composition_id", ssc->ssc_composition_id);
+      htsmsg_add_u32(e, "ancillary_id",   ssc->ssc_ancillary_id);
     }
 
     tvhlog(LOG_INFO, "dvr",
@@ -924,9 +941,23 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
           sr,
           ch,
           ssc->ssc_disabled ? "<disabled, no valid input>" : "");
+    htsmsg_add_msg(info, NULL, e);
   }
 
+  streaming_start_unref(ss_copy);
+
+  /* update the info field for a filename */
+  if ((f = htsmsg_field_last(de->de_files)) != NULL &&
+      (e = htsmsg_field_get_map(f)) != NULL) {
+    htsmsg_set_msg(e, "info", info);
+  } else {
+    htsmsg_destroy(info);
+  }
   return 0;
+
+_err:
+  streaming_start_unref(ss_copy);
+  return -1;
 }
 
 
index 08866cfa1d325a7ecc0a811e6c0d63afb63396f5..792f99ab8f7c4a9504eae0701a222211a411e7c1 100644 (file)
@@ -34,11 +34,9 @@ htsmsg_field_get_msg ( htsmsg_field_t *f, int islist );
 /**
  *
  */
-void
-htsmsg_field_destroy(htsmsg_t *msg, htsmsg_field_t *f)
+static void
+htsmsg_field_data_destroy(htsmsg_t *msg, htsmsg_field_t *f)
 {
-  TAILQ_REMOVE(&msg->hm_fields, f, hmf_link);
-
   switch(f->hmf_type) {
   case HMF_MAP:
   case HMF_LIST:
@@ -57,6 +55,19 @@ htsmsg_field_destroy(htsmsg_t *msg, htsmsg_field_t *f)
   default:
     break;
   }
+  f->hmf_flags &= ~HMF_ALLOCED;
+}
+
+/**
+ *
+ */
+void
+htsmsg_field_destroy(htsmsg_t *msg, htsmsg_field_t *f)
+{
+  TAILQ_REMOVE(&msg->hm_fields, f, hmf_link);
+
+  htsmsg_field_data_destroy(msg, f);
+
   if(f->hmf_flags & HMF_NAME_ALLOCED)
     free((void *)f->hmf_name);
   free(f);
@@ -340,14 +351,9 @@ htsmsg_add_binptr(htsmsg_t *msg, const char *name, const void *bin, size_t len)
 /*
  *
  */
-htsmsg_t *
-htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub)
+static htsmsg_t *
+htsmsg_field_set_msg(htsmsg_field_t *f, htsmsg_t *sub)
 {
-  htsmsg_field_t *f;
-
-  f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP,
-                      HMF_NAME_ALLOCED);
-
   assert(sub->hm_data == NULL);
   f->hmf_msg.hm_islist = sub->hm_islist;
   TAILQ_MOVE(&f->hmf_msg.hm_fields, &sub->hm_fields, hmf_link);
@@ -359,6 +365,32 @@ htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub)
   return NULL;
 }
 
+/*
+ *
+ */
+htsmsg_t *
+htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub)
+{
+  htsmsg_field_t *f;
+
+  f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP,
+                      HMF_NAME_ALLOCED);
+  return htsmsg_field_set_msg(f, sub);
+}
+
+/*
+ *
+ */
+htsmsg_t *
+htsmsg_set_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub)
+{
+  htsmsg_field_t *f = htsmsg_field_find(msg, name);
+  if (!f)
+    return htsmsg_add_msg(msg, name, sub);
+  htsmsg_field_data_destroy(msg, f);
+  return htsmsg_field_set_msg(f, sub);
+}
+
 
 
 /*
index 56cdb21d3a0573ac7282c1f7d860a1b025f6565d..334cfc6010e47a2fbd39d987ee3d70dc19199de1 100644 (file)
@@ -173,6 +173,11 @@ int  htsmsg_field_set_str(htsmsg_field_t *f, const char *str);
  */
 htsmsg_t *htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub);
 
+/**
+ * Add/update an field where source is a list or map message.
+ */
+htsmsg_t *htsmsg_set_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub);
+
 /**
  * Add an field where source is a double
  */
index 382432294dcd2dc28b134fd5b192137844c396c5..bb516959072ca485a7462071e84522d983e58bb0 100644 (file)
@@ -75,7 +75,7 @@ typedef struct muxer {
   const char* (*m_mime)       (struct muxer *,                          /* Figure out the mimetype */
                               const struct streaming_start *);
   int         (*m_init)       (struct muxer *,                          /* Init The muxer with streams */
-                              const struct streaming_start *,
+                              struct streaming_start *,
                               const char *);
   int         (*m_reconfigure)(struct muxer *,                          /* Reconfigure the muxer on */
                               const struct streaming_start *);           /* stream changes */
@@ -113,7 +113,7 @@ static inline int muxer_open_file (muxer_t *m, const char *filename)
 static inline int muxer_open_stream (muxer_t *m, int fd)
   { if(m && fd >= 0) return m->m_open_stream(m, fd); return -1; }
 
-static inline int muxer_init (muxer_t *m, const struct streaming_start *ss, const char *name)
+static inline int muxer_init (muxer_t *m, struct streaming_start *ss, const char *name)
   { if(m && ss) return m->m_init(m, ss, name); return -1; }
 
 static inline int muxer_reconfigure (muxer_t *m, const struct streaming_start *ss)
index f53d396e00393a3b3de21437277b8083350514c6..29b27e84cbe9b53dea6403d6fb2456cbd07e1667 100644 (file)
@@ -259,10 +259,10 @@ lav_muxer_mime(muxer_t* m, const struct streaming_start *ss)
  * Init the muxer with streams
  */
 static int
-lav_muxer_init(muxer_t* m, const struct streaming_start *ss, const char *name)
+lav_muxer_init(muxer_t* m, struct streaming_start *ss, const char *name)
 {
   int i;
-  const streaming_start_component_t *ssc;
+  streaming_start_component_t *ssc;
   AVFormatContext *oc;
   lav_muxer_t *lm = (lav_muxer_t*)m;
   char app[128];
@@ -292,12 +292,14 @@ lav_muxer_init(muxer_t* m, const struct streaming_start *ss, const char *name)
       tvhlog(LOG_WARNING, "libav",  "%s is not supported in %s", 
             streaming_component_type2txt(ssc->ssc_type), 
             muxer_container_type2txt(lm->m_config.m_type));
+      ssc->ssc_muxer_disabled = 1;
       continue;
     }
 
     if(lav_muxer_add_stream(lm, ssc)) {
       tvhlog(LOG_ERR, "libav",  "Failed to add %s stream", 
             streaming_component_type2txt(ssc->ssc_type));
+      ssc->ssc_muxer_disabled = 1;
       continue;
     }
   }
index dc65db6f74dcb23d8bd0daffd5e2b95ed54d50c9..5d11f15c35c63a6df31c3b597af6d3437b7ff7fd 100644 (file)
@@ -222,9 +222,9 @@ mk_build_segment_info(mk_muxer_t *mk)
  *
  */
 static htsbuf_queue_t *
-mk_build_tracks(mk_muxer_t *mk, const streaming_start_t *ss)
+mk_build_tracks(mk_muxer_t *mk, streaming_start_t *ss)
 {
-  const streaming_start_component_t *ssc;
+  streaming_start_component_t *ssc;
   const char *codec_id;
   int i, tracktype;
   htsbuf_queue_t *q = htsbuf_queue_alloc(0), *t;
@@ -323,6 +323,7 @@ mk_build_tracks(mk_muxer_t *mk, const streaming_start_t *ss)
       break;
 
     default:
+      ssc->ssc_muxer_disabled = 1;
       tr->disabled = 1;
       continue;
     }
@@ -866,7 +867,7 @@ mk_write_metaseek(mk_muxer_t *mk, int first)
  */
 static htsbuf_queue_t *
 mk_build_segment(mk_muxer_t *mk,
-                const streaming_start_t *ss)
+                streaming_start_t *ss)
 {
   htsbuf_queue_t *p = htsbuf_queue_alloc(0);
 
@@ -1232,7 +1233,7 @@ mkv_muxer_mime(muxer_t* m, const struct streaming_start *ss)
  * Init the muxer with a title and some tracks
  */
 static int
-mkv_muxer_init(muxer_t *m, const streaming_start_t *ss, const char *name)
+mkv_muxer_init(muxer_t *m, streaming_start_t *ss, const char *name)
 {
   mk_muxer_t *mk = (mk_muxer_t *)m;
   htsbuf_queue_t q, *a;
index 8415f279d6db034edfac9963377445862627bf23..87a97cf7be9543a7ee207f2e23349f55e663558a 100644 (file)
@@ -343,7 +343,7 @@ pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss)
  * Init the passthrough muxer with streams
  */
 static int
-pass_muxer_init(muxer_t* m, const struct streaming_start *ss, const char *name)
+pass_muxer_init(muxer_t* m, struct streaming_start *ss, const char *name)
 {
   return pass_muxer_reconfigure(m, ss);
 }
index f2bec49bbd095b28cf10369a2efff9c506ac55ba..a6f66df47b938d28249457097db25cd93e652460 100644 (file)
@@ -39,6 +39,7 @@ typedef struct streaming_start_component {
   uint8_t ssc_ext_sri;
   uint8_t ssc_channels;
   uint8_t ssc_disabled;
+  uint8_t ssc_muxer_disabled;
   
   pktbuf_t *ssc_gh;
 
index 921da278e4421f490f5ca1370dc987f6e4750479..8e413a082e67f1a2e3eb9427f82f90293870f059 100644 (file)
@@ -310,6 +310,7 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch,
   struct timeval  tp;
   int err = 0;
   socklen_t errlen = sizeof(err);
+  streaming_start_t *ss_copy;
   int64_t mono;
 
   if(muxer_open_stream(mux, hc->hc_fd))
@@ -396,8 +397,10 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch,
           return;
         }
 
-        if(muxer_init(mux, sm->sm_data, name) < 0)
+        ss_copy = streaming_start_copy((streaming_start_t *)sm->sm_data);
+        if(muxer_init(mux, ss_copy, name) < 0)
           run = 0;
+        streaming_start_unref(ss_copy);
 
         started = 1;
       } else if(muxer_reconfigure(mux, sm->sm_data) < 0) {