void
atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
- VisualSampleEntry * entry, guint32 scale, AtomInfo * ext)
+ VisualSampleEntry * entry, guint32 scale, GList * ext_atoms_list)
{
SampleTableEntryMP4V *ste;
gint dwidth, dheight;
trak->is_video = TRUE;
trak->is_h264 = (entry->fourcc == FOURCC_avc1);
+ ste->version = entry->version;
ste->width = entry->width;
ste->height = entry->height;
ste->depth = entry->depth;
ste->color_table_id = entry->color_table_id;
ste->frame_count = entry->frame_count;
- if (ext)
- ste->extension_atoms = g_list_prepend (ste->extension_atoms, ext);
+ if (ext_atoms_list)
+ ste->extension_atoms = g_list_concat (ste->extension_atoms, ext_atoms_list);
/* QT spec has a pasp extension atom in stsd that can hold PAR */
if (par_n && (context->flavor == ATOMS_TREE_FLAVOR_MOV)) {
gst_buffer_unref (buf);
return res;
}
+
+AtomInfo *
+build_gama_atom (gdouble gamma)
+{
+ AtomInfo *res;
+ guint32 gamma_fp;
+ GstBuffer *buf;
+
+ /* convert to uint32 from fixed point */
+ gamma_fp = (guint32) 65536 *gamma;
+
+ buf = gst_buffer_new_and_alloc (4);
+ GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), gamma_fp);
+ res = build_codec_data_extension (FOURCC_gama, buf);
+ gst_buffer_unref (buf);
+ return res;
+}
+
+AtomInfo *
+build_SMI_atom (const GstBuffer * seqh)
+{
+ AtomInfo *res;
+ GstBuffer *buf;
+
+ /* the seqh plus its size and fourcc */
+ buf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (seqh) + 8);
+
+ GST_WRITE_UINT32_LE (GST_BUFFER_DATA (buf), FOURCC_SEQH);
+ GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf) + 4, GST_BUFFER_SIZE (seqh));
+ memcpy (GST_BUFFER_DATA (buf) + 8, GST_BUFFER_DATA (seqh),
+ GST_BUFFER_SIZE (seqh));
+ res = build_codec_data_extension (FOURCC_SMI_, buf);
+ gst_buffer_unref (buf);
+ return res;
+}
typedef struct
{
+ guint16 version;
guint32 fourcc;
guint width;
guint height;
void atom_trak_set_audio_type (AtomTRAK * trak, AtomsContext * context,
AudioSampleEntry * entry, guint32 scale,
AtomInfo * ext, gint sample_size);
+
void atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
VisualSampleEntry * entry, guint32 rate,
- AtomInfo * ext);
+ 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);
guint32 fourcc);
AtomInfo * build_amr_extension ();
AtomInfo * build_h263_extension ();
+AtomInfo * build_gama_atom (gdouble gamma);
+AtomInfo * build_SMI_atom (const GstBuffer *seqh);
/*
#define FOURCC_jpeg GST_MAKE_FOURCC('j','p','e','g')
#define FOURCC_mjp2 GST_MAKE_FOURCC('m','j','p','2')
#define FOURCC_jp2h GST_MAKE_FOURCC('j','p','2','h')
+#define FOURCC_gama GST_MAKE_FOURCC('g','a','m','a')
+
+/* SVQ3 fourcc */
+#define FOURCC_SEQH GST_MAKE_FOURCC('S','E','Q','H')
+#define FOURCC_SMI_ GST_MAKE_FOURCC('S','M','I',' ')
/* Xiph fourcc */
#define FOURCC_XiTh GST_MAKE_FOURCC('X','i','T','h')
VisualSampleEntry entry = { 0, };
GstQTMuxFormat format;
AtomInfo *ext_atom = NULL;
+ GList *ext_atom_list = NULL;
gboolean sync = FALSE;
int par_num, par_den;
break;
}
} else if (strcmp (mimetype, "video/x-h263") == 0) {
+ ext_atom = NULL;
if (format == GST_QT_MUX_FORMAT_QT)
entry.fourcc = FOURCC_h263;
else
entry.fourcc = FOURCC_s263;
ext_atom = build_h263_extension ();
+ if (ext_atom != NULL)
+ ext_atom_list = g_list_prepend (ext_atom_list, ext_atom);
} else if (strcmp (mimetype, "video/x-divx") == 0 ||
strcmp (mimetype, "video/mpeg") == 0) {
gint version = 0;
ext_atom =
build_esds_extension (qtpad->trak, ESDS_OBJECT_TYPE_MPEG4_P2,
ESDS_STREAM_TYPE_VISUAL, codec_data);
+ if (ext_atom != NULL)
+ ext_atom_list = g_list_prepend (ext_atom_list, ext_atom);
if (!codec_data)
GST_WARNING_OBJECT (qtmux, "no codec_data for MPEG4 video; "
"output might not play in Apple QuickTime (try global-headers?)");
if (!codec_data)
GST_WARNING_OBJECT (qtmux, "no codec_data in h264 caps");
ext_atom = build_codec_data_extension (FOURCC_avcC, codec_data);
+ if (ext_atom != NULL)
+ ext_atom_list = g_list_prepend (ext_atom_list, ext_atom);
+ } else if (strcmp (mimetype, "video/x-svq") == 0) {
+ gint version = 0;
+ const GstBuffer *seqh = NULL;
+ const GValue *seqh_value;
+ gdouble gamma = 0;
+
+ gst_structure_get_int (structure, "svqversion", &version);
+ if (version == 3) {
+ entry.fourcc = FOURCC_SVQ3;
+ entry.version = 3;
+ entry.depth = 32;
+ qtpad->is_out_of_order = TRUE;
+
+ seqh_value = gst_structure_get_value (structure, "seqh");
+ if (seqh_value) {
+ seqh = gst_value_get_buffer (seqh_value);
+ ext_atom = build_SMI_atom (seqh);
+ if (ext_atom)
+ ext_atom_list = g_list_prepend (ext_atom_list, ext_atom);
+ }
+
+ /* we need to add the gamma anyway because quicktime might crash
+ * when it doesn't find it */
+ if (!gst_structure_get_double (structure, "applied-gamma", &gamma)) {
+ /* it seems that using 0 here makes it ignored */
+ gamma = 0.0;
+ }
+ ext_atom = build_gama_atom (gamma);
+ if (ext_atom)
+ ext_atom_list = g_list_prepend (ext_atom_list, ext_atom);
+ } else {
+ GST_WARNING_OBJECT (qtmux, "SVQ version %d not supported. Please file "
+ "a bug at http://bugzilla.gnome.org", version);
+ }
} else if (strcmp (mimetype, "video/x-dv") == 0) {
gint version = 0;
gboolean pal = TRUE;
} else if (strcmp (mimetype, "image/x-j2c") == 0) {
guint32 fourcc;
+ ext_atom = NULL;
entry.fourcc = FOURCC_mjp2;
sync = FALSE;
if (!gst_structure_get_fourcc (structure, "fourcc", &fourcc) ||
GST_DEBUG_OBJECT (qtmux, "missing or invalid fourcc in jp2 caps");
goto refuse_caps;
}
+ if (ext_atom)
+ ext_atom_list = g_list_prepend (ext_atom_list, ext_atom);
} else if (strcmp (mimetype, "video/x-qt-part") == 0) {
guint32 fourcc;
qtpad->fourcc = entry.fourcc;
qtpad->sync = sync;
atom_trak_set_video_type (qtpad->trak, qtmux->context, &entry, rate,
- ext_atom);
+ ext_atom_list);
gst_object_unref (qtmux);
return TRUE;
"divxversion = (int) 5, "\
COMMON_VIDEO_CAPS
+#define SVQ_CAPS \
+ "video/x-svq, " \
+ "svqversion = (int) 3, " \
+ COMMON_VIDEO_CAPS
+
#define COMMON_AUDIO_CAPS(c, r) \
"channels = (int) [ 1, " G_STRINGIFY (c) " ], " \
"rate = (int) [ 1, " G_STRINGIFY (r) " ]"
MPEG4V_CAPS "; "
H263_CAPS "; "
H264_CAPS "; "
+ SVQ_CAPS "; "
"video/x-dv, "
"systemstream = (boolean) false, "
COMMON_VIDEO_CAPS "; "