From 4b4398c9dd6e79b8e7ef842924174db37b799581 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 5 Jul 2010 14:09:50 +0530 Subject: [PATCH] qtmux: Write avg/max bitrate to ESDS if available 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 | 12 +++++++++--- gst/quicktime/atoms.h | 6 ++++-- gst/quicktime/gstqtmux.c | 27 +++++++++++++++++++++++---- gst/quicktime/gstqtmux.h | 2 ++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/gst/quicktime/atoms.c b/gst/quicktime/atoms.c index f616fd844e..253aef493a 100644 --- a/gst/quicktime/atoms.c +++ b/gst/quicktime/atoms.c @@ -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 */ diff --git a/gst/quicktime/atoms.h b/gst/quicktime/atoms.h index 85a41d3de7..5b59a7696f 100644 --- a/gst/quicktime/atoms.h +++ b/gst/quicktime/atoms.h @@ -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, diff --git a/gst/quicktime/gstqtmux.c b/gst/quicktime/gstqtmux.c index f324675d2f..ffcd4202b1 100644 --- a/gst/quicktime/gstqtmux.c +++ b/gst/quicktime/gstqtmux.c @@ -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: diff --git a/gst/quicktime/gstqtmux.h b/gst/quicktime/gstqtmux.h index 673c90b71d..16e7f42583 100644 --- a/gst/quicktime/gstqtmux.h +++ b/gst/quicktime/gstqtmux.h @@ -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 */