mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
qtmux: Write tapt atom for MOV files if PAR not 1/1
Needed for QuickTime 7 to properly play files. Also write the clap atom for MOV files always, not only when ProRes is used as a video codec. It's mandatory for MOV. https://bugzilla.gnome.org/show_bug.cgi?id=777100
This commit is contained in:
parent
1cad7108b7
commit
e12c94065d
5 changed files with 88 additions and 19 deletions
|
@ -2813,6 +2813,11 @@ atom_trak_copy_data (AtomTRAK * trak, guint8 ** buffer, guint64 * size,
|
|||
if (!atom_tkhd_copy_data (&trak->tkhd, buffer, size, offset)) {
|
||||
return 0;
|
||||
}
|
||||
if (trak->tapt) {
|
||||
if (!trak->tapt->copy_data_func (trak->tapt->atom, buffer, size, offset)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (trak->edts) {
|
||||
if (!atom_edts_copy_data (trak->edts, buffer, size, offset)) {
|
||||
return 0;
|
||||
|
@ -4097,6 +4102,39 @@ build_clap_extension (gint width_n, gint width_d, gint height_n, gint height_d,
|
|||
atom_data_free);
|
||||
}
|
||||
|
||||
AtomInfo *
|
||||
build_tapt_extension (gint clef_width, gint clef_height, gint prof_width,
|
||||
gint prof_height, gint enof_width, gint enof_height)
|
||||
{
|
||||
AtomData *atom_data = atom_data_new (FOURCC_tapt);
|
||||
guint8 *data;
|
||||
|
||||
atom_data_alloc_mem (atom_data, 60);
|
||||
data = atom_data->data;
|
||||
|
||||
GST_WRITE_UINT32_BE (data, 20);
|
||||
GST_WRITE_UINT32_LE (data + 4, FOURCC_clef);
|
||||
GST_WRITE_UINT32_BE (data + 8, 0);
|
||||
GST_WRITE_UINT32_BE (data + 12, clef_width);
|
||||
GST_WRITE_UINT32_BE (data + 16, clef_height);
|
||||
|
||||
GST_WRITE_UINT32_BE (data + 20, 20);
|
||||
GST_WRITE_UINT32_LE (data + 24, FOURCC_prof);
|
||||
GST_WRITE_UINT32_BE (data + 28, 0);
|
||||
GST_WRITE_UINT32_BE (data + 32, prof_width);
|
||||
GST_WRITE_UINT32_BE (data + 36, prof_height);
|
||||
|
||||
GST_WRITE_UINT32_BE (data + 40, 20);
|
||||
GST_WRITE_UINT32_LE (data + 44, FOURCC_enof);
|
||||
GST_WRITE_UINT32_BE (data + 48, 0);
|
||||
GST_WRITE_UINT32_BE (data + 52, enof_width);
|
||||
GST_WRITE_UINT32_BE (data + 56, enof_height);
|
||||
|
||||
|
||||
return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
|
||||
atom_data_free);
|
||||
}
|
||||
|
||||
SampleTableEntryMP4V *
|
||||
atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
|
||||
VisualSampleEntry * entry, guint32 scale, GList * ext_atoms_list)
|
||||
|
|
|
@ -113,6 +113,8 @@ void atoms_context_free (AtomsContext *context);
|
|||
|
||||
/* atom defs and functions */
|
||||
|
||||
typedef struct _AtomInfo AtomInfo;
|
||||
|
||||
/*
|
||||
* Used for storing time related values for some atoms.
|
||||
*/
|
||||
|
@ -701,6 +703,7 @@ typedef struct _AtomTRAK
|
|||
Atom header;
|
||||
|
||||
AtomTKHD tkhd;
|
||||
AtomInfo *tapt;
|
||||
AtomEDTS *edts;
|
||||
AtomMDIA mdia;
|
||||
AtomUDTA udta;
|
||||
|
@ -893,13 +896,12 @@ typedef guint64 (*AtomFreeFunc) (Atom *atom);
|
|||
* All we need are the two functions (copying it to an array
|
||||
* for serialization and the memory releasing function).
|
||||
*/
|
||||
typedef struct _AtomInfo
|
||||
struct _AtomInfo
|
||||
{
|
||||
Atom *atom;
|
||||
AtomCopyDataFunc copy_data_func;
|
||||
AtomFreeFunc free_func;
|
||||
} AtomInfo;
|
||||
|
||||
};
|
||||
|
||||
guint64 atom_copy_data (Atom *atom, guint8 **buffer,
|
||||
guint64 *size, guint64* offset);
|
||||
|
@ -1056,6 +1058,9 @@ AtomInfo * build_jp2x_extension (const GstBuffer * prefix);
|
|||
AtomInfo * build_fiel_extension (GstVideoInterlaceMode mode, GstVideoFieldOrder order);
|
||||
AtomInfo * build_colr_extension (const GstVideoColorimetry *colorimetry, gboolean is_mp4);
|
||||
AtomInfo * build_clap_extension (gint width_n, gint width_d, gint height_n, gint height_d, gint h_off_n, gint h_off_d, gint v_off_n, gint v_off_d);
|
||||
AtomInfo * build_tapt_extension (gint clef_width, gint clef_height, gint prof_width, gint prof_height, gint enof_width, gint enof_height);
|
||||
|
||||
|
||||
AtomInfo * build_ac3_extension (guint8 fscod, guint8 bsid,
|
||||
guint8 bsmod, guint8 acmod,
|
||||
guint8 lfe_on, guint8 bitrate_code);
|
||||
|
|
|
@ -179,6 +179,10 @@ G_BEGIN_DECLS
|
|||
#define FOURCC_pasp GST_MAKE_FOURCC('p','a','s','p')
|
||||
#define FOURCC_colr GST_MAKE_FOURCC('c','o','l','r')
|
||||
#define FOURCC_clap GST_MAKE_FOURCC('c','l','a','p')
|
||||
#define FOURCC_tapt GST_MAKE_FOURCC('t','a','p','t')
|
||||
#define FOURCC_clef GST_MAKE_FOURCC('c','l','e','f')
|
||||
#define FOURCC_prof GST_MAKE_FOURCC('p','r','o','f')
|
||||
#define FOURCC_enof GST_MAKE_FOURCC('e','n','o','f')
|
||||
#define FOURCC_fiel GST_MAKE_FOURCC('f','i','e','l')
|
||||
#define FOURCC_pcst GST_MAKE_FOURCC('p','c','s','t')
|
||||
#define FOURCC_pgap GST_MAKE_FOURCC('p','g','a','p')
|
||||
|
|
|
@ -4415,6 +4415,43 @@ gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps)
|
|||
ext_atom_list = g_list_append (ext_atom_list, ext_atom);
|
||||
}
|
||||
|
||||
|
||||
if (qtmux_klass->format == GST_QT_MUX_FORMAT_QT) {
|
||||
/* The 'clap' extension is also defined for MP4 but inventing values in
|
||||
* general seems a bit tricky for this one. We only write it for MOV
|
||||
* then, where it is a requirement.
|
||||
* The same goes for the 'tapt' extension, just that it is not defined for
|
||||
* MP4 and only for MOV
|
||||
*
|
||||
* NTSC and PAL have special values, otherwise just take width and height
|
||||
*/
|
||||
if (width == 720 && (height == 480 || height == 486)) {
|
||||
ext_atom = build_clap_extension (704, 1, height, 1, 0, 1, 0, 1);
|
||||
if (ext_atom)
|
||||
ext_atom_list = g_list_append (ext_atom_list, ext_atom);
|
||||
|
||||
} else if (width == 720 && height == 576) {
|
||||
ext_atom = build_clap_extension (768 * 54, 59, 576, 1, 0, 1, 0, 1);
|
||||
if (ext_atom)
|
||||
ext_atom_list = g_list_append (ext_atom_list, ext_atom);
|
||||
} else {
|
||||
ext_atom = build_clap_extension (width, 1, height, 1, 0, 1, 0, 1);
|
||||
if (ext_atom)
|
||||
ext_atom_list = g_list_append (ext_atom_list, ext_atom);
|
||||
}
|
||||
|
||||
if (par_num != par_den) {
|
||||
gint clef_width =
|
||||
gst_util_uint64_scale (width, par_num * G_GUINT64_CONSTANT (65536),
|
||||
par_den);
|
||||
|
||||
ext_atom =
|
||||
build_tapt_extension (clef_width, height << 16, clef_width,
|
||||
height << 16, width << 16, height << 16);
|
||||
qtpad->trak->tapt = ext_atom;
|
||||
}
|
||||
}
|
||||
|
||||
/* ok, set the pad info accordingly */
|
||||
qtpad->fourcc = entry.fourcc;
|
||||
qtpad->sync = sync;
|
||||
|
@ -4457,22 +4494,6 @@ gst_qt_mux_video_sink_set_caps (GstQTPad * qtpad, GstCaps * caps)
|
|||
strcpy ((gchar *) mp4v->compressor + 1, compressor);
|
||||
mp4v->compressor[0] = strlen (compressor);
|
||||
}
|
||||
|
||||
/* The 'clap' extension is also defined for MP4 but inventing values in
|
||||
* general seems a bit tricky for this one. We only write it for ProRes
|
||||
* then, where it is a requirement.
|
||||
*
|
||||
* NTSC and PAL have special values, otherwise just take width and height
|
||||
*/
|
||||
if (width == 720 && (height == 480 || height == 486))
|
||||
ext_atom = build_clap_extension (704, 1, height, 1, 0, 1, 0, 1);
|
||||
else if (width == 720 && height == 576)
|
||||
ext_atom = build_clap_extension (768 * 54, 59, 576, 1, 0, 1, 0, 1);
|
||||
else
|
||||
ext_atom = build_clap_extension (width, 1, height, 1, 0, 1, 0, 1);
|
||||
|
||||
if (ext_atom)
|
||||
mp4v->extension_atoms = g_list_append (mp4v->extension_atoms, ext_atom);
|
||||
}
|
||||
|
||||
gst_object_unref (qtmux);
|
||||
|
|
|
@ -85,6 +85,7 @@ static const QtNodeType qt_node_types[] = {
|
|||
{FOURCC_jp2h, "jp2h", QT_FLAG_CONTAINER,},
|
||||
{FOURCC_colr, "colr", 0,},
|
||||
{FOURCC_clap, "clap", 0,},
|
||||
{FOURCC_tapt, "tapt", 0,},
|
||||
{FOURCC_ihdr, "ihdr", 0,},
|
||||
{FOURCC_fiel, "fiel", 0,},
|
||||
{FOURCC_jp2x, "jp2x", 0,},
|
||||
|
|
Loading…
Reference in a new issue