]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
muxers: pass 'User-Agent' from http streaming
authorJaroslav Kysela <perex@perex.cz>
Tue, 22 Aug 2017 14:00:44 +0000 (16:00 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 22 Aug 2017 14:00:44 +0000 (16:00 +0200)
- and add skip S_DVBSUB tracks for VLC (https://trac.videolan.org/vlc/ticket/14577)

14 files changed:
src/dvr/dvr_rec.c
src/muxer.c
src/muxer.h
src/muxer/muxer_audioes.c
src/muxer/muxer_audioes.h
src/muxer/muxer_libav.c
src/muxer/muxer_libav.h
src/muxer/muxer_mkv.c
src/muxer/muxer_mkv.h
src/muxer/muxer_pass.c
src/muxer/muxer_pass.h
src/profile.c
src/profile.h
src/webui/webui.c

index 3a289615a05f191e04fac32de16fc32875ab99fa..9ebd3d7d6bb15d5b746ec29d1f1ec48de7cffc3b 100644 (file)
@@ -114,13 +114,13 @@ dvr_rec_subscribe(dvr_entry_t *de)
   pro = de->de_config->dvr_profile;
   prch = malloc(sizeof(*prch));
   profile_chain_init(prch, pro, de->de_channel);
-  if (profile_chain_open(prch, &de->de_config->dvr_muxcnf, 0, 0)) {
+  if (profile_chain_open(prch, &de->de_config->dvr_muxcnf, NULL, 0, 0)) {
     profile_chain_close(prch);
     tvherror(LS_DVR, "unable to create new channel streaming chain '%s' for '%s', using default",
              profile_get_name(pro), channel_get_name(de->de_channel, channel_blank_name));
     pro = profile_find_by_name(NULL, NULL);
     profile_chain_init(prch, pro, de->de_channel);
-    if (profile_chain_open(prch, &de->de_config->dvr_muxcnf, 0, 0)) {
+    if (profile_chain_open(prch, &de->de_config->dvr_muxcnf, NULL, 0, 0)) {
       tvherror(LS_DVR, "unable to create channel streaming default chain '%s' for '%s'",
                profile_get_name(pro), channel_get_name(de->de_channel, channel_blank_name));
       profile_chain_close(prch);
@@ -948,7 +948,7 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
   }
 
   if (!(muxer = prch->prch_muxer)) {
-    if (profile_chain_reopen(prch, &cfg->dvr_muxcnf, 0)) {
+    if (profile_chain_reopen(prch, &cfg->dvr_muxcnf, NULL, 0)) {
       dvr_rec_fatal_error(de, "Unable to reopen muxer");
       return -1;
     }
index af6449f85e026e56653dd6752b7f1207fa89e259..d6f1eb28e409cdb6a37f65481a6d145deb6f7215 100644 (file)
@@ -271,7 +271,7 @@ muxer_config_copy(muxer_config_t *dst, const muxer_config_t *src)
 
 
 /**
- * Copy muxer settings
+ * Free muxer settings
  */
 void
 muxer_config_free(muxer_config_t *m_cfg)
@@ -284,37 +284,62 @@ muxer_config_free(muxer_config_t *m_cfg)
 }
 
 
+/**
+ * Create muxer hints
+ */
+muxer_hints_t *
+muxer_hints_create(const char *agent)
+{
+  muxer_hints_t *hints = calloc(1, sizeof(*hints));
+  mystrset(&hints->mh_agent, agent);
+  return hints;
+}
+
+
+/**
+ * Free muxer hints
+ */
+void
+muxer_hints_free(muxer_hints_t *hints)
+{
+  free(hints->mh_agent);
+  free(hints);
+}
+
+
 /**
  * Create a new muxer
  */
 muxer_t* 
-muxer_create(muxer_config_t *m_cfg)
+muxer_create(muxer_config_t *m_cfg, muxer_hints_t *hints)
 {
   muxer_t *m;
 
   assert(m_cfg);
 
-  m = pass_muxer_create(m_cfg);
+  m = pass_muxer_create(m_cfg, hints);
 
   if(!m)
-    m = mkv_muxer_create(m_cfg);
+    m = mkv_muxer_create(m_cfg, hints);
 
   if(!m)
-    m = audioes_muxer_create(m_cfg);
+    m = audioes_muxer_create(m_cfg, hints);
 
 #if CONFIG_LIBAV
   if(!m)
-    m = lav_muxer_create(m_cfg);
+    m = lav_muxer_create(m_cfg, hints);
 #endif
 
   if(!m) {
     tvherror(LS_MUXER, "Can't find a muxer that supports '%s' container",
            muxer_container_type2txt(m_cfg->m_type));
+    muxer_hints_free(hints);
     return NULL;
   }
   
   memcpy(&m->m_config, m_cfg, sizeof(muxer_config_t));
   memset(m_cfg, 0, sizeof(*m_cfg));
+  m->m_hints = hints;
 
   return m;
 }
index 865883d2dcd2d1594235fa9ab7044636a52cc2fe..aa4b17d326b3eb259d60f41cdcb87759fc8fedec 100644 (file)
@@ -87,6 +87,10 @@ typedef struct muxer_config {
   } u;
 } muxer_config_t;
 
+typedef struct muxer_hints {
+  char *mh_agent;
+} muxer_hints_t;
+
 struct muxer;
 struct streaming_start;
 struct th_pkt;
@@ -115,6 +119,7 @@ typedef struct muxer {
   int                    m_eos;        /* End of stream */
   int                    m_errors;     /* Number of errors */
   muxer_config_t         m_config;     /* general configuration */
+  muxer_hints_t         *m_hints;      /* other hints */
 } muxer_t;
 
 
@@ -129,12 +134,16 @@ muxer_container_type_t muxer_container_mime2type (const char *str);
 const char*            muxer_container_suffix(muxer_container_type_t mc, int video);
 
 /* Muxer factory */
-muxer_t *muxer_create(muxer_config_t *m_cfg);
+muxer_t *muxer_create(muxer_config_t *m_cfg, muxer_hints_t *hints);
 
 void muxer_config_copy(muxer_config_t *dst, const muxer_config_t *src);
 
 void muxer_config_free(muxer_config_t *m_cfg);
 
+muxer_hints_t *muxer_hints_create(const char *agent);
+
+void muxer_hints_free(muxer_hints_t *hints);
+
 /* Wrapper functions */
 static inline int muxer_open_file (muxer_t *m, const char *filename)
   { if(m && filename) return m->m_open_file(m, filename); return -1; }
@@ -155,7 +164,7 @@ static inline int muxer_close (muxer_t *m)
   { if (m) return m->m_close(m); return -1; }
 
 static inline int muxer_destroy (muxer_t *m)
-  { if (m) { m->m_destroy(m); muxer_config_free(&m->m_config); return 0; } return -1; }
+  { if (m) { m->m_destroy(m); return 0; } return -1; }
 
 static inline int muxer_write_meta (muxer_t *m, struct epg_broadcast *eb, const char *comment)
   { if (m) return m->m_write_meta(m, eb, comment); return -1; }
index 0277db1b1ad766c11666452ec5684a9010cfb978..f9f0e072d20e0cb3d4f5d63b47a0e6f7f9c59c3f 100644 (file)
@@ -283,6 +283,8 @@ audioes_muxer_destroy(muxer_t *m)
 
   if (am->am_filename)
     free(am->am_filename);
+  muxer_config_free(&am->m_config);
+  muxer_hints_free(am->m_hints);
   free(am);
 }
 
@@ -291,7 +293,8 @@ audioes_muxer_destroy(muxer_t *m)
  * Create a new builtin muxer
  */
 muxer_t*
-audioes_muxer_create(const muxer_config_t *m_cfg)
+audioes_muxer_create(const muxer_config_t *m_cfg,
+                     const muxer_hints_t *hints)
 {
   audioes_muxer_t *am;
 
index 1e4d3c0d0f1b28b8d8c22ae4f73c2d2e638cb49a..ac1a73d2ba967b7e6f7c8daf56faba7a9efd3647 100644 (file)
@@ -21,6 +21,6 @@
 
 #include "muxer.h"
 
-muxer_t* audioes_muxer_create (const muxer_config_t* m_cfg);
+muxer_t *audioes_muxer_create (const muxer_config_t *m_cfg, const muxer_hints_t *hints);
 
 #endif
index e62fbcdffd20561a0c7832ca8ca4415b0354237f..1841be55b46128b7ad51f4fd5c55fd685dc77361 100644 (file)
@@ -592,6 +592,8 @@ lav_muxer_destroy(muxer_t *m)
     lm->lm_oc = NULL;
   }
 
+  muxer_config_free(&lm->m_config);
+  muxer_hints_free(lm->m_hints);
   free(lm);
 }
 
@@ -600,7 +602,8 @@ lav_muxer_destroy(muxer_t *m)
  * Create a new libavformat based muxer
  */
 muxer_t*
-lav_muxer_create(const muxer_config_t *m_cfg)
+lav_muxer_create(const muxer_config_t *m_cfg,
+                 const muxer_hints_t *hints)
 {
   const char *mux_name;
   lav_muxer_t *lm;
index 4c9ec6094d2fccfe71df2c34973c392ac46c15b1..3852948cb23bd75b5334c21b47563446e9197716 100644 (file)
@@ -21,6 +21,6 @@
 
 #include "muxer.h"
 
-muxer_t* lav_muxer_create (const muxer_config_t* m_cfg);
+muxer_t *lav_muxer_create (const muxer_config_t *m_cfg, const muxer_hints_t *hints);
 
 #endif
index 5e8a1ff81ce4410c74d33fc2155c7d57b2da5477..f9940ec3e6fb49bfdc087b7e4ac87237f374c3a3 100644 (file)
@@ -132,6 +132,7 @@ typedef struct mk_muxer {
 
   int webm;
   int dvbsub_reorder;
+  int dvbsub_skip;
 
   struct th_pktref_queue holdq;
 } mk_muxer_t;
@@ -334,6 +335,8 @@ mk_build_tracks(mk_muxer_t *mk, streaming_start_t *ss)
       break;
 
     case SCT_DVBSUB:
+      if (mk->dvbsub_skip)
+        goto disable;
       tracktype = 0x11;
       codec_id = "S_DVBSUB";
       break;
@@ -344,6 +347,7 @@ mk_build_tracks(mk_muxer_t *mk, streaming_start_t *ss)
       break;
 
     default:
+disable:
       ssc->ssc_muxer_disabled = 1;
       tr->disabled = 1;
       continue;
@@ -1504,6 +1508,8 @@ mkv_muxer_destroy(muxer_t *m)
   free(mk->filename);
   free(mk->tracks);
   free(mk->title);
+  muxer_config_free(&mk->m_config);
+  muxer_hints_free(mk->m_hints);
   free(mk);
 }
 
@@ -1511,9 +1517,11 @@ mkv_muxer_destroy(muxer_t *m)
  * Create a new builtin muxer
  */
 muxer_t*
-mkv_muxer_create(const muxer_config_t *m_cfg)
+mkv_muxer_create(const muxer_config_t *m_cfg,
+                 const muxer_hints_t *hints)
 {
   mk_muxer_t *mk;
+  const char *agent = hints ? hints->mh_agent : NULL;
 
   if(m_cfg->m_type != MC_MATROSKA && m_cfg->m_type != MC_WEBM)
     return NULL;
@@ -1533,6 +1541,11 @@ mkv_muxer_create(const muxer_config_t *m_cfg)
   mk->dvbsub_reorder = m_cfg->u.mkv.m_dvbsub_reorder;
   mk->fd             = -1;
 
+  /*
+   * VLC has no support for MKV S_DVBSUB codec format
+   */
+  mk->dvbsub_skip    = strstr(agent, "LibVLC/") != NULL;
+
   TAILQ_INIT(&mk->holdq);
 
   return (muxer_t*)mk;
index 1e268a622582ff5741ac41e204db9efdbc1346ae..9abd2e5a96928cb52d5ee16de74fc8f4c30bcda1 100644 (file)
@@ -21,6 +21,6 @@
 
 #include "muxer.h"
 
-muxer_t* mkv_muxer_create (const muxer_config_t* m_cfg);
+muxer_t *mkv_muxer_create (const muxer_config_t *m_cfg, const muxer_hints_t *hints);
 
 #endif /* MUXER_MKV_H_ */
index e6f9499651aed23f22668038c3d86ee1f279cedc..b2000728e60a7042fdb5c69b89c14143150479f2 100644 (file)
@@ -630,6 +630,8 @@ pass_muxer_destroy(muxer_t *m)
   dvb_table_parse_done(&pm->pm_sdt);
   dvb_table_parse_done(&pm->pm_eit);
 
+  muxer_config_free(&pm->m_config);
+  muxer_hints_free(pm->m_hints);
   free(pm);
 }
 
@@ -638,7 +640,8 @@ pass_muxer_destroy(muxer_t *m)
  * Create a new passthrough muxer
  */
 muxer_t*
-pass_muxer_create(const muxer_config_t *m_cfg)
+pass_muxer_create(const muxer_config_t *m_cfg,
+                  const muxer_hints_t *hints)
 {
   pass_muxer_t *pm;
 
index af52b80188a2aae6b6849e5cc3fcfde82b6a6fb4..0cf269438cd20a7abbefb80b696446b92eea5cba 100644 (file)
@@ -21,6 +21,6 @@
 
 #include "muxer.h"
 
-muxer_t* pass_muxer_create (const muxer_config_t* m_cfg);
+muxer_t *pass_muxer_create (const muxer_config_t *m_cfg, const muxer_hints_t *hints);
 
 #endif
index a47b20745f99101529a0e7276353a8ea1f4997fc..0b33220ef750d0aff6b5d679a17441bcc12aaaaf 100644 (file)
@@ -1030,11 +1030,12 @@ profile_chain_work(profile_chain_t *prch, struct streaming_target *dst,
  */
 int
 profile_chain_reopen(profile_chain_t *prch,
-                     muxer_config_t *m_cfg, int flags)
+                     muxer_config_t *m_cfg,
+                     muxer_hints_t *hints, int flags)
 {
   profile_t *pro = prch->prch_pro;
   if (pro && pro->pro_reopen)
-    return pro->pro_reopen(prch, m_cfg, flags);
+    return pro->pro_reopen(prch, m_cfg, hints, flags);
   return -1;
 }
 
@@ -1043,11 +1044,13 @@ profile_chain_reopen(profile_chain_t *prch,
  */
 int
 profile_chain_open(profile_chain_t *prch,
-                   muxer_config_t *m_cfg, int flags, size_t qsize)
+                   muxer_config_t *m_cfg,
+                   muxer_hints_t *hints,
+                   int flags, size_t qsize)
 {
   profile_t *pro = prch->prch_pro;
   if (pro && pro->pro_open)
-    return pro->pro_open(prch, m_cfg, flags, qsize);
+    return pro->pro_open(prch, m_cfg, hints, flags, qsize);
   return -1;
 }
 
@@ -1068,7 +1071,7 @@ profile_chain_raw_open(profile_chain_t *prch, void *id, size_t qsize, int muxer)
   if (muxer) {
     memset(&c, 0, sizeof(c));
     c.m_type = MC_RAW;
-    prch->prch_muxer = muxer_create(&c);
+    prch->prch_muxer = muxer_create(&c, NULL);
   }
   return 0;
 }
@@ -1375,7 +1378,8 @@ const idclass_t profile_mpegts_pass_class =
 
 static int
 profile_mpegts_pass_reopen(profile_chain_t *prch,
-                           muxer_config_t *m_cfg, int flags)
+                           muxer_config_t *m_cfg,
+                           muxer_hints_t *hints, int flags)
 {
   profile_mpegts_t *pro = (profile_mpegts_t *)prch->prch_pro;
   muxer_config_t c;
@@ -1393,13 +1397,15 @@ profile_mpegts_pass_reopen(profile_chain_t *prch,
   c.u.pass.m_rewrite_eit = pro->pro_rewrite_eit;
 
   assert(!prch->prch_muxer);
-  prch->prch_muxer = muxer_create(&c);
+  prch->prch_muxer = muxer_create(&c, hints);
   return 0;
 }
 
 static int
 profile_mpegts_pass_open(profile_chain_t *prch,
-                         muxer_config_t *m_cfg, int flags, size_t qsize)
+                         muxer_config_t *m_cfg,
+                         muxer_hints_t *hints,
+                         int flags, size_t qsize)
 {
   prch->prch_flags = SUBSCRIPTION_MPEGTS;
 
@@ -1408,8 +1414,7 @@ profile_mpegts_pass_open(profile_chain_t *prch,
 
   prch->prch_st    = &prch->prch_sq.sq_st;
 
-  profile_mpegts_pass_reopen(prch, m_cfg, flags);
-  return 0;
+  return profile_mpegts_pass_reopen(prch, m_cfg, hints, flags);
 }
 
 static profile_t *
@@ -1499,7 +1504,8 @@ const idclass_t profile_mpegts_spawn_class =
 
 static int
 profile_mpegts_spawn_reopen(profile_chain_t *prch,
-                           muxer_config_t *m_cfg, int flags)
+                            muxer_config_t *m_cfg,
+                            muxer_hints_t *hints, int flags)
 {
   profile_mpegts_spawn_t *pro = (profile_mpegts_spawn_t *)prch->prch_pro;
   muxer_config_t c;
@@ -1522,13 +1528,15 @@ profile_mpegts_spawn_reopen(profile_chain_t *prch,
   c.u.pass.m_killtimeout = pro->pro_killtimeout;
 
   assert(!prch->prch_muxer);
-  prch->prch_muxer = muxer_create(&c);
+  prch->prch_muxer = muxer_create(&c, hints);
   return 0;
 }
 
 static int
 profile_mpegts_spawn_open(profile_chain_t *prch,
-                         muxer_config_t *m_cfg, int flags, size_t qsize)
+                          muxer_config_t *m_cfg,
+                          muxer_hints_t *hints,
+                          int flags, size_t qsize)
 {
   prch->prch_flags = SUBSCRIPTION_MPEGTS;
 
@@ -1537,7 +1545,7 @@ profile_mpegts_spawn_open(profile_chain_t *prch,
 
   prch->prch_st    = &prch->prch_sq.sq_st;
 
-  return profile_mpegts_spawn_reopen(prch, m_cfg, flags);
+  return profile_mpegts_spawn_reopen(prch, m_cfg, hints, flags);
 }
 
 static void
@@ -1613,7 +1621,8 @@ const idclass_t profile_matroska_class =
 
 static int
 profile_matroska_reopen(profile_chain_t *prch,
-                        muxer_config_t *m_cfg, int flags)
+                        muxer_config_t *m_cfg,
+                        muxer_hints_t *hints, int flags)
 {
   profile_matroska_t *pro = (profile_matroska_t *)prch->prch_pro;
   muxer_config_t c;
@@ -1630,13 +1639,15 @@ profile_matroska_reopen(profile_chain_t *prch,
   c.u.mkv.m_dvbsub_reorder = pro->pro_dvbsub_reorder;
 
   assert(!prch->prch_muxer);
-  prch->prch_muxer = muxer_create(&c);
+  prch->prch_muxer = muxer_create(&c, hints);
   return 0;
 }
 
 static int
 profile_matroska_open(profile_chain_t *prch,
-                      muxer_config_t *m_cfg, int flags, size_t qsize)
+                      muxer_config_t *m_cfg,
+                      muxer_hints_t *hints,
+                      int flags, size_t qsize)
 {
   streaming_target_t *dst;
 
@@ -1647,9 +1658,7 @@ profile_matroska_open(profile_chain_t *prch,
   dst = prch->prch_tsfix = tsfix_create(dst);
   prch->prch_st    = dst;
 
-  profile_matroska_reopen(prch, m_cfg, flags);
-
-  return 0;
+  return profile_matroska_reopen(prch, m_cfg, hints, flags);
 }
 
 static profile_t *
@@ -1717,7 +1726,8 @@ const idclass_t profile_audio_class =
 
 static int
 profile_audio_reopen(profile_chain_t *prch,
-                     muxer_config_t *m_cfg, int flags)
+                     muxer_config_t *m_cfg,
+                     muxer_hints_t *hints, int flags)
 {
   muxer_config_t c;
   profile_audio_t *pro = (profile_audio_t *)prch->prch_pro;
@@ -1731,13 +1741,15 @@ profile_audio_reopen(profile_chain_t *prch,
   c.u.audioes.m_index = pro->pro_index;
 
   assert(!prch->prch_muxer);
-  prch->prch_muxer = muxer_create(&c);
+  prch->prch_muxer = muxer_create(&c, hints);
   return 0;
 }
 
 static int
 profile_audio_open(profile_chain_t *prch,
-                   muxer_config_t *m_cfg, int flags, size_t qsize)
+                   muxer_config_t *m_cfg,
+                   muxer_hints_t *hints,
+                   int flags, size_t qsize)
 {
   int r;
 
@@ -1750,8 +1762,7 @@ profile_audio_open(profile_chain_t *prch,
     return r;
   }
 
-  profile_audio_reopen(prch, m_cfg, flags);
-  return 0;
+  return profile_audio_reopen(prch, m_cfg, hints, flags);
 }
 
 static profile_t *
@@ -1786,7 +1797,8 @@ const idclass_t profile_libav_mpegts_class =
 
 static int
 profile_libav_mpegts_reopen(profile_chain_t *prch,
-                            muxer_config_t *m_cfg, int flags)
+                            muxer_config_t *m_cfg,
+                            muxer_hints_t *hints, int flags)
 {
   muxer_config_t c;
 
@@ -1797,13 +1809,15 @@ profile_libav_mpegts_reopen(profile_chain_t *prch,
   c.m_type = MC_MPEGTS;
 
   assert(!prch->prch_muxer);
-  prch->prch_muxer = muxer_create(&c);
+  prch->prch_muxer = muxer_create(&c, hints);
   return 0;
 }
 
 static int
 profile_libav_mpegts_open(profile_chain_t *prch,
-                          muxer_config_t *m_cfg, int flags, size_t qsize)
+                          muxer_config_t *m_cfg,
+                          muxer_hints_t *hints,
+                          int flags, size_t qsize)
 {
   int r;
 
@@ -1816,8 +1830,7 @@ profile_libav_mpegts_open(profile_chain_t *prch,
     return r;
   }
 
-  profile_libav_mpegts_reopen(prch, m_cfg, flags);
-  return 0;
+  return profile_libav_mpegts_reopen(prch, m_cfg, hints, flags);
 }
 
 static profile_t *
@@ -1871,7 +1884,8 @@ const idclass_t profile_libav_matroska_class =
 
 static int
 profile_libav_matroska_reopen(profile_chain_t *prch,
-                              muxer_config_t *m_cfg, int flags)
+                              muxer_config_t *m_cfg,
+                              muxer_hints_t *hints, int flags)
 {
   profile_libav_matroska_t *pro = (profile_libav_matroska_t *)prch->prch_pro;
   muxer_config_t c;
@@ -1886,13 +1900,15 @@ profile_libav_matroska_reopen(profile_chain_t *prch,
     c.m_type = MC_AVWEBM;
 
   assert(!prch->prch_muxer);
-  prch->prch_muxer = muxer_create(&c);
+  prch->prch_muxer = muxer_create(&c, hints);
   return 0;
 }
 
 static int
 profile_libav_matroska_open(profile_chain_t *prch,
-                            muxer_config_t *m_cfg, int flags, size_t qsize)
+                            muxer_config_t *m_cfg,
+                            muxer_hints_t *hints,
+                            int flags, size_t qsize)
 {
   int r;
 
@@ -1905,9 +1921,7 @@ profile_libav_matroska_open(profile_chain_t *prch,
     return r;
   }
 
-  profile_libav_matroska_reopen(prch, m_cfg, flags);
-
-  return 0;
+  return profile_libav_matroska_reopen(prch, m_cfg, hints, flags);
 }
 
 static profile_t *
