qtmux: Write avg/max bitrate to ESDS if available
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 5 Jul 2010 08:39:50 +0000 (14:09 +0530)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Tue, 12 Apr 2011 19:32:18 +0000 (20:32 +0100)
This collects the 'bitrate' and 'maximum-bitrate' tags on the
corresponding pad and uses these to populate these fields in the ESDS
where applicable.

https://bugzilla.gnome.org/show_bug.cgi?id=623678

gst/quicktime/atoms.c
gst/quicktime/atoms.h
gst/quicktime/gstqtmux.c
gst/quicktime/gstqtmux.h

index f616fd8..253aef4 100644 (file)
@@ -3091,7 +3091,7 @@ atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
 
 AtomInfo *
 build_esds_extension (AtomTRAK * trak, guint8 object_type, guint8 stream_type,
-    const GstBuffer * codec_data)
+    const GstBuffer * codec_data, guint32 avg_bitrate, guint32 max_bitrate)
 {
   guint32 track_id;
   AtomESDS *esds;
@@ -3103,6 +3103,11 @@ build_esds_extension (AtomTRAK * trak, guint8 object_type, guint8 stream_type,
   esds->es.dec_conf_desc.object_type = object_type;
   esds->es.dec_conf_desc.stream_type = stream_type << 2 | 0x01;
 
+  if (avg_bitrate > 0)
+    esds->es.dec_conf_desc.avg_bitrate = avg_bitrate;
+  if (max_bitrate > 0)
+    esds->es.dec_conf_desc.max_bitrate = max_bitrate;
+
   /* optional DecoderSpecificInfo */
   if (codec_data) {
     DecoderSpecificInfoDescriptor *desc;
@@ -3157,14 +3162,15 @@ build_mov_wave_extension (AtomTRAK * trak, guint32 fourcc, AtomInfo * atom1,
 }
 
 AtomInfo *
-build_mov_aac_extension (AtomTRAK * trak, const GstBuffer * codec_data)
+build_mov_aac_extension (AtomTRAK * trak, const GstBuffer * codec_data,
+    guint32 avg_bitrate, guint32 max_bitrate)
 {
   AtomInfo *esds, *mp4a;
   GstBuffer *buf;
 
   /* Add ESDS atom to WAVE */
   esds = build_esds_extension (trak, ESDS_OBJECT_TYPE_MPEG4_P3,
-      ESDS_STREAM_TYPE_AUDIO, codec_data);
+      ESDS_STREAM_TYPE_AUDIO, codec_data, avg_bitrate, max_bitrate);
 
   /* Add MP4A atom to the WAVE:
    * not really in spec, but makes offset based players happy */
index 85a41d3..5b59a76 100644 (file)
@@ -720,10 +720,12 @@ void atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
                                GList * ext_atoms_list);
 
 AtomInfo *   build_codec_data_extension  (guint32 fourcc, const GstBuffer * codec_data);
-AtomInfo *   build_mov_aac_extension     (AtomTRAK * trak, const GstBuffer * codec_data);
+AtomInfo *   build_mov_aac_extension     (AtomTRAK * trak, const GstBuffer * codec_data,
+                                          guint32 avg_bitrate, guint32 max_bitrate);
 AtomInfo *   build_mov_alac_extension    (AtomTRAK * trak, const GstBuffer * codec_data);
 AtomInfo *   build_esds_extension        (AtomTRAK * trak, guint8 object_type,
-                                          guint8 stream_type, const GstBuffer * codec_data);
+                                          guint8 stream_type, const GstBuffer * codec_data,
+                                          guint32 avg_bitrate, guint32 max_bitrate);
 AtomInfo *   build_jp2h_extension        (AtomTRAK * trak, gint width, gint height,
                                           guint32 fourcc, gint ncomp,
                                           const GValue * cmap_array,
index f324675..ffcd420 100644 (file)
@@ -258,6 +258,8 @@ gst_qt_mux_pad_reset (GstQTPad * qtpad)
   qtpad->last_dts = 0;
   qtpad->first_ts = GST_CLOCK_TIME_NONE;
   qtpad->prepare_buf_func = NULL;
+  qtpad->avg_bitrate = 0;
+  qtpad->max_bitrate = 0;
 
   if (qtpad->last_buf)
     gst_buffer_replace (&qtpad->last_buf, NULL);
@@ -1943,7 +1945,8 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps)
               entry.fourcc = FOURCC_mp4a;
               ext_atom =
                   build_esds_extension (qtpad->trak, ESDS_OBJECT_TYPE_MPEG1_P3,
-                  ESDS_STREAM_TYPE_AUDIO, codec_data);
+                  ESDS_STREAM_TYPE_AUDIO, codec_data, qtpad->avg_bitrate,
+                  qtpad->max_bitrate);
             }
             entry.samples_per_packet = 1152;
             entry.bytes_per_sample = 2;
