hlsdemux: Extract ID3 tags, strip them from the output and provide them as tags
authorSebastian Dröge <sebastian@centricular.com>
Mon, 19 Dec 2016 09:40:28 +0000 (11:40 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 19 Dec 2016 09:51:36 +0000 (11:51 +0200)
They often don't only contain the PCR information but also other
metadata, like title. Give this information to the pipeline.

Also strip the tags from the stream as we a) already parsed them now and
b) decoders don't like these tags to happen in the middle of the stream
(i.e. the start of each fragment) and tagdemux only can strip them off
the beginning and end.

ext/hls/gsthlsdemux-util.c
ext/hls/gsthlsdemux.c
ext/hls/gsthlsdemux.h

index 252f042c5fc237378754a3d73f436c1fd4c53063..efa1129a33a300de490e7e0758d27af7f25bcfdf 100644 (file)
@@ -265,13 +265,15 @@ gst_hlsdemux_tsreader_find_pcrs_mpegts (GstHLSTSReader * r,
 
 static gboolean
 gst_hlsdemux_tsreader_find_pcrs_id3 (GstHLSTSReader * r,
-    GstBuffer * buffer, GstClockTime * first_pcr, GstClockTime * last_pcr)
+    GstBuffer ** buffer_out, GstClockTime * first_pcr, GstClockTime * last_pcr,
+    GstTagList ** tags)
 {
   GstMapInfo info;
   guint32 tag_size;
   gsize size;
   GstTagList *taglist;
   GstSample *priv_data = NULL;
+  GstBuffer *buffer = *buffer_out;
   GstBuffer *tag_buf;
   guint64 pts;
 
@@ -297,10 +299,17 @@ gst_hlsdemux_tsreader_find_pcrs_id3 (GstHLSTSReader * r,
    * not try and read again */
   r->have_id3 = TRUE;
 
+  *buffer_out =
+      gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, tag_size, -1);
+
   /* Parse the tag */
   taglist = gst_tag_list_from_id3v2_tag (buffer);
-  if (taglist == NULL)
+  if (taglist == NULL) {
+    gst_buffer_unref (buffer);
     return TRUE;                /* Invalid tag, stop trying */
+  }
+
+  *tags = taglist;
 
   /* Extract the timestamps */
   if (!gst_tag_list_get_sample (taglist, GST_TAG_PRIVATE_DATA, &priv_data))
@@ -330,19 +339,22 @@ gst_hlsdemux_tsreader_find_pcrs_id3 (GstHLSTSReader * r,
 out:
   if (priv_data)
     gst_sample_unref (priv_data);
-
-  gst_tag_list_unref (taglist);
+  gst_buffer_unref (buffer);
 
   return TRUE;
 }
 
 gboolean
 gst_hlsdemux_tsreader_find_pcrs (GstHLSTSReader * r,
-    GstBuffer * buffer, GstClockTime * first_pcr, GstClockTime * last_pcr)
+    GstBuffer ** buffer, GstClockTime * first_pcr, GstClockTime * last_pcr,
+    GstTagList ** tags)
 {
+  *tags = NULL;
+
   if (r->rtype == GST_HLS_TSREADER_MPEGTS)
-    return gst_hlsdemux_tsreader_find_pcrs_mpegts (r, buffer, first_pcr,
+    return gst_hlsdemux_tsreader_find_pcrs_mpegts (r, *buffer, first_pcr,
         last_pcr);
 
-  return gst_hlsdemux_tsreader_find_pcrs_id3 (r, buffer, first_pcr, last_pcr);
+  return gst_hlsdemux_tsreader_find_pcrs_id3 (r, buffer, first_pcr, last_pcr,
+      tags);
 }
index 9247d45c333febd5df4151583bb5606a2a7fb2d6..3e82d58e986399c66030698bea5b6f95d7855e42 100644 (file)
@@ -767,6 +767,7 @@ gst_hls_demux_handle_buffer (GstAdaptiveDemux * demux,
   GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
   GstMapInfo info;
   GstClockTime first_pcr, last_pcr;
+  GstTagList *tags;
 
   if (buffer == NULL)
     return GST_FLOW_OK;
@@ -832,14 +833,18 @@ gst_hls_demux_handle_buffer (GstAdaptiveDemux * demux,
     hls_stream->pending_pcr_buffer = NULL;
   }
 
-  if (!gst_hlsdemux_tsreader_find_pcrs (&hls_stream->tsreader, buffer,
-          &first_pcr, &last_pcr)
+  if (!gst_hlsdemux_tsreader_find_pcrs (&hls_stream->tsreader, &buffer,
+          &first_pcr, &last_pcr, &tags)
       && !at_eos) {
     // Store this buffer for later
     hls_stream->pending_pcr_buffer = buffer;
     return GST_FLOW_OK;
   }
 
+  if (tags) {
+    gst_adaptive_demux_stream_set_tags (stream, tags);
+  }
+
   if (buffer) {
     buffer = gst_buffer_make_writable (buffer);
     GST_BUFFER_OFFSET (buffer) = hls_stream->current_offset;
index f2bc238c5d90d900bd008ada80f76c825cbf5c9f..4a2b9c0fe4fbdc8904bd29c43fb5844903d54628 100644 (file)
@@ -154,8 +154,8 @@ struct _GstHLSDemuxClass
 void gst_hlsdemux_tsreader_init (GstHLSTSReader *r);
 void gst_hlsdemux_tsreader_set_type (GstHLSTSReader *r, GstHLSTSReaderType rtype);
 
-gboolean gst_hlsdemux_tsreader_find_pcrs (GstHLSTSReader *r, GstBuffer *buffer,
-    GstClockTime *first_pcr, GstClockTime *last_pcr);
+gboolean gst_hlsdemux_tsreader_find_pcrs (GstHLSTSReader *r, GstBuffer **buffer,
+    GstClockTime *first_pcr, GstClockTime *last_pcr, GstTagList **tags);
 
 GType gst_hls_demux_get_type (void);