@@ -1936,7 +1950,8 @@ const idclass_t profile_libav_mp4_class =
 
 static int
 profile_libav_mp4_reopen(profile_chain_t *prch,
-                         muxer_config_t *m_cfg, int flags)
+                         muxer_config_t *m_cfg,
+                         muxer_hints_t *hints, int flags)
 {
   muxer_config_t c;
 
@@ -1948,13 +1963,15 @@ profile_libav_mp4_reopen(profile_chain_t *prch,
     c.m_type = MC_AVMP4;
 
   assert(!prch->prch_muxer);
-  prch->prch_muxer = muxer_create(&c);
+  prch->prch_muxer = muxer_create(&c, hints);
   return 0;
 }
 
 static int
 profile_libav_mp4_open(profile_chain_t *prch,
-                       muxer_config_t *m_cfg, int flags, size_t qsize)
+                       muxer_config_t *m_cfg,
+                       muxer_hints_t *hints,
+                       int flags, size_t qsize)
 {
   int r;
 
@@ -1967,9 +1984,7 @@ profile_libav_mp4_open(profile_chain_t *prch,
     return r;
   }
 
-  profile_libav_mp4_reopen(prch, m_cfg, flags);
-
-  return 0;
+  return profile_libav_mp4_reopen(prch, m_cfg, hints, flags);
 }
 
 static profile_t *
