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
This commit is contained in:
Arun Raghavan 2010-07-05 14:09:50 +05:30 committed by Tim-Philipp Müller
parent 099ad6380f
commit 4b4398c9dd
4 changed files with 38 additions and 9 deletions

View 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 */

View 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,

View 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:

View 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 */