summaryrefslogtreecommitdiffstats
path: root/gst/avi
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-01-19 11:01:09 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-01-19 11:01:09 +0000
commit471c844eb55dee35c36f03bdf8316992cc6a9877 (patch)
tree555f3948677f90ac7a4242f75915475c76854b88 /gst/avi
parent079805f0c912f82f7f879d02b738256f04e202aa (diff)
ext/mad/gstmad.c: Fail if caps negotiation fails. Should fix #162184, and should definately be in there regardless of...
Original commit message from CVS: * ext/mad/gstmad.c: (gst_mad_check_caps_reset), (gst_mad_chain): Fail if caps negotiation fails. Should fix #162184, and should definately be in there regardless of it fixing the actual bug. * gst/avi/gstavimux.c: (gst_avimux_get_type), (gst_avimux_init), (gst_avimux_write_tag), (gst_avimux_riff_get_avi_header), (gst_avimux_riff_get_avix_header), (gst_avimux_riff_get_video_header), (gst_avimux_riff_get_audio_header), (gst_avimux_write_index), (gst_avimux_start_file), (gst_avimux_handle_event), (gst_avimux_change_state): * gst/avi/gstavimux.h: Refactor structure writing to use GST_WRITE_UINT macros, add metadata writing support.
Diffstat (limited to 'gst/avi')
-rw-r--r--gst/avi/gstavimux.c541
-rw-r--r--gst/avi/gstavimux.h3
2 files changed, 245 insertions, 299 deletions
diff --git a/gst/avi/gstavimux.c b/gst/avi/gstavimux.c
index e12a03b6..778f8c29 100644
--- a/gst/avi/gstavimux.c
+++ b/gst/avi/gstavimux.c
@@ -178,9 +178,16 @@ gst_avimux_get_type (void)
0,
(GInstanceInitFunc) gst_avimux_init,
};
+ static const GInterfaceInfo tag_setter_info = {
+ NULL,
+ NULL,
+ NULL
+ };
avimux_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstAviMux", &avimux_info, 0);
+ g_type_add_interface_static (avimux_type, GST_TYPE_TAG_SETTER,
+ &tag_setter_info);
}
return avimux_type;
}
@@ -274,6 +281,7 @@ gst_avimux_init (GstAviMux * avimux)
avimux->auds_hdr.type = GST_MAKE_FOURCC ('a', 'u', 'd', 's');
avimux->vids_hdr.quality = 0xFFFFFFFF;
avimux->auds_hdr.quality = 0xFFFFFFFF;
+ avimux->tags = NULL;
avimux->idx = NULL;
@@ -565,302 +573,236 @@ gst_avimux_release_pad (GstElement * element, GstPad * pad)
/* DISCLAIMER: this function is ugly. So be it (i.e. it makes the rest easier) */
+static void
+gst_avimux_write_tag (const GstTagList * list, const gchar * tag, gpointer data)
+{
+ const struct
+ {
+ guint32 fcc;
+ gchar *tag;
+ } rifftags[] = {
+ {
+ GST_RIFF_INFO_ICMT, GST_TAG_COMMENT}, {
+ GST_RIFF_INFO_INAM, GST_TAG_TITLE}, {
+ GST_RIFF_INFO_ISFT, GST_TAG_ENCODER}, {
+ GST_RIFF_INFO_IGNR, GST_TAG_GENRE}, {
+ GST_RIFF_INFO_ICOP, GST_TAG_COPYRIGHT}, {
+ GST_RIFF_INFO_IART, GST_TAG_ARTIST}, {
+ GST_RIFF_INFO_IARL, GST_TAG_LOCATION}, {
+ 0, NULL}
+ };
+ gint n, len;
+ GstBuffer *buf = data;
+ gchar *str;
+
+ for (n = 0; rifftags[n].fcc != 0; n++) {
+ if (!strcmp (rifftags[n].tag, tag) &&
+ gst_tag_list_get_string (list, tag, &str)) {
+ len = strlen (str);
+ if (GST_BUFFER_MAXSIZE (buf) >= GST_BUFFER_SIZE (buf) + 8 + len + 1) {
+ GST_WRITE_UINT32_LE (GST_BUFFER_DATA (buf), rifftags[n].fcc);
+ GST_WRITE_UINT32_LE (GST_BUFFER_DATA (buf) + 4, len + 1);
+ memcpy (GST_BUFFER_DATA (buf) + 8, str, len);
+ GST_BUFFER_DATA (buf)[8 + len] = 0;
+ GST_BUFFER_SIZE (buf) += 8 + len + 1;
+ }
+ }
+ break;
+ }
+}
+
static GstBuffer *
gst_avimux_riff_get_avi_header (GstAviMux * avimux)
{
+ GstTagList *tags;
+ const GstTagList *iface_tags;
GstBuffer *buffer;
guint8 *buffdata;
- guint16 temp16;
- guint32 temp32;
-
- buffer = gst_buffer_new ();
+ guint size = 0;
/* first, let's see what actually needs to be in the buffer */
- GST_BUFFER_SIZE (buffer) = 0;
- GST_BUFFER_SIZE (buffer) += 32 + sizeof (gst_riff_avih); /* avi header */
+ size += 32 + sizeof (gst_riff_avih); /* avi header */
if (avimux->video_pad_connected) { /* we have video */
- GST_BUFFER_SIZE (buffer) += 28 + sizeof (gst_riff_strh) + sizeof (gst_riff_strf_vids); /* vid hdr */
- GST_BUFFER_SIZE (buffer) += 24; /* odml header */
+ size += 28 + sizeof (gst_riff_strh) + sizeof (gst_riff_strf_vids); /* vid hdr */
+ size += 24; /* odml header */
}
if (avimux->audio_pad_connected) { /* we have audio */
- GST_BUFFER_SIZE (buffer) += 28 + sizeof (gst_riff_strh) + sizeof (gst_riff_strf_auds); /* aud hdr */
+ size += 28 + sizeof (gst_riff_strh) + sizeof (gst_riff_strf_auds); /* aud hdr */
}
/* this is the "riff size" */
- avimux->header_size = GST_BUFFER_SIZE (buffer);
- GST_BUFFER_SIZE (buffer) += 12; /* avi data header */
+ avimux->header_size = size;
+ size += 12; /* avi data header */
+
+ /* tags */
+ iface_tags = gst_tag_setter_get_list (GST_TAG_SETTER (avimux));
+ if (iface_tags || avimux->tags) {
+ size += 1024;
+ if (iface_tags && avimux->tags) {
+ tags = gst_tag_list_merge (iface_tags, avimux->tags,
+ GST_TAG_MERGE_APPEND);
+ } else if (iface_tags) {
+ tags = gst_tag_list_copy (iface_tags);
+ } else {
+ tags = gst_tag_list_copy (avimux->tags);
+ }
+ } else {
+ tags = NULL;
+ }
/* allocate the buffer */
- buffdata = GST_BUFFER_DATA (buffer) = g_malloc (GST_BUFFER_SIZE (buffer));
+ buffer = gst_buffer_new_and_alloc (size);
+ buffdata = GST_BUFFER_DATA (buffer);
+ GST_BUFFER_SIZE (buffer) = 0;
/* avi header metadata */
- memcpy (buffdata, "RIFF", 4);
- buffdata += 4;
- temp32 =
- LE_FROM_GUINT32 (avimux->header_size + avimux->idx_size +
- avimux->data_size);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- memcpy (buffdata, "AVI ", 4);
- buffdata += 4;
- memcpy (buffdata, "LIST", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->header_size - 4 * 5);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- memcpy (buffdata, "hdrl", 4);
- buffdata += 4;
- memcpy (buffdata, "avih", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_avih));
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ memcpy (buffdata + 0, "RIFF", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4,
+ avimux->header_size + avimux->idx_size + avimux->data_size);
+ memcpy (buffdata + 8, "AVI ", 4);
+ memcpy (buffdata + 12, "LIST", 4);
+ GST_WRITE_UINT32_LE (buffdata + 16, avimux->header_size - 4 * 5);
+ memcpy (buffdata + 20, "hdrl", 4);
+ memcpy (buffdata + 24, "avih", 4);
+ GST_WRITE_UINT32_LE (buffdata + 28, sizeof (gst_riff_avih));
+ buffdata += 32;
+ GST_BUFFER_SIZE (buffer) += 32;
+
/* the AVI header itself */
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.us_frame);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.max_bps);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.pad_gran);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.flags);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.tot_frames);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.init_frames);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.streams);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.bufsize);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.width);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.height);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.scale);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.rate);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.start);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.length);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ GST_WRITE_UINT32_LE (buffdata + 0, avimux->avi_hdr.us_frame);
+ GST_WRITE_UINT32_LE (buffdata + 4, avimux->avi_hdr.max_bps);
+ GST_WRITE_UINT32_LE (buffdata + 8, avimux->avi_hdr.pad_gran);
+ GST_WRITE_UINT32_LE (buffdata + 12, avimux->avi_hdr.flags);
+ GST_WRITE_UINT32_LE (buffdata + 16, avimux->avi_hdr.tot_frames);
+ GST_WRITE_UINT32_LE (buffdata + 20, avimux->avi_hdr.init_frames);
+ GST_WRITE_UINT32_LE (buffdata + 24, avimux->avi_hdr.streams);
+ GST_WRITE_UINT32_LE (buffdata + 28, avimux->avi_hdr.bufsize);
+ GST_WRITE_UINT32_LE (buffdata + 32, avimux->avi_hdr.width);
+ GST_WRITE_UINT32_LE (buffdata + 36, avimux->avi_hdr.height);
+ GST_WRITE_UINT32_LE (buffdata + 40, avimux->avi_hdr.scale);
+ GST_WRITE_UINT32_LE (buffdata + 44, avimux->avi_hdr.rate);
+ GST_WRITE_UINT32_LE (buffdata + 48, avimux->avi_hdr.start);
+ GST_WRITE_UINT32_LE (buffdata + 52, avimux->avi_hdr.length);
+ buffdata += 56;
+ GST_BUFFER_SIZE (buffer) += 56;
if (avimux->video_pad_connected) {
/* video header metadata */
- memcpy (buffdata, "LIST", 4);
- buffdata += 4;
- temp32 =
- LE_FROM_GUINT32 (sizeof (gst_riff_strh) + sizeof (gst_riff_strf_vids) +
- 4 * 5);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- memcpy (buffdata, "strl", 4);
- buffdata += 4;
+ memcpy (buffdata + 0, "LIST", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4,
+ sizeof (gst_riff_strh) + sizeof (gst_riff_strf_vids) + 4 * 5);
+ memcpy (buffdata + 8, "strl", 4);
/* generic header */
- memcpy (buffdata, "strh", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_strh));
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ memcpy (buffdata + 12, "strh", 4);
+ GST_WRITE_UINT32_LE (buffdata + 16, sizeof (gst_riff_strh));
/* the actual header */
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.type);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.fcc_handler);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.flags);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.priority);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.init_frames);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.scale);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.rate);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.start);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.length);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.bufsize);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.quality);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.samplesize);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ GST_WRITE_UINT32_LE (buffdata + 20, avimux->vids_hdr.type);
+ GST_WRITE_UINT32_LE (buffdata + 24, avimux->vids_hdr.fcc_handler);
+ GST_WRITE_UINT32_LE (buffdata + 28, avimux->vids_hdr.flags);
+ GST_WRITE_UINT32_LE (buffdata + 32, avimux->vids_hdr.priority);
+ GST_WRITE_UINT32_LE (buffdata + 36, avimux->vids_hdr.init_frames);
+ GST_WRITE_UINT32_LE (buffdata + 40, avimux->vids_hdr.scale);
+ GST_WRITE_UINT32_LE (buffdata + 44, avimux->vids_hdr.rate);
+ GST_WRITE_UINT32_LE (buffdata + 48, avimux->vids_hdr.start);
+ GST_WRITE_UINT32_LE (buffdata + 52, avimux->vids_hdr.length);
+ GST_WRITE_UINT32_LE (buffdata + 56, avimux->vids_hdr.bufsize);
+ GST_WRITE_UINT32_LE (buffdata + 60, avimux->vids_hdr.quality);
+ GST_WRITE_UINT32_LE (buffdata + 64, avimux->vids_hdr.samplesize);
/* the video header */
- memcpy (buffdata, "strf", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_strf_vids));
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ memcpy (buffdata + 68, "strf", 4);
+ GST_WRITE_UINT32_LE (buffdata + 72, sizeof (gst_riff_strf_vids));
/* the actual header */
- temp32 = LE_FROM_GUINT32 (avimux->vids.size);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids.width);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids.height);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp16 = LE_FROM_GUINT16 (avimux->vids.planes);
- memcpy (buffdata, &temp16, 2);
- buffdata += 2;
- temp16 = LE_FROM_GUINT16 (avimux->vids.bit_cnt);
- memcpy (buffdata, &temp16, 2);
- buffdata += 2;
- temp32 = LE_FROM_GUINT32 (avimux->vids.compression);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids.image_size);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids.xpels_meter);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids.ypels_meter);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids.num_colors);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->vids.imp_colors);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ GST_WRITE_UINT32_LE (buffdata + 76, avimux->vids.size);
+ GST_WRITE_UINT32_LE (buffdata + 80, avimux->vids.width);
+ GST_WRITE_UINT32_LE (buffdata + 84, avimux->vids.height);
+ GST_WRITE_UINT16_LE (buffdata + 88, avimux->vids.planes);
+ GST_WRITE_UINT16_LE (buffdata + 90, avimux->vids.bit_cnt);
+ GST_WRITE_UINT32_LE (buffdata + 92, avimux->vids.compression);
+ GST_WRITE_UINT32_LE (buffdata + 96, avimux->vids.image_size);
+ GST_WRITE_UINT32_LE (buffdata + 100, avimux->vids.xpels_meter);
+ GST_WRITE_UINT32_LE (buffdata + 104, avimux->vids.ypels_meter);
+ GST_WRITE_UINT32_LE (buffdata + 108, avimux->vids.num_colors);
+ GST_WRITE_UINT32_LE (buffdata + 112, avimux->vids.imp_colors);
+ buffdata += 116;
+ GST_BUFFER_SIZE (buffer) += 116;
}
if (avimux->audio_pad_connected) {
/* audio header */
- memcpy (buffdata, "LIST", 4);
- buffdata += 4;
- temp32 =
- LE_FROM_GUINT32 (sizeof (gst_riff_strh) + sizeof (gst_riff_strf_auds) +
- 4 * 5);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- memcpy (buffdata, "strl", 4);
- buffdata += 4;
+ memcpy (buffdata + 0, "LIST", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4,
+ sizeof (gst_riff_strh) + sizeof (gst_riff_strf_auds) + 4 * 5);
+ memcpy (buffdata + 8, "strl", 4);
/* generic header */
- memcpy (buffdata, "strh", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_strh));
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ memcpy (buffdata + 12, "strh", 4);
+ GST_WRITE_UINT32_LE (buffdata + 16, sizeof (gst_riff_strh));
/* the actual header */
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.type);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.fcc_handler);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.flags);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.priority);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.init_frames);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.scale);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.rate);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.start);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.length);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.bufsize);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.quality);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.samplesize);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ GST_WRITE_UINT32_LE (buffdata + 20, avimux->auds_hdr.type);
+ GST_WRITE_UINT32_LE (buffdata + 24, avimux->auds_hdr.fcc_handler);
+ GST_WRITE_UINT32_LE (buffdata + 28, avimux->auds_hdr.flags);
+ GST_WRITE_UINT32_LE (buffdata + 32, avimux->auds_hdr.priority);
+ GST_WRITE_UINT32_LE (buffdata + 36, avimux->auds_hdr.init_frames);
+ GST_WRITE_UINT32_LE (buffdata + 40, avimux->auds_hdr.scale);
+ GST_WRITE_UINT32_LE (buffdata + 44, avimux->auds_hdr.rate);
+ GST_WRITE_UINT32_LE (buffdata + 48, avimux->auds_hdr.start);
+ GST_WRITE_UINT32_LE (buffdata + 52, avimux->auds_hdr.length);
+ GST_WRITE_UINT32_LE (buffdata + 56, avimux->auds_hdr.bufsize);
+ GST_WRITE_UINT32_LE (buffdata + 60, avimux->auds_hdr.quality);
+ GST_WRITE_UINT32_LE (buffdata + 64, avimux->auds_hdr.samplesize);
/* the audio header */
- memcpy (buffdata, "strf", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_strf_auds));
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ memcpy (buffdata + 68, "strf", 4);
+ GST_WRITE_UINT32_LE (buffdata + 72, sizeof (gst_riff_strf_auds));
/* the actual header */
- temp16 = LE_FROM_GUINT16 (avimux->auds.format);
- memcpy (buffdata, &temp16, 2);
- buffdata += 2;
- temp16 = LE_FROM_GUINT16 (avimux->auds.channels);
- memcpy (buffdata, &temp16, 2);
- buffdata += 2;
- temp32 = LE_FROM_GUINT32 (avimux->auds.rate);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->auds.av_bps);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp16 = LE_FROM_GUINT16 (avimux->auds.blockalign);
- memcpy (buffdata, &temp16, 2);
- buffdata += 2;
- temp16 = LE_FROM_GUINT16 (avimux->auds.size);
- memcpy (buffdata, &temp16, 2);
- buffdata += 2;
+ GST_WRITE_UINT16_LE (buffdata + 76, avimux->auds.format);
+ GST_WRITE_UINT16_LE (buffdata + 78, avimux->auds.channels);
+ GST_WRITE_UINT32_LE (buffdata + 80, avimux->auds.rate);
+ GST_WRITE_UINT32_LE (buffdata + 84, avimux->auds.av_bps);
+ GST_WRITE_UINT16_LE (buffdata + 88, avimux->auds.blockalign);
+ GST_WRITE_UINT16_LE (buffdata + 90, avimux->auds.size);
+ buffdata += 92;
+ GST_BUFFER_SIZE (buffer) += 92;
}
if (avimux->video_pad_connected) {
/* odml header */
- memcpy (buffdata, "LIST", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (sizeof (guint32) + 4 * 3);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- memcpy (buffdata, "odml", 4);
- buffdata += 4;
- memcpy (buffdata, "dmlh", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (sizeof (guint32));
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->total_frames);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
+ memcpy (buffdata + 0, "LIST", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4, sizeof (guint32) + 4 * 3);
+ memcpy (buffdata + 8, "odml", 4);
+ memcpy (buffdata + 12, "dmlh", 4);
+ GST_WRITE_UINT32_LE (buffdata + 16, sizeof (guint32));
+ GST_WRITE_UINT32_LE (buffdata + 20, avimux->total_frames);
+ buffdata += 24;
+ GST_BUFFER_SIZE (buffer) += 24;
+ }
+
+ /* tags */
+ if (tags) {
+ guint8 *ptr;
+ guint startsize;
+
+ memcpy (buffdata + 0, "LIST", 4);
+ ptr = buffdata + 4; /* fill in later */
+ startsize = GST_BUFFER_SIZE (buffer) + 4;
+ memcpy (buffdata + 8, "INFO", 4);
+ buffdata += 12;
+ GST_BUFFER_SIZE (buffer) += 12;
+
+ /* 12 bytes is needed for data header */
+ GST_BUFFER_MAXSIZE (buffer) -= 12;
+ gst_tag_list_foreach (tags, gst_avimux_write_tag, buffer);
+ gst_tag_list_free (tags);
+ GST_BUFFER_MAXSIZE (buffer) += 12;
+ buffdata = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer);
+
+ /* update list size */
+ GST_WRITE_UINT32_LE (ptr, GST_BUFFER_SIZE (buffer) - startsize);
}
/* avi data header */
- memcpy (buffdata, "LIST", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (avimux->data_size);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- memcpy (buffdata, "movi", 4);
+ memcpy (buffdata + 0, "LIST", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4, avimux->data_size);
+ memcpy (buffdata + 12, "movi", 4);
+ buffdata += 12;
+ GST_BUFFER_SIZE (buffer) += 12;
return buffer;
}
@@ -870,25 +812,16 @@ gst_avimux_riff_get_avix_header (guint32 datax_size)
{
GstBuffer *buffer;
guint8 *buffdata;
- guint32 temp32;
- buffer = gst_buffer_new ();
- GST_BUFFER_SIZE (buffer) = 24;
- buffdata = GST_BUFFER_DATA (buffer) = g_malloc (GST_BUFFER_SIZE (buffer));
-
- memcpy (buffdata, "LIST", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (datax_size + 4 * 4);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- memcpy (buffdata, "AVIX", 4);
- buffdata += 4;
- memcpy (buffdata, "LIST", 4);
- buffdata += 4;
- temp32 = LE_FROM_GUINT32 (datax_size);
- memcpy (buffdata, &temp32, 4);
- buffdata += 4;
- memcpy (buffdata, "movi", 4);
+ buffer = gst_buffer_new_and_alloc (24);
+ buffdata = GST_BUFFER_DATA (buffer);
+
+ memcpy (buffdata + 0, "LIST", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4, datax_size + 4 * 4);
+ memcpy (buffdata + 8, "AVIX", 4);
+ memcpy (buffdata + 12, "LIST", 4);
+ GST_WRITE_UINT32_LE (buffdata + 16, datax_size);
+ memcpy (buffdata + 20, "movi", 4);
return buffer;
}
@@ -897,14 +830,12 @@ static GstBuffer *
gst_avimux_riff_get_video_header (guint32 video_frame_size)
{
GstBuffer *buffer;
- guint32 temp32;
+ guint8 *buffdata;
- buffer = gst_buffer_new ();
- GST_BUFFER_DATA (buffer) = g_malloc (8);
- GST_BUFFER_SIZE (buffer) = 8;
- memcpy (GST_BUFFER_DATA (buffer), "00db", 4);
- temp32 = LE_FROM_GUINT32 (video_frame_size);
- memcpy (GST_BUFFER_DATA (buffer) + 4, &temp32, 4);
+ buffer = gst_buffer_new_and_alloc (8);
+ buffdata = GST_BUFFER_DATA (buffer);
+ memcpy (buffdata + 0, "00db", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4, video_frame_size);
return buffer;
}
@@ -913,14 +844,12 @@ static GstBuffer *
gst_avimux_riff_get_audio_header (guint32 audio_sample_size)
{
GstBuffer *buffer;
- guint32 temp32;
+ guint8 *buffdata;
- buffer = gst_buffer_new ();
- GST_BUFFER_DATA (buffer) = g_malloc (8);
- GST_BUFFER_SIZE (buffer) = 8;
- memcpy (GST_BUFFER_DATA (buffer), "01wb", 4);
- temp32 = LE_FROM_GUINT32 (audio_sample_size);
- memcpy (GST_BUFFER_DATA (buffer) + 4, &temp32, 4);
+ buffer = gst_buffer_new_and_alloc (8);
+ buffdata = GST_BUFFER_DATA (buffer);
+ memcpy (buffdata + 0, "01wb", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4, audio_sample_size);
return buffer;
}
@@ -948,21 +877,20 @@ static void
gst_avimux_write_index (GstAviMux * avimux)
{
GstBuffer *buffer;
- guint32 temp32;
+ guint8 *buffdata;
- buffer = gst_buffer_new ();
- GST_BUFFER_SIZE (buffer) = 8;
- GST_BUFFER_DATA (buffer) = g_malloc (8);
- memcpy (GST_BUFFER_DATA (buffer), "idx1", 4);
- temp32 = LE_FROM_GUINT32 (avimux->idx_index * sizeof (gst_riff_index_entry));
- memcpy (GST_BUFFER_DATA (buffer) + 4, &temp32, 4);
+ buffer = gst_buffer_new_and_alloc (8);
+ buffdata = GST_BUFFER_DATA (buffer);
+ memcpy (buffdata + 0, "idx1", 4);
+ GST_WRITE_UINT32_LE (buffdata + 4,
+ avimux->idx_index * sizeof (gst_riff_index_entry));
gst_pad_push (avimux->srcpad, GST_DATA (buffer));
buffer = gst_buffer_new ();
GST_BUFFER_SIZE (buffer) = avimux->idx_index * sizeof (gst_riff_index_entry);
- GST_BUFFER_DATA (buffer) = (unsigned char *) avimux->idx;
+ GST_BUFFER_DATA (buffer) = (guint8 *) avimux->idx;
avimux->idx = NULL; /* will be free()'ed by gst_buffer_unref() */
- avimux->total_data += GST_BUFFER_SIZE (buffer);
+ avimux->total_data += GST_BUFFER_SIZE (buffer) + 8;
gst_pad_push (avimux->srcpad, GST_DATA (buffer));
avimux->idx_size += avimux->idx_index * sizeof (gst_riff_index_entry) + 8;
@@ -1038,9 +966,10 @@ gst_avimux_start_file (GstAviMux * avimux)
header = gst_avimux_riff_get_avi_header (avimux);
avimux->total_data += GST_BUFFER_SIZE (header);
- avimux->idx_offset = avimux->total_data;
gst_pad_push (avimux->srcpad, GST_DATA (header));
+ avimux->idx_offset = avimux->total_data;
+
avimux->write_header = FALSE;
avimux->restart = FALSE;
}
@@ -1141,6 +1070,14 @@ gst_avimux_handle_event (GstPad * pad, GstEvent * event)
g_warning ("Unknown pad for EOS!");
}
break;
+ case GST_EVENT_TAG:
+ if (avimux->tags) {
+ gst_tag_list_insert (avimux->tags, gst_event_tag_get_list (event),
+ GST_TAG_MERGE_PREPEND);
+ } else {
+ avimux->tags = gst_tag_list_copy (gst_event_tag_get_list (event));
+ }
+ break;
default:
break;
}
@@ -1383,6 +1320,12 @@ gst_avimux_change_state (GstElement * element)
case GST_STATE_PAUSED_TO_PLAYING:
avimux->video_pad_eos = avimux->audio_pad_eos = FALSE;
break;
+ case GST_STATE_PAUSED_TO_READY:
+ if (avimux->tags) {
+ gst_tag_list_free (avimux->tags);
+ avimux->tags = NULL;
+ }
+ break;
}
if (GST_ELEMENT_CLASS (parent_class)->change_state)
diff --git a/gst/avi/gstavimux.h b/gst/avi/gstavimux.h
index 452b7221..d814941d 100644
--- a/gst/avi/gstavimux.h
+++ b/gst/avi/gstavimux.h
@@ -77,6 +77,9 @@ struct _GstAviMux {
gst_riff_strh auds_hdr;
gst_riff_strf_auds auds;
+ /* tags */
+ GstTagList *tags;
+
/* information about the AVI index ('idx') */
gst_riff_index_entry *idx;
gint idx_index, idx_count;