@@ -2466,7 +2481,8 @@ profile_transcode_mc_valid(int mc)
 
 static int
 profile_transcode_reopen(profile_chain_t *prch,
-                         muxer_config_t *m_cfg, int flags)
+                         muxer_config_t *m_cfg,
+                         muxer_hints_t *hints, int flags)
 {
   profile_transcode_t *pro = (profile_transcode_t *)prch->prch_pro;
   muxer_config_t c;
@@ -2482,13 +2498,15 @@ profile_transcode_reopen(profile_chain_t *prch,
   }
 
   assert(!prch->prch_muxer);
-  prch->prch_muxer = muxer_create(&c);
+  prch->prch_muxer = muxer_create(&c, hints);
   return 0;
 }
 
 static int
 profile_transcode_open(profile_chain_t *prch,
-                       muxer_config_t *m_cfg, int flags, size_t qsize)
+                       muxer_config_t *m_cfg,
+                       muxer_hints_t *hints,
+                       int flags, size_t qsize)
 {
   int r;
 
@@ -2503,8 +2521,7 @@ profile_transcode_open(profile_chain_t *prch,
     return r;
   }
 
-  profile_transcode_reopen(prch, m_cfg, flags);
-  return 0;
+  return profile_transcode_reopen(prch, m_cfg, hints, flags);
 }
 
 static void
