diff options
author | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2008-06-29 19:52:51 +0000 |
---|---|---|
committer | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2008-06-29 19:52:51 +0000 |
commit | ae82126a56898c37b4e242cc370dfa28c151c471 (patch) | |
tree | 39d933da9b256e851706ea1bc2745a3bc0aed16b /gst/avi/gstavimux.c | |
parent | cb0b3da393b5d695d852bfb683eeb042dd62ec96 (diff) |
gst/avi/avi-ids.h: Add vprp chunk related structures.
Original commit message from CVS:
* gst/avi/avi-ids.h:
Add vprp chunk related structures.
* gst/avi/gstavidemux.c: (gst_avi_demux_riff_parse_vprp),
(gst_avi_demux_parse_stream):
Parse optional vprp chunk and add calculated pixel-aspect-ratio
to caps. Fixes #539482.
* gst/avi/gstavimux.h:
* gst/avi/gstavimux.c: (gst_avi_mux_pad_reset),
(gst_avi_mux_vidsink_set_caps), (gst_avi_mux_riff_get_avi_header):
Add a vprp chunk if non-trival pixel-aspect-ratio provided in caps.
Diffstat (limited to 'gst/avi/gstavimux.c')
-rw-r--r-- | gst/avi/gstavimux.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/gst/avi/gstavimux.c b/gst/avi/gstavimux.c index 3beff5e4..80d8ba8d 100644 --- a/gst/avi/gstavimux.c +++ b/gst/avi/gstavimux.c @@ -337,6 +337,7 @@ gst_avi_mux_pad_reset (GstAviPad * avipad, gboolean free) } memset (&(vidpad->vids), 0, sizeof (gst_riff_strf_vids)); + memset (&(vidpad->vprp), 0, sizeof (gst_riff_vprp)); } else { GstAviAudioPad *audpad = (GstAviAudioPad *) avipad; @@ -425,9 +426,10 @@ gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps) GstAviCollectData *collect_pad; GstStructure *structure; const gchar *mimetype; - const GValue *fps; + const GValue *fps, *par; const GValue *codec_data; gint width, height; + gint par_n, par_d; avimux = GST_AVI_MUX (gst_pad_get_parent (pad)); @@ -463,6 +465,36 @@ gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps) avipad->parent.hdr.rate = gst_value_get_fraction_numerator (fps); avipad->parent.hdr.scale = gst_value_get_fraction_denominator (fps); + /* (pixel) aspect ratio data, if any */ + par = gst_structure_get_value (structure, "pixel-aspect-ratio"); + /* only use video properties header if there is non-trivial aspect info */ + if (par && GST_VALUE_HOLDS_FRACTION (par) && + ((par_n = gst_value_get_fraction_numerator (par)) != + (par_d = gst_value_get_fraction_denominator (par)))) { + GValue to_ratio = { 0, }; + guint ratio_n, ratio_d; + + /* some fraction voodoo to obtain simplest possible ratio */ + g_value_init (&to_ratio, GST_TYPE_FRACTION); + gst_value_set_fraction (&to_ratio, width * par_n, height * par_d); + ratio_n = gst_value_get_fraction_numerator (&to_ratio); + ratio_d = gst_value_get_fraction_denominator (&to_ratio); + GST_DEBUG_OBJECT (avimux, "generating vprp data with aspect ratio %d/%d", + ratio_n, ratio_d); + /* simply fill in */ + avipad->vprp.vert_rate = avipad->parent.hdr.rate / avipad->parent.hdr.scale; + avipad->vprp.hor_t_total = width; + avipad->vprp.vert_lines = height; + avipad->vprp.aspect = (ratio_n) << 16 | (ratio_d & 0xffff); + avipad->vprp.width = width; + avipad->vprp.height = height; + avipad->vprp.fields = 1; + avipad->vprp.field_info[0].compressed_bm_height = height; + avipad->vprp.field_info[0].compressed_bm_width = width; + avipad->vprp.field_info[0].valid_bm_height = height; + avipad->vprp.field_info[0].valid_bm_width = width; + } + /* codec initialization data, if any */ codec_data = gst_structure_get_value (structure, "codec_data"); if (codec_data) { @@ -957,6 +989,7 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux) size += avimux->codec_data_size + 100 + sizeof (gst_riff_avih) + (g_slist_length (avimux->sinkpads) * (100 + sizeof (gst_riff_strh_full) + sizeof (gst_riff_strf_vids) + + sizeof (gst_riff_vprp) + sizeof (gst_riff_strf_auds) + ODML_SUPERINDEX_SIZE)); buffer = gst_buffer_new_and_alloc (size); @@ -1003,13 +1036,21 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux) GstAviPad *avipad = (GstAviPad *) node->data; GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad; GstAviAudioPad *audpad = (GstAviAudioPad *) avipad; - guint codec_size = 0, strl_size = 0; + guint codec_size = 0, strl_size = 0, vprp_size = 0; if (avipad->is_video) { if (vidpad->vids_codec_data) codec_size = GST_BUFFER_SIZE (vidpad->vids_codec_data); strl_size = sizeof (gst_riff_strh_full) + sizeof (gst_riff_strf_vids) + codec_size + 4 * 5 + ODML_SUPERINDEX_SIZE; + if (vidpad->vprp.aspect) { + /* let's be on the safe side */ + vidpad->vprp.fields = MIN (vidpad->vprp.fields, + GST_RIFF_VPRP_VIDEO_FIELDS); + vprp_size = G_STRUCT_OFFSET (gst_riff_vprp, field_info) + + (vidpad->vprp.fields * sizeof (gst_riff_vprp_video_field_desc)); + strl_size += 4 * 2 + vprp_size; + } } else { if (audpad->auds_codec_data) codec_size = GST_BUFFER_SIZE (audpad->auds_codec_data); @@ -1072,6 +1113,42 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux) buffdata += codec_size; highmark += codec_size; } + + /* add video property data, mainly for aspect ratio, if any */ + if (vprp_size) { + gint f; + + /* the vprp header */ + memcpy (buffdata + 0, "vprp", 4); + GST_WRITE_UINT32_LE (buffdata + 4, vprp_size); + /* the actual data */ + GST_WRITE_UINT32_LE (buffdata + 8, vidpad->vprp.format_token); + GST_WRITE_UINT32_LE (buffdata + 12, vidpad->vprp.standard); + GST_WRITE_UINT32_LE (buffdata + 16, vidpad->vprp.vert_rate); + GST_WRITE_UINT32_LE (buffdata + 20, vidpad->vprp.hor_t_total); + GST_WRITE_UINT32_LE (buffdata + 24, vidpad->vprp.vert_lines); + GST_WRITE_UINT32_LE (buffdata + 28, vidpad->vprp.aspect); + GST_WRITE_UINT32_LE (buffdata + 32, vidpad->vprp.width); + GST_WRITE_UINT32_LE (buffdata + 36, vidpad->vprp.height); + GST_WRITE_UINT32_LE (buffdata + 40, vidpad->vprp.fields); + buffdata += codec_size + 44; + highmark += codec_size + 44; + for (f = 0; f < vidpad->vprp.fields; ++f) { + gst_riff_vprp_video_field_desc *fd; + + fd = &(vidpad->vprp.field_info[f]); + GST_WRITE_UINT32_LE (buffdata + 0, fd->compressed_bm_height); + GST_WRITE_UINT32_LE (buffdata + 4, fd->compressed_bm_width); + GST_WRITE_UINT32_LE (buffdata + 8, fd->valid_bm_height); + GST_WRITE_UINT32_LE (buffdata + 12, fd->valid_bm_width); + GST_WRITE_UINT32_LE (buffdata + 16, fd->valid_bm_x_offset); + GST_WRITE_UINT32_LE (buffdata + 20, fd->valid_bm_y_offset); + GST_WRITE_UINT32_LE (buffdata + 24, fd->video_x_t_offset); + GST_WRITE_UINT32_LE (buffdata + 28, fd->video_y_start); + buffdata += codec_size + 32; + highmark += codec_size + 32; + } + } } else { /* the audio header */ memcpy (buffdata + 0, "strf", 4); |