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.
This commit is contained in:
Ronald S. Bultje 2005-01-19 11:01:09 +00:00
parent 079805f0c9
commit 471c844eb5
3 changed files with 260 additions and 298 deletions

View file

@ -1,3 +1,19 @@
2005-01-19 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* 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.
2005-01-18 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* gst/playback/gststreaminfo.c: (gst_stream_info_dispose):

View file

@ -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));
buffer = gst_buffer_new_and_alloc (24);
buffdata = GST_BUFFER_DATA (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);
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)

View file

@ -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;