index 7ae712a935de9e87819f634bf19ac884c09fde0d..0c6e623d8396ec2a974b66841351498f0ae8e2f3 100644 (file)
@@ -129,10 +129,10 @@ typedef struct profile {
 
   int (*pro_work)(profile_chain_t *prch, struct streaming_target *dst,
                   uint32_t timeshift_period, int flags);
-  int (*pro_reopen)(profile_chain_t *prch,
-                    muxer_config_t *m_cfg, int flags);
-  int (*pro_open)(profile_chain_t *prch,
-                  muxer_config_t *m_cfg, int flags, size_t qsize);
+  int (*pro_reopen)(profile_chain_t *prch, muxer_config_t *m_cfg,
+                    muxer_hints_t *hints, int flags);
+  int (*pro_open)(profile_chain_t *prch, muxer_config_t *m_cfg,
+                  muxer_hints_t *hints, int flags, size_t qsize);
 } profile_t;
 
 typedef struct profile_sharer_message {
@@ -173,15 +173,15 @@ static inline void profile_release( profile_t *pro )
     if (--pro->pro_refcount == 0) profile_release_(pro);
   }
 
-int
-profile_chain_work(profile_chain_t *prch, struct streaming_target *dst,
-                   uint32_t timeshift_period, int flags);
-int
-profile_chain_reopen(profile_chain_t *prch,
-                     muxer_config_t *m_cfg, int flags);
-int
-profile_chain_open(profile_chain_t *prch,
-                   muxer_config_t *m_cfg, int flags, size_t qsize);
+int profile_chain_work(profile_chain_t *prch, struct streaming_target *dst,
+                       uint32_t timeshift_period, int flags);
+int profile_chain_reopen(profile_chain_t *prch,
+                         muxer_config_t *m_cfg,
+                         muxer_hints_t *hints, int flags);
+int profile_chain_open(profile_chain_t *prch,
+                       muxer_config_t *m_cfg,
+                       muxer_hints_t *hints,
+                       int flags, size_t qsize);
 void profile_chain_init(profile_chain_t *prch, profile_t *pro, void *id);
 int  profile_chain_raw_open(profile_chain_t *prch, void *id, size_t qsize, int muxer);
 void profile_chain_close(profile_chain_t *prch);