@@ -1981,11 +1984,13 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps)
         entry.fourcc = FOURCC_mp4a;
 
         if (format == GST_QT_MUX_FORMAT_QT)
-          ext_atom = build_mov_aac_extension (qtpad->trak, codec_data);
+          ext_atom = build_mov_aac_extension (qtpad->trak, codec_data,
+              qtpad->avg_bitrate, qtpad->max_bitrate);
         else
           ext_atom =
               build_esds_extension (qtpad->trak, ESDS_OBJECT_TYPE_MPEG4_P3,
-              ESDS_STREAM_TYPE_AUDIO, codec_data);
+              ESDS_STREAM_TYPE_AUDIO, codec_data, qtpad->avg_bitrate,
+              qtpad->max_bitrate);
         break;
       default:
         break;
@@ -2302,7 +2307,8 @@ gst_qt_mux_video_sink_set_caps (GstPad * pad, GstCaps * caps)
       entry.fourcc = FOURCC_mp4v;
       ext_atom =
           build_esds_extension (qtpad->trak, ESDS_OBJECT_TYPE_MPEG4_P2,
-          ESDS_STREAM_TYPE_VISUAL, codec_data);
+          ESDS_STREAM_TYPE_VISUAL, codec_data, qtpad->avg_bitrate,
+          qtpad->max_bitrate);
       if (ext_atom != NULL)
         ext_atom_list = g_list_prepend (ext_atom_list, ext_atom);
       if (!codec_data)
@@ -2473,6 +2479,7 @@ gst_qt_mux_sink_event (GstPad * pad, GstEvent * event)
 {
   gboolean ret;
   GstQTMux *qtmux;
+  guint32 avg_bitrate = 0, max_bitrate = 0;
 
   qtmux = GST_QT_MUX_CAST (gst_pad_get_parent (pad));
   switch (GST_EVENT_TYPE (event)) {
@@ -2489,6 +2496,18 @@ gst_qt_mux_sink_event (GstPad * pad, GstEvent * event)
 
       gst_tag_setter_merge_tags (setter, list, mode);
       GST_OBJECT_UNLOCK (qtmux);
+
+      if (gst_tag_list_get_uint (list, GST_TAG_BITRATE, &avg_bitrate) |
+          gst_tag_list_get_uint (list, GST_TAG_MAXIMUM_BITRATE, &max_bitrate)) {
+        GstQTPad *qtpad = gst_pad_get_element_private (pad);
+        g_assert (qtpad);
+
+        if (avg_bitrate > 0 && avg_bitrate < G_MAXUINT32)
+          qtpad->avg_bitrate = avg_bitrate;
+        if (max_bitrate > 0 && max_bitrate < G_MAXUINT32)
+          qtpad->max_bitrate = max_bitrate;
+      }
+
       break;
     }
     default:
index 673c90b..16e7f42 100644 (file)
@@ -92,6 +92,8 @@ struct _GstQTPad
   guint sample_size;
   /* make sync table entry */
   gboolean sync;
+  /* bitrates */
+  guint32 avg_bitrate, max_bitrate;
 
   GstBuffer *last_buf;
   /* dts of last_buf */