isomp4: port to 0.11

This commit is contained in:
Mark Nauwelaerts 2011-06-29 12:46:20 +02:00
parent 65bb271a95
commit f886681367
10 changed files with 514 additions and 424 deletions

View file

@ -6,6 +6,7 @@ libgstisomp4_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) \
-lgstriff-@GST_MAJORMINOR@ \
-lgstaudio-@GST_MAJORMINOR@ \
-lgstvideo-@GST_MAJORMINOR@ \
-lgstrtp-@GST_MAJORMINOR@ \
-lgsttag-@GST_MAJORMINOR@ \
-lgstpbutils-@GST_MAJORMINOR@ \

View file

@ -206,9 +206,10 @@ static AtomData *
atom_data_new_from_gst_buffer (guint32 fourcc, const GstBuffer * buf)
{
AtomData *data = atom_data_new (fourcc);
gsize size = gst_buffer_get_size ((GstBuffer *) buf);
atom_data_alloc_mem (data, GST_BUFFER_SIZE (buf));
g_memmove (data->data, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
atom_data_alloc_mem (data, size);
gst_buffer_extract ((GstBuffer *) buf, 0, data->data, size);
return data;
}
@ -2825,6 +2826,19 @@ atom_moov_add_uint_tag (AtomMOOV * moov, guint32 fourcc, guint32 flags,
}
}
static GstBuffer *
_gst_buffer_new_wrapped (gpointer mem, gsize size, GFreeFunc free_func)
{
GstBuffer *buf;
buf = gst_buffer_new ();
gst_buffer_take_memory (buf, -1,
gst_memory_new_wrapped (free_func ? 0 : GST_MEMORY_FLAG_READONLY,
mem, free_func, size, 0, size));
return buf;
}
void
atom_moov_add_blob_tag (AtomMOOV * moov, guint8 * data, guint size)
{
@ -2843,10 +2857,7 @@ atom_moov_add_blob_tag (AtomMOOV * moov, guint8 * data, guint size)
if (len > size)
return;
buf = gst_buffer_new ();
GST_BUFFER_SIZE (buf) = len - 8;
GST_BUFFER_DATA (buf) = data + 8;
buf = _gst_buffer_new_wrapped (data + 8, len - 8, NULL);
data_atom = atom_data_new_from_gst_buffer (fourcc, buf);
gst_buffer_unref (buf);
@ -2864,12 +2875,12 @@ atom_moov_add_3gp_tag (AtomMOOV * moov, guint32 fourcc, guint8 * data,
guint8 *bdata;
/* need full atom */
buf = gst_buffer_new_and_alloc (size + 4);
bdata = GST_BUFFER_DATA (buf);
bdata = g_malloc (size + 4);
/* full atom: version and flags */
GST_WRITE_UINT32_BE (bdata, 0);
memcpy (bdata + 4, data, size);
buf = _gst_buffer_new_wrapped (bdata, size + 4, g_free);
data_atom = atom_data_new_from_gst_buffer (fourcc, buf);
gst_buffer_unref (buf);
@ -3188,13 +3199,12 @@ build_pasp_extension (AtomTRAK * trak, gint par_width, gint par_height)
GstBuffer *buf;
guint8 *data;
buf = gst_buffer_new_and_alloc (8);
data = GST_BUFFER_DATA (buf);
data = g_malloc (8);
/* ihdr = image header box */
GST_WRITE_UINT32_BE (data, par_width);
GST_WRITE_UINT32_BE (data + 4, par_height);
buf = _gst_buffer_new_wrapped (data, 8, g_free);
atom_data = atom_data_new_from_gst_buffer (FOURCC_pasp, buf);
gst_buffer_unref (buf);
@ -3942,13 +3952,13 @@ build_esds_extension (AtomTRAK * trak, guint8 object_type, guint8 stream_type,
/* optional DecoderSpecificInfo */
if (codec_data) {
DecoderSpecificInfoDescriptor *desc;
gsize size;
esds->es.dec_conf_desc.dec_specific_info = desc =
desc_dec_specific_info_new ();
desc_dec_specific_info_alloc_data (desc, GST_BUFFER_SIZE (codec_data));
memcpy (desc->data, GST_BUFFER_DATA (codec_data),
GST_BUFFER_SIZE (codec_data));
size = gst_buffer_get_size ((GstBuffer *) codec_data);
desc_dec_specific_info_alloc_data (desc, size);
gst_buffer_extract ((GstBuffer *) codec_data, 0, desc->data, size);
}
return build_atom_info_wrapper ((Atom *) esds, atom_esds_copy_data,
@ -3961,16 +3971,17 @@ build_btrt_extension (guint32 buffer_size_db, guint32 avg_bitrate,
{
AtomData *atom_data;
GstBuffer *buf;
guint8 *data;
if (buffer_size_db == 0 && avg_bitrate == 0 && max_bitrate == 0)
return 0;
buf = gst_buffer_new_and_alloc (12);
GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), buffer_size_db);
GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf) + 4, max_bitrate);
GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf) + 8, avg_bitrate);
data = g_malloc (12);
GST_WRITE_UINT32_BE (data, buffer_size_db);
GST_WRITE_UINT32_BE (data + 4, max_bitrate);
GST_WRITE_UINT32_BE (data + 8, avg_bitrate);
buf = _gst_buffer_new_wrapped (data, 12, g_free);
atom_data =
atom_data_new_from_gst_buffer (GST_MAKE_FOURCC ('b', 't', 'r', 't'), buf);
gst_buffer_unref (buf);
@ -4022,6 +4033,7 @@ build_mov_aac_extension (AtomTRAK * trak, const GstBuffer * codec_data,
{
AtomInfo *esds, *mp4a;
GstBuffer *buf;
guint32 tmp = 0;
/* Add ESDS atom to WAVE */
esds = build_esds_extension (trak, ESDS_OBJECT_TYPE_MPEG4_P3,
@ -4029,8 +4041,7 @@ build_mov_aac_extension (AtomTRAK * trak, const GstBuffer * codec_data,
/* Add MP4A atom to the WAVE:
* not really in spec, but makes offset based players happy */
buf = gst_buffer_new_and_alloc (4);
*((guint32 *) GST_BUFFER_DATA (buf)) = 0;
buf = _gst_buffer_new_wrapped (&tmp, 4, NULL);
mp4a = build_codec_data_extension (FOURCC_mp4a, buf);
gst_buffer_unref (buf);
@ -4052,14 +4063,13 @@ build_fiel_extension (gint fields)
{
AtomData *atom_data;
GstBuffer *buf;
guint8 f = fields;
if (fields == 1) {
return NULL;
}
buf = gst_buffer_new_and_alloc (1);
GST_BUFFER_DATA (buf)[0] = (guint8) fields;
buf = _gst_buffer_new_wrapped (&f, 1, NULL);
atom_data =
atom_data_new_from_gst_buffer (GST_MAKE_FOURCC ('f', 'i', 'e', 'l'), buf);
gst_buffer_unref (buf);
@ -4129,9 +4139,8 @@ build_jp2h_extension (AtomTRAK * trak, gint width, gint height, guint32 fourcc,
cdef_size = 8 + 2 + cdef_array_size * 6;
}
buf = gst_buffer_new_and_alloc (idhr_size + colr_size + cmap_size +
cdef_size);
gst_byte_writer_init_with_buffer (&writer, buf, FALSE);
gst_byte_writer_init_with_size (&writer,
idhr_size + colr_size + cmap_size + cdef_size, TRUE);
/* ihdr = image header box */
gst_byte_writer_put_uint32_be (&writer, 22);
@ -4215,6 +4224,7 @@ build_jp2h_extension (AtomTRAK * trak, gint width, gint height, guint32 fourcc,
}
g_assert (gst_byte_writer_get_remaining (&writer) == 0);
buf = gst_byte_writer_reset_and_get_buffer (&writer);
atom_data = atom_data_new_from_gst_buffer (FOURCC_jp2h, buf);
gst_buffer_unref (buf);
@ -4245,10 +4255,6 @@ build_amr_extension (void)
GstBuffer *buf;
AtomInfo *res;
buf = gst_buffer_new ();
GST_BUFFER_DATA (buf) = ext;
GST_BUFFER_SIZE (buf) = sizeof (ext);
/* vendor */
GST_WRITE_UINT32_LE (ext, 0);
/* decoder version */
@ -4260,6 +4266,7 @@ build_amr_extension (void)
/* frames per sample */
GST_WRITE_UINT8 (ext + 8, 1);
buf = _gst_buffer_new_wrapped (ext, sizeof (ext), NULL);
res = build_codec_data_extension (GST_MAKE_FOURCC ('d', 'a', 'm', 'r'), buf);
gst_buffer_unref (buf);
return res;
@ -4272,10 +4279,6 @@ build_h263_extension (void)
GstBuffer *buf;
AtomInfo *res;
buf = gst_buffer_new ();
GST_BUFFER_DATA (buf) = ext;
GST_BUFFER_SIZE (buf) = sizeof (ext);
/* vendor */
GST_WRITE_UINT32_LE (ext, 0);
/* decoder version */
@ -4285,6 +4288,7 @@ build_h263_extension (void)
GST_WRITE_UINT8 (ext + 5, 10);
GST_WRITE_UINT8 (ext + 6, 0);
buf = _gst_buffer_new_wrapped (ext, sizeof (ext), NULL);
res = build_codec_data_extension (GST_MAKE_FOURCC ('d', '2', '6', '3'), buf);
gst_buffer_unref (buf);
return res;
@ -4300,8 +4304,8 @@ build_gama_atom (gdouble gamma)
/* 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);
gamma_fp = GUINT32_TO_BE (gamma_fp);
buf = _gst_buffer_new_wrapped (&gamma_fp, 4, NULL);
res = build_codec_data_extension (FOURCC_gama, buf);
gst_buffer_unref (buf);
return res;
@ -4312,14 +4316,17 @@ build_SMI_atom (const GstBuffer * seqh)
{
AtomInfo *res;
GstBuffer *buf;
gsize size;
guint8 *data;
/* the seqh plus its size and fourcc */
buf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (seqh) + 8);
size = gst_buffer_get_size ((GstBuffer *) seqh);
data = g_malloc (size + 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));
GST_WRITE_UINT32_LE (data, FOURCC_SEQH);
GST_WRITE_UINT32_BE (data + 4, size + 8);
gst_buffer_extract ((GstBuffer *) seqh, 0, data + 8, size);
buf = _gst_buffer_new_wrapped (data, size + 8, g_free);
res = build_codec_data_extension (FOURCC_SMI_, buf);
gst_buffer_unref (buf);
return res;
@ -4341,8 +4348,7 @@ build_ima_adpcm_atom (gint channels, gint rate, gint blocksize)
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);
data = g_malloc (ima_adpcm_atom_size);
/* 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. */
@ -4359,6 +4365,7 @@ build_ima_adpcm_atom (gint channels, gint rate, gint blocksize)
GST_WRITE_UINT16_LE (data + 16, 2); /* Two extra bytes */
GST_WRITE_UINT16_LE (data + 18, samplesperblock);
buf = _gst_buffer_new_wrapped (data, ima_adpcm_atom_size, g_free);
atom_data = atom_data_new_from_gst_buffer (fourcc, buf);
gst_buffer_unref (buf);
@ -4402,6 +4409,7 @@ AtomInfo *
build_uuid_xmp_atom (GstBuffer * xmp_data)
{
AtomUUID *uuid;
gsize size;
static guint8 xmp_uuid[] = { 0xBE, 0x7A, 0xCF, 0xCB,
0x97, 0xA9, 0x42, 0xE8,
0x9C, 0x71, 0x99, 0x94,
@ -4414,9 +4422,10 @@ build_uuid_xmp_atom (GstBuffer * xmp_data)
uuid = atom_uuid_new ();
memcpy (uuid->uuid, xmp_uuid, 16);
uuid->data = g_malloc (GST_BUFFER_SIZE (xmp_data));
uuid->datalen = GST_BUFFER_SIZE (xmp_data);
memcpy (uuid->data, GST_BUFFER_DATA (xmp_data), GST_BUFFER_SIZE (xmp_data));
size = gst_buffer_get_size (xmp_data);
uuid->data = g_malloc (size);
uuid->datalen = size;
gst_buffer_extract (xmp_data, 0, uuid->data, size);
return build_atom_info_wrapper ((Atom *) uuid, atom_uuid_copy_data,
atom_uuid_free);

View file

@ -108,10 +108,15 @@ atoms_recov_write_ftyp_info (FILE * f, AtomFTYP * ftyp, GstBuffer * prefix)
guint64 size = 0;
if (prefix) {
if (fwrite (GST_BUFFER_DATA (prefix), 1, GST_BUFFER_SIZE (prefix), f) !=
GST_BUFFER_SIZE (prefix)) {
guint8 *bdata;
gsize bsize;
bdata = gst_buffer_map (prefix, &bsize, NULL, GST_MAP_READ);
if (fwrite (bdata, 1, bsize, f) != bsize) {
gst_buffer_unmap (prefix, bdata, bsize);
return FALSE;
}
gst_buffer_unmap (prefix, bdata, bsize);
}
if (!atom_ftyp_copy_data (ftyp, &data, &size, &offset)) {
return FALSE;

View file

@ -89,8 +89,8 @@ enum
PROP_FAST_START_MODE
};
GST_BOILERPLATE (GstQTMoovRecover, gst_qt_moov_recover, GstPipeline,
GST_TYPE_PIPELINE);
#define gst_qt_moov_recover_parent_class parent_class
G_DEFINE_TYPE (GstQTMoovRecover, gst_qt_moov_recover, GST_TYPE_PIPELINE);
/* property functions */
static void gst_qt_moov_recover_set_property (GObject * object,
@ -103,18 +103,6 @@ static GstStateChangeReturn gst_qt_moov_recover_change_state (GstElement *
static void gst_qt_moov_recover_finalize (GObject * object);
static void
gst_qt_moov_recover_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
#if 0
GstQTMoovRecoverClass *klass = (GstQTMoovRecoverClass *) g_class;
#endif
gst_element_class_set_details_simple (element_class, "QT Moov Recover",
"Util", "Recovers unfinished qtmux files",
"Thiago Santos <thiago.sousa.santos@collabora.co.uk>");
}
static void
gst_qt_moov_recover_class_init (GstQTMoovRecoverClass * klass)
{
@ -156,11 +144,14 @@ gst_qt_moov_recover_class_init (GstQTMoovRecoverClass * klass)
GST_DEBUG_CATEGORY_INIT (gst_qt_moov_recover_debug, "qtmoovrecover", 0,
"QT Moovie Recover");
gst_element_class_set_details_simple (gstelement_class, "QT Moov Recover",
"Util", "Recovers unfinished qtmux files",
"Thiago Santos <thiago.sousa.santos@collabora.co.uk>");
}
static void
gst_qt_moov_recover_init (GstQTMoovRecover * qtmr,
GstQTMoovRecoverClass * qtmr_klass)
gst_qt_moov_recover_init (GstQTMoovRecover * qtmr)
{
}

View file

@ -117,6 +117,7 @@
#include <gst/gst.h>
#include <gst/base/gstcollectpads.h>
#include <gst/video/video.h>
#include <gst/tag/xmpwriter.h>
#include <sys/types.h>
@ -220,7 +221,7 @@ static void gst_qt_mux_get_property (GObject * object,
/* pad functions */
static GstPad *gst_qt_mux_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name);
GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gst_qt_mux_release_pad (GstElement * element, GstPad * pad);
/* event */
@ -515,20 +516,23 @@ gst_qt_mux_prepare_jpc_buffer (GstQTPad * qtpad, GstBuffer * buf,
GstQTMux * qtmux)
{
GstBuffer *newbuf;
guint8 *data;
gsize size;
GST_LOG_OBJECT (qtmux, "Preparing jpc buffer");
if (buf == NULL)
return NULL;
newbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buf) + 8);
gst_buffer_copy_metadata (newbuf, buf, GST_BUFFER_COPY_ALL);
size = gst_buffer_get_size (buf);
newbuf = gst_buffer_new_and_alloc (size + 8);
gst_buffer_copy_into (newbuf, buf, GST_BUFFER_COPY_ALL, 8, size);
GST_WRITE_UINT32_BE (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
GST_WRITE_UINT32_LE (GST_BUFFER_DATA (newbuf) + 4, FOURCC_jp2c);
data = gst_buffer_map (newbuf, &size, NULL, GST_MAP_WRITE);
GST_WRITE_UINT32_BE (data, size);
GST_WRITE_UINT32_LE (data + 4, FOURCC_jp2c);
memcpy (GST_BUFFER_DATA (newbuf) + 8, GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf));
gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
return newbuf;
@ -635,6 +639,8 @@ gst_qt_mux_add_mp4_cover (GstQTMux * qtmux, const GstTagList * list,
GstCaps *caps;
GstStructure *structure;
gint flags = 0;
guint8 *data;
gsize size;
g_return_if_fail (gst_tag_get_type (tag) == GST_TYPE_BUFFER);
@ -645,7 +651,9 @@ gst_qt_mux_add_mp4_cover (GstQTMux * qtmux, const GstTagList * list,
if (!buf)
goto done;
caps = gst_buffer_get_caps (buf);
/* FIXME-0.11 caps metadata ? */
/* caps = gst_buffer_get_caps (buf); */
caps = NULL;
if (!caps) {
GST_WARNING_OBJECT (qtmux, "preview image without caps");
goto done;
@ -665,10 +673,11 @@ gst_qt_mux_add_mp4_cover (GstQTMux * qtmux, const GstTagList * list,
goto done;
}
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
GST_DEBUG_OBJECT (qtmux, "Adding tag %" GST_FOURCC_FORMAT
" -> image size %d", GST_FOURCC_ARGS (fourcc), GST_BUFFER_SIZE (buf));
atom_moov_add_tag (qtmux->moov, fourcc, flags, GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf));
" -> image size %d", GST_FOURCC_ARGS (fourcc), size);
atom_moov_add_tag (qtmux->moov, fourcc, flags, data, size);
gst_buffer_unmap (buf, data, size);
done:
g_value_unset (&value);
}
@ -1095,14 +1104,18 @@ gst_qt_mux_add_metadata_tags (GstQTMux * qtmux, const GstTagList * list)
GstCaps *caps = NULL;
val = gst_tag_list_get_value_index (list, GST_QT_DEMUX_PRIVATE_TAG, i);
buf = (GstBuffer *) gst_value_get_mini_object (val);
buf = (GstBuffer *) gst_value_get_buffer (val);
if (buf && (caps = gst_buffer_get_caps (buf))) {
/* FIXME-0.11 */
if (buf && (caps = NULL /*gst_buffer_get_caps (buf) */ )) {
GstStructure *s;
const gchar *style = NULL;
guint8 *data;
gsize size;
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
GST_DEBUG_OBJECT (qtmux, "Found private tag %d/%d; size %d, caps %"
GST_PTR_FORMAT, i, num_tags, GST_BUFFER_SIZE (buf), caps);
GST_PTR_FORMAT, i, num_tags, size, caps);
s = gst_caps_get_structure (caps, 0);
if (s && (style = gst_structure_get_string (s, "style"))) {
/* try to prevent some style tag ending up into another variant
@ -1112,10 +1125,10 @@ gst_qt_mux_add_metadata_tags (GstQTMux * qtmux, const GstTagList * list)
(strcmp (style, "iso") == 0 &&
qtmux_klass->format == GST_QT_MUX_FORMAT_3GP)) {
GST_DEBUG_OBJECT (qtmux, "Adding private tag");
atom_moov_add_blob_tag (qtmux->moov, GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf));
atom_moov_add_blob_tag (qtmux->moov, data, size);
}
}
gst_buffer_unmap (buf, data, size);
gst_caps_unref (caps);
}
}
@ -1162,8 +1175,8 @@ _gst_buffer_new_take_data (guint8 * data, guint size)
GstBuffer *buf;
buf = gst_buffer_new ();
GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
GST_BUFFER_SIZE (buf) = size;
gst_buffer_take_memory (buf, -1,
gst_memory_new_wrapped (0, data, g_free, size, 0, size));
return buf;
}
@ -1173,21 +1186,21 @@ gst_qt_mux_send_buffer (GstQTMux * qtmux, GstBuffer * buf, guint64 * offset,
gboolean mind_fast)
{
GstFlowReturn res;
guint8 *data;
guint size;
gsize size;
g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
data = GST_BUFFER_DATA (buf);
size = GST_BUFFER_SIZE (buf);
size = gst_buffer_get_size (buf);
GST_LOG_OBJECT (qtmux, "sending buffer size %d", size);
if (mind_fast && qtmux->fast_start_file) {
gint ret;
guint8 *data;
GST_LOG_OBJECT (qtmux, "to temporary file");
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
ret = fwrite (data, sizeof (guint8), size, qtmux->fast_start_file);
gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
if (ret != size)
goto write_error;
@ -1195,9 +1208,6 @@ gst_qt_mux_send_buffer (GstQTMux * qtmux, GstBuffer * buf, guint64 * offset,
res = GST_FLOW_OK;
} else {
GST_LOG_OBJECT (qtmux, "downstream");
buf = gst_buffer_make_metadata_writable (buf);
gst_buffer_set_caps (buf, GST_PAD_CAPS (qtmux->srcpad));
res = gst_pad_push (qtmux->srcpad, buf);
}
@ -1248,16 +1258,19 @@ gst_qt_mux_send_buffered_data (GstQTMux * qtmux, guint64 * offset)
* (somehow optimize copy?) */
GST_DEBUG_OBJECT (qtmux, "Sending buffered data");
while (ret == GST_FLOW_OK) {
gint r;
const int bufsize = 4096;
guint8 *data;
gsize size;
buf = gst_buffer_new_and_alloc (bufsize);
r = fread (GST_BUFFER_DATA (buf), sizeof (guint8), bufsize,
qtmux->fast_start_file);
if (r == 0)
gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
size = fread (data, sizeof (guint8), bufsize, qtmux->fast_start_file);
if (size == 0) {
gst_buffer_unmap (buf, data, -1);
break;
GST_BUFFER_SIZE (buf) = r;
GST_LOG_OBJECT (qtmux, "Pushing buffered buffer of size %d", r);
}
gst_buffer_unmap (buf, data, size);
GST_LOG_OBJECT (qtmux, "Pushing buffered buffer of size %d", (gint) size);
ret = gst_qt_mux_send_buffer (qtmux, buf, offset, FALSE);
buf = NULL;
}
@ -1354,9 +1367,11 @@ static GstFlowReturn
gst_qt_mux_update_mdat_size (GstQTMux * qtmux, guint64 mdat_pos,
guint64 mdat_size, guint64 * offset)
{
GstEvent *event;
GstBuffer *buf;
gboolean large_file;
GstSegment segment;
guint8 *data;
gsize size;
large_file = (mdat_size > MDAT_LARGE_FILE_LIMIT);
@ -1364,23 +1379,23 @@ gst_qt_mux_update_mdat_size (GstQTMux * qtmux, guint64 mdat_pos,
mdat_pos += 8;
/* seek and rewrite the header */
event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
mdat_pos, GST_CLOCK_TIME_NONE, 0);
gst_pad_push_event (qtmux->srcpad, event);
gst_segment_init (&segment, GST_FORMAT_BYTES);
segment.start = mdat_pos;
gst_pad_push_event (qtmux->srcpad, gst_event_new_segment (&segment));
if (large_file) {
buf = gst_buffer_new_and_alloc (sizeof (guint64));
GST_WRITE_UINT64_BE (GST_BUFFER_DATA (buf), mdat_size + 16);
data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
GST_WRITE_UINT64_BE (data, mdat_size + 16);
} else {
guint8 *data;
buf = gst_buffer_new_and_alloc (16);
data = GST_BUFFER_DATA (buf);
data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
GST_WRITE_UINT32_BE (data, 8);
GST_WRITE_UINT32_LE (data + 4, FOURCC_free);
GST_WRITE_UINT32_BE (data + 8, mdat_size + 8);
GST_WRITE_UINT32_LE (data + 12, FOURCC_mdat);
}
gst_buffer_unmap (buf, data, size);
return gst_qt_mux_send_buffer (qtmux, buf, offset, FALSE);
}
@ -1467,9 +1482,12 @@ gst_qt_mux_set_header_on_caps (GstQTMux * mux, GstBuffer * buf)
GstStructure *structure;
GValue array = { 0 };
GValue value = { 0 };
GstCaps *caps = GST_PAD_CAPS (mux->srcpad);
GstCaps *caps, *tcaps;
tcaps = gst_pad_get_current_caps (mux->srcpad);
caps = gst_caps_copy (tcaps);
gst_caps_unref (tcaps);
caps = gst_caps_copy (GST_PAD_CAPS (mux->srcpad));
structure = gst_caps_get_structure (caps, 0);
g_value_init (&array, GST_TYPE_ARRAY);
@ -1589,6 +1607,7 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
{
GstFlowReturn ret = GST_FLOW_OK;
GstCaps *caps;
GstSegment segment;
GST_DEBUG_OBJECT (qtmux, "starting file");
@ -1600,8 +1619,8 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
gst_caps_unref (caps);
/* let downstream know we think in BYTES and expect to do seeking later on */
gst_pad_push_event (qtmux->srcpad,
gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0));
gst_segment_init (&segment, GST_FORMAT_BYTES);
gst_pad_push_event (qtmux->srcpad, gst_event_new_segment (&segment));
/* initialize our moov recovery file */
GST_OBJECT_LOCK (qtmux);
@ -1760,7 +1779,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
}
if (qtmux->fragment_sequence) {
GstEvent *event;
GstSegment segment;
if (qtmux->mfra) {
guint8 *data = NULL;
@ -1780,7 +1799,6 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
return GST_FLOW_OK;
}
timescale = qtmux->timescale;
/* only mvex duration is updated,
* mvhd should be consistent with empty moov
@ -1790,9 +1808,9 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
GST_DEBUG_OBJECT (qtmux, "rewriting moov with mvex duration %"
GST_TIME_FORMAT, GST_TIME_ARGS (first_ts));
/* seek and rewrite the header */
event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
qtmux->mdat_pos, GST_CLOCK_TIME_NONE, 0);
gst_pad_push_event (qtmux->srcpad, event);
gst_segment_init (&segment, GST_FORMAT_BYTES);
segment.start = qtmux->mdat_pos;
gst_pad_push_event (qtmux->srcpad, gst_event_new_segment (&segment));
/* no need to seek back */
return gst_qt_mux_send_moov (qtmux, NULL, FALSE);
}
@ -1948,14 +1966,15 @@ flush:
pad->traf = NULL;
atom_moof_copy_data (moof, &data, &size, &offset);
buffer = _gst_buffer_new_take_data (data, offset);
GST_LOG_OBJECT (qtmux, "writing moof size %d", GST_BUFFER_SIZE (buffer));
GST_LOG_OBJECT (qtmux, "writing moof size %d",
gst_buffer_get_size (buffer));
ret = gst_qt_mux_send_buffer (qtmux, buffer, &qtmux->header_size, FALSE);
/* and actual data */
total_size = 0;
for (i = 0; i < atom_array_get_len (&pad->fragment_buffers); i++) {
total_size +=
GST_BUFFER_SIZE (atom_array_index (&pad->fragment_buffers, i));
gst_buffer_get_size (atom_array_index (&pad->fragment_buffers, i));
}
GST_LOG_OBJECT (qtmux, "writing %d buffers, total_size %d",
@ -2046,7 +2065,7 @@ gst_qt_mux_get_asc_buffer_ts (GstQTMux * qtmux, GstQTPad * pad, GstBuffer * buf)
buf = pad->buf_entries[pad->buf_head];
pad->buf_entries[pad->buf_head++] = NULL;
pad->buf_head %= wrap;
buf = gst_buffer_make_metadata_writable (buf);
buf = gst_buffer_make_writable (buf);
/* track original ts (= pts ?) for later */
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_TIMESTAMP (buf);
GST_BUFFER_TIMESTAMP (buf) = ts;
@ -2224,7 +2243,7 @@ again:
buffer (= chunk)), but can also be fixed-packet-size codecs like ADPCM
*/
sample_size = pad->sample_size;
if (GST_BUFFER_SIZE (last_buf) % sample_size != 0)
if (gst_buffer_get_size (last_buf) % sample_size != 0)
goto fragmented_sample;
/* note: qt raw audio storage warps it implicitly into a timewise
* perfect stream, discarding buffer times */
@ -2232,7 +2251,7 @@ again:
nsamples = gst_util_uint64_scale_round (GST_BUFFER_DURATION (last_buf),
atom_trak_get_timescale (pad->trak), GST_SECOND);
} else {
nsamples = GST_BUFFER_SIZE (last_buf) / sample_size;
nsamples = gst_buffer_get_size (last_buf) / sample_size;
}
duration = GST_BUFFER_DURATION (last_buf) / nsamples;
@ -2241,7 +2260,7 @@ again:
pad->last_dts += duration * nsamples;
} else {
nsamples = 1;
sample_size = GST_BUFFER_SIZE (last_buf);
sample_size = gst_buffer_get_size (last_buf);
if (pad->have_dts) {
gint64 scaled_dts;
pad->last_dts = GST_BUFFER_OFFSET_END (last_buf);
@ -2473,7 +2492,7 @@ gst_qt_mux_collected (GstCollectPads * pads, gpointer user_data)
GST_LOG_OBJECT (qtmux, "selected pad %s with time %" GST_TIME_FORMAT,
GST_PAD_NAME (best_pad->collect.pad), GST_TIME_ARGS (best_time));
buf = gst_collect_pads_pop (pads, &best_pad->collect);
buf = gst_buffer_make_metadata_writable (buf);
buf = gst_buffer_make_writable (buf);
GST_BUFFER_TIMESTAMP (buf) = best_time;
ret = gst_qt_mux_add_buffer (qtmux, best_pad, buf);
} else {
@ -2528,7 +2547,6 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps)
AtomInfo *ext_atom = NULL;
gint constant_size = 0;
const gchar *stream_format;
GstCaps *current_caps = NULL;
/* find stream data */
qtpad = (GstQTPad *) gst_pad_get_element_private (pad);
@ -2540,15 +2558,19 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps)
* the old caps are a subset of the new one (this means upstream
* added more info to the caps, as both should be 'fixed' caps) */
if (qtpad->fourcc) {
g_object_get (pad, "caps", &current_caps, NULL);
GstCaps *current_caps;
current_caps = gst_pad_get_current_caps (pad);
g_assert (caps != NULL);
if (!gst_qtmux_caps_is_subset_full (qtmux, current_caps, caps)) {
gst_caps_unref (current_caps);
goto refuse_renegotiation;
}
GST_DEBUG_OBJECT (qtmux,
"pad %s accepted renegotiation to %" GST_PTR_FORMAT " from %"
GST_PTR_FORMAT, GST_PAD_NAME (pad), caps, GST_PAD_CAPS (pad));
GST_PTR_FORMAT, GST_PAD_NAME (pad), caps, current_caps);
gst_caps_unref (current_caps);
}
GST_DEBUG_OBJECT (qtmux, "%s:%s, caps=%" GST_PTR_FORMAT,
@ -2625,11 +2647,12 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps)
"assuming 'raw'");
}
if (!codec_data || GST_BUFFER_SIZE (codec_data) < 2)
if (!codec_data || gst_buffer_get_size ((GstBuffer *) codec_data) < 2)
GST_WARNING_OBJECT (qtmux, "no (valid) codec_data for AAC audio");
else {
guint8 profile = GST_READ_UINT8 (GST_BUFFER_DATA (codec_data));
guint8 profile;
gst_buffer_extract ((GstBuffer *) codec_data, 0, &profile, 1);
/* warn if not Low Complexity profile */
profile >>= 3;
if (profile != 2)
@ -2756,19 +2779,25 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps)
} else if (strcmp (mimetype, "audio/x-alac") == 0) {
GstBuffer *codec_config;
gint len;
guint8 *data;
gsize size;
entry.fourcc = FOURCC_alac;
data = gst_buffer_map ((GstBuffer *) codec_data, &size, NULL, GST_MAP_READ);
/* let's check if codec data already comes with 'alac' atom prefix */
if (!codec_data || (len = GST_BUFFER_SIZE (codec_data)) < 28) {
if (!codec_data || (len = size) < 28) {
GST_DEBUG_OBJECT (qtmux, "broken caps, codec data missing");
gst_buffer_unmap ((GstBuffer *) codec_data, data, size);
goto refuse_caps;
}
if (GST_READ_UINT32_LE (GST_BUFFER_DATA (codec_data) + 4) == FOURCC_alac) {
if (GST_READ_UINT32_LE (data + 4) == FOURCC_alac) {
len -= 8;
codec_config = gst_buffer_create_sub ((GstBuffer *) codec_data, 8, len);
codec_config =
gst_buffer_copy_region ((GstBuffer *) codec_data, 0, 8, len);
} else {
codec_config = gst_buffer_ref ((GstBuffer *) codec_data);
}
gst_buffer_unmap ((GstBuffer *) codec_data, data, size);
if (len != 28) {
/* does not look good, but perhaps some trailing unneeded stuff */
GST_WARNING_OBJECT (qtmux, "unexpected codec-data size, possibly broken");
@ -2778,9 +2807,10 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps)
else
ext_atom = build_codec_data_extension (FOURCC_alac, codec_config);
/* set some more info */
data = gst_buffer_map (codec_config, &size, NULL, GST_MAP_READ);
entry.bytes_per_sample = 2;
entry.samples_per_packet =
GST_READ_UINT32_BE (GST_BUFFER_DATA (codec_config) + 4);
entry.samples_per_packet = GST_READ_UINT32_BE (data + 4);
gst_buffer_unmap (codec_config, data, size);
gst_buffer_unref (codec_config);
}
@ -2850,7 +2880,6 @@ gst_qt_mux_video_sink_set_caps (GstPad * pad, GstCaps * caps)
GList *ext_atom_list = NULL;
gboolean sync = FALSE;
int par_num, par_den;
GstCaps *current_caps = NULL;
/* find stream data */
qtpad = (GstQTPad *) gst_pad_get_element_private (pad);
@ -2862,15 +2891,19 @@ gst_qt_mux_video_sink_set_caps (GstPad * pad, GstCaps * caps)
* the old caps are a subset of the new one (this means upstream
* added more info to the caps, as both should be 'fixed' caps) */
if (qtpad->fourcc) {
g_object_get (pad, "caps", &current_caps, NULL);
GstCaps *current_caps;
current_caps = gst_pad_get_current_caps (pad);
g_assert (caps != NULL);
if (!gst_qtmux_caps_is_subset_full (qtmux, current_caps, caps)) {
gst_caps_unref (current_caps);
goto refuse_renegotiation;
}
GST_DEBUG_OBJECT (qtmux,
"pad %s accepted renegotiation to %" GST_PTR_FORMAT " from %"
GST_PTR_FORMAT, GST_PAD_NAME (pad), caps, GST_PAD_CAPS (pad));
GST_PTR_FORMAT, GST_PAD_NAME (pad), caps, current_caps);
gst_caps_unref (current_caps);
}
GST_DEBUG_OBJECT (qtmux, "%s:%s, caps=%" GST_PTR_FORMAT,
@ -2925,24 +2958,27 @@ gst_qt_mux_video_sink_set_caps (GstPad * pad, GstCaps * caps)
sync = TRUE;
/* now map onto a fourcc, and some extra properties */
if (strcmp (mimetype, "video/x-raw-rgb") == 0) {
gint bpp;
if (strcmp (mimetype, "video/x-raw") == 0) {
const gchar *format;
GstVideoFormat fmt;
entry.fourcc = FOURCC_raw_;
gst_structure_get_int (structure, "bpp", &bpp);
entry.depth = bpp;
sync = FALSE;
} else if (strcmp (mimetype, "video/x-raw-yuv") == 0) {
guint32 format = 0;
format = gst_structure_get_string (structure, "format");
fmt = gst_video_format_from_string (format);
sync = FALSE;
gst_structure_get_fourcc (structure, "format", &format);
switch (format) {
case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
switch (fmt) {
case GST_VIDEO_FORMAT_UYVY:
if (depth == -1)
depth = 24;
entry.fourcc = FOURCC_2vuy;
entry.depth = depth;
sync = FALSE;
break;
default:
if (gst_video_format_is_rgb (fmt)) {
entry.fourcc = FOURCC_raw_;
entry.depth = gst_video_format_get_pixel_stride (fmt, 0) * 8;
sync = FALSE;
}
break;
}
} else if (strcmp (mimetype, "video/x-h263") == 0) {
@ -3155,8 +3191,8 @@ refuse_caps:
refuse_renegotiation:
{
GST_WARNING_OBJECT (qtmux,
"pad %s refused renegotiation to %" GST_PTR_FORMAT " from %"
GST_PTR_FORMAT, GST_PAD_NAME (pad), caps, GST_PAD_CAPS (pad));
"pad %s refused renegotiation to %" GST_PTR_FORMAT, GST_PAD_NAME (pad),
caps);
gst_object_unref (qtmux);
return FALSE;
}
@ -3170,7 +3206,23 @@ gst_qt_mux_sink_event (GstPad * pad, GstEvent * event)
guint32 avg_bitrate = 0, max_bitrate = 0;
qtmux = GST_QT_MUX_CAST (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
{
GstCaps *caps;
GstQTPad *collect_pad;
gst_event_parse_caps (event, &caps);
/* find stream data */
collect_pad = (GstQTPad *) gst_pad_get_element_private (pad);
g_assert (collect_pad);
g_assert (collect_pad->set_caps);
collect_pad->set_caps (pad, caps);
break;
}
case GST_EVENT_TAG:{
GstTagList *list;
GstTagSetter *setter = GST_TAG_SETTER (qtmux);
@ -3232,7 +3284,7 @@ gst_qt_mux_release_pad (GstElement * element, GstPad * pad)
static GstPad *
gst_qt_mux_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * req_name)
GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
GstQTMux *qtmux = GST_QT_MUX_CAST (element);
@ -3273,11 +3325,9 @@ gst_qt_mux_request_new_pad (GstElement * element,
/* set up pad functions */
if (audio)
gst_pad_set_setcaps_function (newpad,
GST_DEBUG_FUNCPTR (gst_qt_mux_audio_sink_set_caps));
collect_pad->set_caps = GST_DEBUG_FUNCPTR (gst_qt_mux_audio_sink_set_caps);
else
gst_pad_set_setcaps_function (newpad,
GST_DEBUG_FUNCPTR (gst_qt_mux_video_sink_set_caps));
collect_pad->set_caps = GST_DEBUG_FUNCPTR (gst_qt_mux_video_sink_set_caps);
/* FIXME: hacked way to override/extend the event function of
* GstCollectPads; because it sets its own event function giving the

View file

@ -125,6 +125,7 @@ struct _GstQTPad
/* if nothing is set, it won't be called */
GstQTPadPrepareBufferFunc prepare_buf_func;
gboolean (*set_caps) (GstPad * pad, GstCaps * caps);
};
typedef enum _GstQTMuxState

View file

@ -153,10 +153,8 @@ GstQTMuxFormatProp gst_qt_mux_format_list[] = {
"GstQTMux",
GST_STATIC_CAPS ("video/quicktime, variant = (string) apple; "
"video/quicktime"),
GST_STATIC_CAPS ("video/x-raw-rgb, "
COMMON_VIDEO_CAPS "; "
"video/x-raw-yuv, "
"format = (fourcc) UYVY, "
GST_STATIC_CAPS ("video/x-raw, "
"format = (string) { RGB, UYVY }, "
COMMON_VIDEO_CAPS "; "
MPEG4V_CAPS "; "
H263_CAPS "; "
@ -361,12 +359,18 @@ gst_qt_mux_map_format_to_header (GstQTMuxFormat format, GstBuffer ** _prefix,
break;
}
case GST_QT_MUX_FORMAT_MJ2:
{
guint8 *bdata;
major = FOURCC_mjp2;
comp = mjp2_brands;
version = 0;
prefix = gst_buffer_new_and_alloc (sizeof (mjp2_prefix));
memcpy (GST_BUFFER_DATA (prefix), mjp2_prefix, GST_BUFFER_SIZE (prefix));
bdata = gst_buffer_map (prefix, NULL, NULL, GST_MAP_WRITE);
memcpy (bdata, mjp2_prefix, sizeof (mjp2_prefix));
gst_buffer_unmap (prefix, bdata, -1);
break;
}
default:
g_assert_not_reached ();
break;

View file

@ -91,8 +91,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
"encoding-name = (string) { \"X-QT\", \"X-QUICKTIME\" }")
);
GST_BOILERPLATE (GstRtpXQTDepay, gst_rtp_xqt_depay, GstBaseRTPDepayload,
GST_TYPE_BASE_RTP_DEPAYLOAD);
#define gst_rtp_xqt_depay_parent_class parent_class
G_DEFINE_TYPE (GstRtpXQTDepay, gst_rtp_xqt_depay, GST_TYPE_BASE_RTP_DEPAYLOAD);
static void gst_rtp_xqt_depay_finalize (GObject * object);
@ -104,21 +104,6 @@ static GstBuffer *gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload,
static GstStateChangeReturn gst_rtp_xqt_depay_change_state (GstElement *
element, GstStateChange transition);
static void
gst_rtp_xqt_depay_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_rtp_xqt_depay_src_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_rtp_xqt_depay_sink_template));
gst_element_class_set_details_simple (element_class, "RTP packet depayloader",
"Codec/Depayloader/Network",
"Extracts Quicktime audio/video from RTP packets",
"Wim Taymans <wim@fluendo.com>");
}
static void
gst_rtp_xqt_depay_class_init (GstRtpXQTDepayClass * klass)
@ -142,11 +127,20 @@ gst_rtp_xqt_depay_class_init (GstRtpXQTDepayClass * klass)
GST_DEBUG_CATEGORY_INIT (rtpxqtdepay_debug, "rtpxqtdepay", 0,
"QT Media RTP Depayloader");
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&gst_rtp_xqt_depay_src_template));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&gst_rtp_xqt_depay_sink_template));
gst_element_class_set_details_simple (gstelement_class,
"RTP packet depayloader", "Codec/Depayloader/Network",
"Extracts Quicktime audio/video from RTP packets",
"Wim Taymans <wim@fluendo.com>");
}
static void
gst_rtp_xqt_depay_init (GstRtpXQTDepay * rtpxqtdepay,
GstRtpXQTDepayClass * klass)
gst_rtp_xqt_depay_init (GstRtpXQTDepay * rtpxqtdepay)
{
rtpxqtdepay->adapter = gst_adapter_new ();
}
@ -201,6 +195,7 @@ gst_rtp_quicktime_parse_sd (GstRtpXQTDepay * rtpxqtdepay, guint8 * data,
GstBuffer *buf;
gint size;
GstCaps *caps;
guint8 *bdata;
GST_DEBUG_OBJECT (rtpxqtdepay, "found avcC codec_data in sd, %u",
chlen);
@ -212,7 +207,9 @@ gst_rtp_quicktime_parse_sd (GstRtpXQTDepay * rtpxqtdepay, guint8 * data,
size = len - 8;
buf = gst_buffer_new_and_alloc (size);
memcpy (GST_BUFFER_DATA (buf), data + 8, size);
bdata = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
memcpy (bdata, data + 8, size);
gst_buffer_unmap (buf, bdata, -1);
caps = gst_caps_new_simple ("video/x-h264",
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
@ -255,11 +252,14 @@ static GstBuffer *
gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
{
GstRtpXQTDepay *rtpxqtdepay;
GstBuffer *outbuf;
GstBuffer *outbuf = NULL;
gboolean m;
GstRTPBuffer rtp;
rtpxqtdepay = GST_RTP_XQT_DEPAY (depayload);
gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
if (!gst_rtp_buffer_validate (buf))
goto bad_packet;
@ -270,7 +270,7 @@ gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
GST_DEBUG_OBJECT (rtpxqtdepay, "we need resync");
}
m = gst_rtp_buffer_get_marker (buf);
m = gst_rtp_buffer_get_marker (&rtp);
GST_LOG_OBJECT (rtpxqtdepay, "marker: %d", m);
{
@ -279,9 +279,11 @@ gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
guint8 *payload;
guint8 ver, pck;
gboolean s, q, l, d;
guint8 *bdata;
gsize bsize;
payload_len = gst_rtp_buffer_get_payload_len (buf);
payload = gst_rtp_buffer_get_payload (buf);
payload_len = gst_rtp_buffer_get_payload_len (&rtp);
payload = gst_rtp_buffer_get_payload (&rtp);
/* 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@ -545,8 +547,11 @@ gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
{
/* multiple samples per packet. */
outbuf = gst_buffer_new_and_alloc (payload_len);
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
return outbuf;
bdata = gst_buffer_map (outbuf, &bsize, NULL, GST_MAP_WRITE);
memcpy (bdata, payload, payload_len);
gst_buffer_unmap (outbuf, bdata, bsize);
goto done;
}
case 2:
{
@ -586,7 +591,9 @@ gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
slen = payload_len;
outbuf = gst_buffer_new_and_alloc (slen);
memcpy (GST_BUFFER_DATA (outbuf), payload, slen);
bdata = gst_buffer_map (outbuf, &bsize, NULL, GST_MAP_WRITE);
memcpy (bdata, payload, slen);
gst_buffer_unmap (outbuf, bdata, bsize);
if (!s)
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
@ -604,7 +611,9 @@ gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
{
/* one sample per packet, use adapter to combine based on marker bit. */
outbuf = gst_buffer_new_and_alloc (payload_len);
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
bdata = gst_buffer_map (outbuf, &bsize, NULL, GST_MAP_WRITE);
memcpy (bdata, payload, payload_len);
gst_buffer_unmap (outbuf, bdata, bsize);
gst_adapter_push (rtpxqtdepay->adapter, outbuf);
@ -617,48 +626,49 @@ gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
GST_DEBUG_OBJECT (rtpxqtdepay,
"gst_rtp_xqt_depay_chain: pushing buffer of size %u", avail);
return outbuf;
goto done;
}
}
}
done:
return NULL;
gst_rtp_buffer_unmap (&rtp);
return outbuf;
bad_packet:
{
GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
("Packet did not validate."), (NULL));
return NULL;
goto done;
}
need_resync:
{
GST_DEBUG_OBJECT (rtpxqtdepay, "waiting for marker");
return NULL;
goto done;
}
wrong_version:
{
GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
("Unknown payload version."), (NULL));
return NULL;
goto done;
}
pck_reserved:
{
GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
("PCK reserved 0."), (NULL));
return NULL;
goto done;
}
wrong_length:
{
GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
("Wrong payload length."), (NULL));
return NULL;
goto done;
}
unknown_format:
{
GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE,
("Unknown payload format."), (NULL));
return NULL;
goto done;
}
}

File diff suppressed because it is too large Load diff

View file

@ -100,7 +100,6 @@ struct _GstQTDemux {
/* configured playback region */
GstSegment segment;
gboolean segment_running;
GstEvent *pending_newsegment;
/* gst index support */