mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-21 07:46:38 +00:00
qtmux: add ima adpcm support
This commit is contained in:
parent
405872f69d
commit
dd8d704bb9
5 changed files with 99 additions and 0 deletions
|
@ -3337,3 +3337,74 @@ build_SMI_atom (const GstBuffer * seqh)
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static AtomInfo *
|
||||||
|
build_ima_adpcm_atom (gint channels, gint rate, gint blocksize)
|
||||||
|
{
|
||||||
|
AtomData *atom_data;
|
||||||
|
GstBuffer *buf;
|
||||||
|
guint8 *data;
|
||||||
|
const gint ima_adpcm_atom_size = 20;
|
||||||
|
guint32 fourcc;
|
||||||
|
gint samplesperblock;
|
||||||
|
gint bytespersec;
|
||||||
|
|
||||||
|
/* The FOURCC for WAV codecs in QT is 'ms' followed by the 16 bit wave codec
|
||||||
|
identifier. Note that the identifier here is big-endian, but when used
|
||||||
|
within the WAVE header (below), it's little endian. */
|
||||||
|
fourcc = MS_WAVE_FOURCC (0x11);
|
||||||
|
|
||||||
|
buf = gst_buffer_new_and_alloc (ima_adpcm_atom_size);
|
||||||
|
data = GST_BUFFER_DATA (buf);
|
||||||
|
|
||||||
|
/* This atom's content is a WAVE header, including 2 bytes of extra data.
|
||||||
|
Note that all of this is little-endian, unlike most stuff in qt. */
|
||||||
|
samplesperblock = 2 * blocksize / channels - 7;
|
||||||
|
bytespersec = rate * blocksize / samplesperblock;
|
||||||
|
GST_WRITE_UINT16_LE (data, 0x11);
|
||||||
|
GST_WRITE_UINT16_LE (data + 2, channels);
|
||||||
|
GST_WRITE_UINT32_LE (data + 4, rate);
|
||||||
|
GST_WRITE_UINT32_LE (data + 8, bytespersec);
|
||||||
|
GST_WRITE_UINT16_LE (data + 12, blocksize);
|
||||||
|
GST_WRITE_UINT16_LE (data + 14, 4);
|
||||||
|
GST_WRITE_UINT16_LE (data + 16, 2); /* Two extra bytes */
|
||||||
|
GST_WRITE_UINT16_LE (data + 18, samplesperblock);
|
||||||
|
|
||||||
|
atom_data = atom_data_new_from_gst_buffer (fourcc, buf);
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
|
return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
|
||||||
|
atom_data_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomInfo *
|
||||||
|
build_ima_adpcm_extension (gint channels, gint rate, gint blocksize)
|
||||||
|
{
|
||||||
|
AtomWAVE *wave;
|
||||||
|
AtomFRMA *frma;
|
||||||
|
Atom *ext_atom;
|
||||||
|
|
||||||
|
/* Add WAVE atom */
|
||||||
|
wave = atom_wave_new ();
|
||||||
|
|
||||||
|
/* Prepend Terminator atom to the WAVE list first, so it ends up last */
|
||||||
|
ext_atom = (Atom *) atom_data_new (FOURCC_null);
|
||||||
|
wave->extension_atoms =
|
||||||
|
atom_info_list_prepend_atom (wave->extension_atoms, (Atom *) ext_atom,
|
||||||
|
(AtomCopyDataFunc) atom_data_copy_data, (AtomFreeFunc) atom_data_free);
|
||||||
|
|
||||||
|
/* Add wave ima adpcm atom to WAVE */
|
||||||
|
wave->extension_atoms = g_list_prepend (wave->extension_atoms,
|
||||||
|
build_ima_adpcm_atom (channels, rate, blocksize));
|
||||||
|
|
||||||
|
/* Add FRMA to the WAVE */
|
||||||
|
frma = atom_frma_new ();
|
||||||
|
frma->media_type = MS_WAVE_FOURCC (0x11);
|
||||||
|
|
||||||
|
wave->extension_atoms =
|
||||||
|
atom_info_list_prepend_atom (wave->extension_atoms, (Atom *) frma,
|
||||||
|
(AtomCopyDataFunc) atom_frma_copy_data, (AtomFreeFunc) atom_frma_free);
|
||||||
|
|
||||||
|
return build_atom_info_wrapper ((Atom *) wave, atom_wave_copy_data,
|
||||||
|
atom_wave_free);
|
||||||
|
}
|
||||||
|
|
|
@ -675,6 +675,8 @@ AtomInfo * build_amr_extension ();
|
||||||
AtomInfo * build_h263_extension ();
|
AtomInfo * build_h263_extension ();
|
||||||
AtomInfo * build_gama_atom (gdouble gamma);
|
AtomInfo * build_gama_atom (gdouble gamma);
|
||||||
AtomInfo * build_SMI_atom (const GstBuffer *seqh);
|
AtomInfo * build_SMI_atom (const GstBuffer *seqh);
|
||||||
|
AtomInfo * build_ima_adpcm_extension (gint channels, gint rate,
|
||||||
|
gint blocksize);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -196,6 +196,11 @@ G_BEGIN_DECLS
|
||||||
#define FOURCC_loci GST_MAKE_FOURCC('l','o','c','i')
|
#define FOURCC_loci GST_MAKE_FOURCC('l','o','c','i')
|
||||||
#define FOURCC_kywd GST_MAKE_FOURCC('k','y','w','d')
|
#define FOURCC_kywd GST_MAKE_FOURCC('k','y','w','d')
|
||||||
|
|
||||||
|
/* For Microsoft Wave formats embedded in quicktime, the FOURCC is
|
||||||
|
'm', 's', then the 16 bit wave codec id */
|
||||||
|
#define MS_WAVE_FOURCC(codecid) GST_MAKE_FOURCC( \
|
||||||
|
'm', 's', ((codecid)>>8)&0xff, ((codecid)&0xff))
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __FOURCC_H__ */
|
#endif /* __FOURCC_H__ */
|
||||||
|
|
|
@ -1717,6 +1717,19 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps)
|
||||||
entry.fourcc = FOURCC_ulaw;
|
entry.fourcc = FOURCC_ulaw;
|
||||||
entry.samples_per_packet = 1023;
|
entry.samples_per_packet = 1023;
|
||||||
entry.bytes_per_sample = 2;
|
entry.bytes_per_sample = 2;
|
||||||
|
} else if (strcmp (mimetype, "audio/x-adpcm") == 0) {
|
||||||
|
gint blocksize;
|
||||||
|
if (!gst_structure_get_int (structure, "block_align", &blocksize)) {
|
||||||
|
GST_DEBUG_OBJECT (qtmux, "broken caps, block_align missing");
|
||||||
|
goto refuse_caps;
|
||||||
|
}
|
||||||
|
// Currently only supports WAV-style IMA ADPCM, for which the codec id is
|
||||||
|
// 0x11
|
||||||
|
entry.fourcc = MS_WAVE_FOURCC (0x11);
|
||||||
|
entry.samples_per_packet = 2 * blocksize / channels - 7;
|
||||||
|
entry.bytes_per_sample = 2;
|
||||||
|
|
||||||
|
ext_atom = build_ima_adpcm_extension (channels, rate, blocksize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!entry.fourcc)
|
if (!entry.fourcc)
|
||||||
|
|
|
@ -129,6 +129,13 @@
|
||||||
"rate = (int) 16000, " \
|
"rate = (int) 16000, " \
|
||||||
"channels = [ 1, 2 ] "
|
"channels = [ 1, 2 ] "
|
||||||
|
|
||||||
|
#define ADPCM_CAPS \
|
||||||
|
"audio/x-adpcm, " \
|
||||||
|
"layout = (string)dvi, " \
|
||||||
|
"block_align = (int)[64, 8096], " \
|
||||||
|
COMMON_AUDIO_CAPS(2, MAX)
|
||||||
|
|
||||||
|
|
||||||
/* FIXME 0.11 - take a look at bugs #580005 and #340375 */
|
/* FIXME 0.11 - take a look at bugs #580005 and #340375 */
|
||||||
GstQTMuxFormatProp gst_qt_mux_format_list[] = {
|
GstQTMuxFormatProp gst_qt_mux_format_list[] = {
|
||||||
/* original QuickTime format; see Apple site (e.g. qtff.pdf) */
|
/* original QuickTime format; see Apple site (e.g. qtff.pdf) */
|
||||||
|
@ -156,6 +163,7 @@ GstQTMuxFormatProp gst_qt_mux_format_list[] = {
|
||||||
GST_STATIC_CAPS (PCM_CAPS_FULL "; "
|
GST_STATIC_CAPS (PCM_CAPS_FULL "; "
|
||||||
MP3_CAPS " ; "
|
MP3_CAPS " ; "
|
||||||
AAC_CAPS " ; "
|
AAC_CAPS " ; "
|
||||||
|
ADPCM_CAPS " ; "
|
||||||
"audio/x-alaw, " COMMON_AUDIO_CAPS (2, MAX) "; " AMR_CAPS)
|
"audio/x-alaw, " COMMON_AUDIO_CAPS (2, MAX) "; " AMR_CAPS)
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
|
|
Loading…
Reference in a new issue