qtmux (and variants): handle pixel-aspect-ratio. Fixes #584358.
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Mon, 1 Jun 2009 21:00:44 +0000 (23:00 +0200)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Tue, 12 Apr 2011 19:32:12 +0000 (20:32 +0100)
gst/quicktime/atoms.c
gst/quicktime/atoms.h
gst/quicktime/fourcc.h
gst/quicktime/gstqtmux.c

index 47db40c..2ce8631 100644 (file)
@@ -2804,14 +2804,56 @@ atom_trak_set_audio_type (AtomTRAK * trak, AtomsContext * context,
   atom_trak_set_constant_size_samples (trak, sample_size);
 }
 
+AtomInfo *
+build_pasp_extension (AtomTRAK * trak, gint par_width, gint par_height)
+{
+  AtomData *atom_data;
+  GstBuffer *buf;
+  guint8 *data;
+
+  buf = gst_buffer_new_and_alloc (8);
+  data = GST_BUFFER_DATA (buf);
+
+  /* ihdr = image header box */
+  GST_WRITE_UINT32_BE (data, par_width);
+  GST_WRITE_UINT32_BE (data + 4, par_height);
+
+  atom_data = atom_data_new_from_gst_buffer (FOURCC_pasp, buf);
+  gst_buffer_unref (buf);
+
+  return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
+      atom_data_free);
+}
+
 void
 atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
     VisualSampleEntry * entry, guint32 scale, AtomInfo * ext)
 {
   SampleTableEntryMP4V *ste;
+  gint dwidth, dheight;
+  gint par_n = 0, par_d = 0;
+
+  if ((entry->par_n != 1 || entry->par_d != 1) &&
+      (entry->par_n != entry->par_d)) {
+    par_n = entry->par_n;
+    par_d = entry->par_d;
+  }
+
+  dwidth = entry->width;
+  dheight = entry->height;
+  /* ISO file spec says track header w/h indicates track's visual presentation
+   * (so this together with pixels w/h implicitly defines PAR) */
+  if (par_n && (context->flavor == ATOMS_TREE_FLAVOR_ISOM)) {
+    if (par_n > par_d) {
+      dwidth = entry->width * par_n / par_d;
+      dheight = entry->height;
+    } else {
+      dwidth = entry->width * par_n / par_d;
+      dheight = entry->height;
+    }
+  }
 
-  atom_trak_set_video_commons (trak, context, scale, entry->width,
-      entry->height);
+  atom_trak_set_video_commons (trak, context, scale, dwidth, dheight);
   ste = atom_trak_add_video_entry (trak, context, entry->fourcc);
 
   trak->is_video = TRUE;
@@ -2825,6 +2867,12 @@ atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
 
   if (ext)
     ste->extension_atoms = g_list_prepend (ste->extension_atoms, ext);
+
+  /* QT spec has a pasp extension atom in stsd that can hold PAR */
+  if (par_n && (context->flavor == ATOMS_TREE_FLAVOR_MOV)) {
+    ste->extension_atoms = g_list_append (ste->extension_atoms,
+        build_pasp_extension (trak, par_n, par_d));
+  }
 }
 
 /* some sample description construction helpers */
index 23bc19b..0bf3f20 100644 (file)
@@ -602,6 +602,8 @@ typedef struct
   guint depth;
   guint frame_count;
   gint color_table_id;
+  guint par_n;
+  guint par_d;
 
   GstBuffer *codec_data;
 } VisualSampleEntry;
index 3db6003..d61075b 100644 (file)
@@ -104,6 +104,7 @@ G_BEGIN_DECLS
 #define FOURCC_wave     GST_MAKE_FOURCC('w','a','v','e')
 #define FOURCC_appl     GST_MAKE_FOURCC('a','p','p','l')
 #define FOURCC_esds     GST_MAKE_FOURCC('e','s','d','s')
+#define FOURCC_pasp     GST_MAKE_FOURCC('p','a','s','p')
 #define FOURCC_hnti     GST_MAKE_FOURCC('h','n','t','i')
 #define FOURCC_rtp_     GST_MAKE_FOURCC('r','t','p',' ')
 #define FOURCC_sdp_     GST_MAKE_FOURCC('s','d','p',' ')
index 03b0a1a..913bfc3 100644 (file)
@@ -1464,7 +1464,6 @@ gst_qt_mux_video_sink_set_caps (GstPad * pad, GstCaps * caps)
   par_den = 1;
   gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_num,
       &par_den);
-  /* FIXME: pixel-aspect-ratio */
 
   qtpad->is_out_of_order = FALSE;
 
@@ -1477,6 +1476,8 @@ gst_qt_mux_video_sink_set_caps (GstPad * pad, GstCaps * caps)
   /* set common properties */
   entry.width = width;
   entry.height = height;
+  entry.par_n = par_num;
+  entry.par_d = par_den;
   /* should be OK according to qt and iso spec, override if really needed */
   entry.color_table_id = -1;
   entry.frame_count = 1;