index ca55f36566125aa6a4a21bc04c5931a945d8e26d..7728d4712282bf6bba869ee98c5a38ce9afa7f8b 100644 (file)
@@ -1140,6 +1140,7 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight)
   th_subscription_t *s;
   profile_t *pro;
   profile_chain_t prch;
+  muxer_hints_t *hints;
   const char *str;
   size_t qsize;
   const char *name;
@@ -1174,8 +1175,10 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight)
   else
     qsize = 1500000;
 
+  hints = muxer_hints_create(http_arg_get(&hc->hc_args, "User-Agent"));
+
   profile_chain_init(&prch, pro, service);
-  if (!profile_chain_open(&prch, NULL, 0, qsize)) {
+  if (!profile_chain_open(&prch, NULL, hints, 0, qsize)) {
 
     s = subscription_create_from_service(&prch, NULL, weight, "HTTP",
                                          prch.prch_flags | SUBSCRIPTION_STREAMING |
@@ -1290,6 +1293,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight)
   th_subscription_t *s;
   profile_t *pro;
   profile_chain_t prch;
+  muxer_hints_t *hints;
   char *str;
   size_t qsize;
   const char *name;
@@ -1313,8 +1317,10 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight)
   else
     qsize = 1500000;
 
+  hints = muxer_hints_create(http_arg_get(&hc->hc_args, "User-Agent"));
+
   profile_chain_init(&prch, pro, ch);
-  if (!profile_chain_open(&prch, NULL, 0, qsize)) {
+  if (!profile_chain_open(&prch, NULL, hints, 0, qsize)) {
 
     s = subscription_create_from_channel(&prch,
                  NULL, weight, "HTTP",