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

View File

@ -178,9 +178,16 @@ gst_avimux_get_type (void)
0, 0,
(GInstanceInitFunc) gst_avimux_init, (GInstanceInitFunc) gst_avimux_init,
}; };
static const GInterfaceInfo tag_setter_info = {
NULL,
NULL,
NULL
};
avimux_type = avimux_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstAviMux", &avimux_info, 0); 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; return avimux_type;
} }
@ -274,6 +281,7 @@ gst_avimux_init (GstAviMux * avimux)
avimux->auds_hdr.type = GST_MAKE_FOURCC ('a', 'u', 'd', 's'); avimux->auds_hdr.type = GST_MAKE_FOURCC ('a', 'u', 'd', 's');
avimux->vids_hdr.quality = 0xFFFFFFFF; avimux->vids_hdr.quality = 0xFFFFFFFF;
avimux->auds_hdr.quality = 0xFFFFFFFF; avimux->auds_hdr.quality = 0xFFFFFFFF;
avimux->tags = NULL;
avimux->idx = 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) */ /* 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 * static GstBuffer *
gst_avimux_riff_get_avi_header (GstAviMux * avimux) gst_avimux_riff_get_avi_header (GstAviMux * avimux)
{ {
GstTagList *tags;
const GstTagList *iface_tags;
GstBuffer *buffer; GstBuffer *buffer;
guint8 *buffdata; guint8 *buffdata;
guint16 temp16; guint size = 0;
guint32 temp32;
buffer = gst_buffer_new ();
/* first, let's see what actually needs to be in the buffer */ /* first, let's see what actually needs to be in the buffer */
GST_BUFFER_SIZE (buffer) = 0; size += 32 + sizeof (gst_riff_avih); /* avi header */
GST_BUFFER_SIZE (buffer) += 32 + sizeof (gst_riff_avih); /* avi header */
if (avimux->video_pad_connected) { /* we have video */ if (avimux->video_pad_connected) { /* we have video */
GST_BUFFER_SIZE (buffer) += 28 + sizeof (gst_riff_strh) + sizeof (gst_riff_strf_vids); /* vid hdr */ size += 28 + sizeof (gst_riff_strh) + sizeof (gst_riff_strf_vids); /* vid hdr */
GST_BUFFER_SIZE (buffer) += 24; /* odml header */ size += 24; /* odml header */
} }
if (avimux->audio_pad_connected) { /* we have audio */ 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" */ /* this is the "riff size" */
avimux->header_size = GST_BUFFER_SIZE (buffer); avimux->header_size = size;
GST_BUFFER_SIZE (buffer) += 12; /* avi data header */ 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 */ /* 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 */ /* avi header metadata */
memcpy (buffdata, "RIFF", 4); memcpy (buffdata + 0, "RIFF", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 4,
temp32 = avimux->header_size + avimux->idx_size + avimux->data_size);
LE_FROM_GUINT32 (avimux->header_size + avimux->idx_size + memcpy (buffdata + 8, "AVI ", 4);
avimux->data_size); memcpy (buffdata + 12, "LIST", 4);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 16, avimux->header_size - 4 * 5);
buffdata += 4; memcpy (buffdata + 20, "hdrl", 4);
memcpy (buffdata, "AVI ", 4); memcpy (buffdata + 24, "avih", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 28, sizeof (gst_riff_avih));
memcpy (buffdata, "LIST", 4); buffdata += 32;
buffdata += 4; GST_BUFFER_SIZE (buffer) += 32;
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;
/* the AVI header itself */ /* the AVI header itself */
temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.us_frame); GST_WRITE_UINT32_LE (buffdata + 0, avimux->avi_hdr.us_frame);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 4, avimux->avi_hdr.max_bps);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 8, avimux->avi_hdr.pad_gran);
temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.max_bps); GST_WRITE_UINT32_LE (buffdata + 12, avimux->avi_hdr.flags);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 16, avimux->avi_hdr.tot_frames);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 20, avimux->avi_hdr.init_frames);
temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.pad_gran); GST_WRITE_UINT32_LE (buffdata + 24, avimux->avi_hdr.streams);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 28, avimux->avi_hdr.bufsize);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 32, avimux->avi_hdr.width);
temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.flags); GST_WRITE_UINT32_LE (buffdata + 36, avimux->avi_hdr.height);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 40, avimux->avi_hdr.scale);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 44, avimux->avi_hdr.rate);
temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.tot_frames); GST_WRITE_UINT32_LE (buffdata + 48, avimux->avi_hdr.start);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 52, avimux->avi_hdr.length);
buffdata += 4; buffdata += 56;
temp32 = LE_FROM_GUINT32 (avimux->avi_hdr.init_frames); GST_BUFFER_SIZE (buffer) += 56;
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;
if (avimux->video_pad_connected) { if (avimux->video_pad_connected) {
/* video header metadata */ /* video header metadata */
memcpy (buffdata, "LIST", 4); memcpy (buffdata + 0, "LIST", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 4,
temp32 = sizeof (gst_riff_strh) + sizeof (gst_riff_strf_vids) + 4 * 5);
LE_FROM_GUINT32 (sizeof (gst_riff_strh) + sizeof (gst_riff_strf_vids) + memcpy (buffdata + 8, "strl", 4);
4 * 5);
memcpy (buffdata, &temp32, 4);
buffdata += 4;
memcpy (buffdata, "strl", 4);
buffdata += 4;
/* generic header */ /* generic header */
memcpy (buffdata, "strh", 4); memcpy (buffdata + 12, "strh", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 16, sizeof (gst_riff_strh));
temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_strh));
memcpy (buffdata, &temp32, 4);
buffdata += 4;
/* the actual header */ /* the actual header */
temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.type); GST_WRITE_UINT32_LE (buffdata + 20, avimux->vids_hdr.type);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 24, avimux->vids_hdr.fcc_handler);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 28, avimux->vids_hdr.flags);
temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.fcc_handler); GST_WRITE_UINT32_LE (buffdata + 32, avimux->vids_hdr.priority);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 36, avimux->vids_hdr.init_frames);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 40, avimux->vids_hdr.scale);
temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.flags); GST_WRITE_UINT32_LE (buffdata + 44, avimux->vids_hdr.rate);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 48, avimux->vids_hdr.start);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 52, avimux->vids_hdr.length);
temp32 = LE_FROM_GUINT32 (avimux->vids_hdr.priority); GST_WRITE_UINT32_LE (buffdata + 56, avimux->vids_hdr.bufsize);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 60, avimux->vids_hdr.quality);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 64, avimux->vids_hdr.samplesize);
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;
/* the video header */ /* the video header */
memcpy (buffdata, "strf", 4); memcpy (buffdata + 68, "strf", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 72, sizeof (gst_riff_strf_vids));
temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_strf_vids));
memcpy (buffdata, &temp32, 4);
buffdata += 4;
/* the actual header */ /* the actual header */
temp32 = LE_FROM_GUINT32 (avimux->vids.size); GST_WRITE_UINT32_LE (buffdata + 76, avimux->vids.size);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 80, avimux->vids.width);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 84, avimux->vids.height);
temp32 = LE_FROM_GUINT32 (avimux->vids.width); GST_WRITE_UINT16_LE (buffdata + 88, avimux->vids.planes);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT16_LE (buffdata + 90, avimux->vids.bit_cnt);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 92, avimux->vids.compression);
temp32 = LE_FROM_GUINT32 (avimux->vids.height); GST_WRITE_UINT32_LE (buffdata + 96, avimux->vids.image_size);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 100, avimux->vids.xpels_meter);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 104, avimux->vids.ypels_meter);
temp16 = LE_FROM_GUINT16 (avimux->vids.planes); GST_WRITE_UINT32_LE (buffdata + 108, avimux->vids.num_colors);
memcpy (buffdata, &temp16, 2); GST_WRITE_UINT32_LE (buffdata + 112, avimux->vids.imp_colors);
buffdata += 2; buffdata += 116;
temp16 = LE_FROM_GUINT16 (avimux->vids.bit_cnt); GST_BUFFER_SIZE (buffer) += 116;
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;
} }
if (avimux->audio_pad_connected) { if (avimux->audio_pad_connected) {
/* audio header */ /* audio header */
memcpy (buffdata, "LIST", 4); memcpy (buffdata + 0, "LIST", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 4,
temp32 = sizeof (gst_riff_strh) + sizeof (gst_riff_strf_auds) + 4 * 5);
LE_FROM_GUINT32 (sizeof (gst_riff_strh) + sizeof (gst_riff_strf_auds) + memcpy (buffdata + 8, "strl", 4);
4 * 5);
memcpy (buffdata, &temp32, 4);
buffdata += 4;
memcpy (buffdata, "strl", 4);
buffdata += 4;
/* generic header */ /* generic header */
memcpy (buffdata, "strh", 4); memcpy (buffdata + 12, "strh", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 16, sizeof (gst_riff_strh));
temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_strh));
memcpy (buffdata, &temp32, 4);
buffdata += 4;
/* the actual header */ /* the actual header */
temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.type); GST_WRITE_UINT32_LE (buffdata + 20, avimux->auds_hdr.type);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 24, avimux->auds_hdr.fcc_handler);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 28, avimux->auds_hdr.flags);
temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.fcc_handler); GST_WRITE_UINT32_LE (buffdata + 32, avimux->auds_hdr.priority);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 36, avimux->auds_hdr.init_frames);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 40, avimux->auds_hdr.scale);
temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.flags); GST_WRITE_UINT32_LE (buffdata + 44, avimux->auds_hdr.rate);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 48, avimux->auds_hdr.start);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 52, avimux->auds_hdr.length);
temp32 = LE_FROM_GUINT32 (avimux->auds_hdr.priority); GST_WRITE_UINT32_LE (buffdata + 56, avimux->auds_hdr.bufsize);
memcpy (buffdata, &temp32, 4); GST_WRITE_UINT32_LE (buffdata + 60, avimux->auds_hdr.quality);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 64, avimux->auds_hdr.samplesize);
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;
/* the audio header */ /* the audio header */
memcpy (buffdata, "strf", 4); memcpy (buffdata + 68, "strf", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 72, sizeof (gst_riff_strf_auds));
temp32 = LE_FROM_GUINT32 (sizeof (gst_riff_strf_auds));
memcpy (buffdata, &temp32, 4);
buffdata += 4;
/* the actual header */ /* the actual header */
temp16 = LE_FROM_GUINT16 (avimux->auds.format); GST_WRITE_UINT16_LE (buffdata + 76, avimux->auds.format);
memcpy (buffdata, &temp16, 2); GST_WRITE_UINT16_LE (buffdata + 78, avimux->auds.channels);
buffdata += 2; GST_WRITE_UINT32_LE (buffdata + 80, avimux->auds.rate);
temp16 = LE_FROM_GUINT16 (avimux->auds.channels); GST_WRITE_UINT32_LE (buffdata + 84, avimux->auds.av_bps);
memcpy (buffdata, &temp16, 2); GST_WRITE_UINT16_LE (buffdata + 88, avimux->auds.blockalign);
buffdata += 2; GST_WRITE_UINT16_LE (buffdata + 90, avimux->auds.size);
temp32 = LE_FROM_GUINT32 (avimux->auds.rate); buffdata += 92;
memcpy (buffdata, &temp32, 4); GST_BUFFER_SIZE (buffer) += 92;
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;
} }
if (avimux->video_pad_connected) { if (avimux->video_pad_connected) {
/* odml header */ /* odml header */
memcpy (buffdata, "LIST", 4); memcpy (buffdata + 0, "LIST", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 4, sizeof (guint32) + 4 * 3);
temp32 = LE_FROM_GUINT32 (sizeof (guint32) + 4 * 3); memcpy (buffdata + 8, "odml", 4);
memcpy (buffdata, &temp32, 4); memcpy (buffdata + 12, "dmlh", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 16, sizeof (guint32));
memcpy (buffdata, "odml", 4); GST_WRITE_UINT32_LE (buffdata + 20, avimux->total_frames);
buffdata += 4; buffdata += 24;
memcpy (buffdata, "dmlh", 4); GST_BUFFER_SIZE (buffer) += 24;
buffdata += 4; }
temp32 = LE_FROM_GUINT32 (sizeof (guint32));
memcpy (buffdata, &temp32, 4); /* tags */
buffdata += 4; if (tags) {
temp32 = LE_FROM_GUINT32 (avimux->total_frames); guint8 *ptr;
memcpy (buffdata, &temp32, 4); guint startsize;
buffdata += 4;
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 */ /* avi data header */
memcpy (buffdata, "LIST", 4); memcpy (buffdata + 0, "LIST", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 4, avimux->data_size);
temp32 = LE_FROM_GUINT32 (avimux->data_size); memcpy (buffdata + 12, "movi", 4);
memcpy (buffdata, &temp32, 4); buffdata += 12;
buffdata += 4; GST_BUFFER_SIZE (buffer) += 12;
memcpy (buffdata, "movi", 4);
return buffer; return buffer;
} }
@ -870,25 +812,16 @@ gst_avimux_riff_get_avix_header (guint32 datax_size)
{ {
GstBuffer *buffer; GstBuffer *buffer;
guint8 *buffdata; guint8 *buffdata;
guint32 temp32;
buffer = gst_buffer_new (); buffer = gst_buffer_new_and_alloc (24);
GST_BUFFER_SIZE (buffer) = 24; buffdata = GST_BUFFER_DATA (buffer);
buffdata = GST_BUFFER_DATA (buffer) = g_malloc (GST_BUFFER_SIZE (buffer));
memcpy (buffdata, "LIST", 4); memcpy (buffdata + 0, "LIST", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 4, datax_size + 4 * 4);
temp32 = LE_FROM_GUINT32 (datax_size + 4 * 4); memcpy (buffdata + 8, "AVIX", 4);
memcpy (buffdata, &temp32, 4); memcpy (buffdata + 12, "LIST", 4);
buffdata += 4; GST_WRITE_UINT32_LE (buffdata + 16, datax_size);
memcpy (buffdata, "AVIX", 4); memcpy (buffdata + 20, "movi", 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);
return buffer; return buffer;
} }
@ -897,14 +830,12 @@ static GstBuffer *
gst_avimux_riff_get_video_header (guint32 video_frame_size) gst_avimux_riff_get_video_header (guint32 video_frame_size)
{ {
GstBuffer *buffer; GstBuffer *buffer;
guint32 temp32; guint8 *buffdata;
buffer = gst_buffer_new (); buffer = gst_buffer_new_and_alloc (8);
GST_BUFFER_DATA (buffer) = g_malloc (8); buffdata = GST_BUFFER_DATA (buffer);
GST_BUFFER_SIZE (buffer) = 8; memcpy (buffdata + 0, "00db", 4);
memcpy (GST_BUFFER_DATA (buffer), "00db", 4); GST_WRITE_UINT32_LE (buffdata + 4, video_frame_size);
temp32 = LE_FROM_GUINT32 (video_frame_size);
memcpy (GST_BUFFER_DATA (buffer) + 4, &temp32, 4);
return buffer; return buffer;
} }
@ -913,14 +844,12 @@ static GstBuffer *
gst_avimux_riff_get_audio_header (guint32 audio_sample_size) gst_avimux_riff_get_audio_header (guint32 audio_sample_size)
{ {
GstBuffer *buffer; GstBuffer *buffer;
guint32 temp32; guint8 *buffdata;
buffer = gst_buffer_new (); buffer = gst_buffer_new_and_alloc (8);
GST_BUFFER_DATA (buffer) = g_malloc (8); buffdata = GST_BUFFER_DATA (buffer);
GST_BUFFER_SIZE (buffer) = 8; memcpy (buffdata + 0, "01wb", 4);
memcpy (GST_BUFFER_DATA (buffer), "01wb", 4); GST_WRITE_UINT32_LE (buffdata + 4, audio_sample_size);
temp32 = LE_FROM_GUINT32 (audio_sample_size);
memcpy (GST_BUFFER_DATA (buffer) + 4, &temp32, 4);
return buffer; return buffer;
} }
@ -948,21 +877,20 @@ static void
gst_avimux_write_index (GstAviMux * avimux) gst_avimux_write_index (GstAviMux * avimux)
{ {
GstBuffer *buffer; GstBuffer *buffer;
guint32 temp32; guint8 *buffdata;
buffer = gst_buffer_new (); buffer = gst_buffer_new_and_alloc (8);
GST_BUFFER_SIZE (buffer) = 8; buffdata = GST_BUFFER_DATA (buffer);
GST_BUFFER_DATA (buffer) = g_malloc (8); memcpy (buffdata + 0, "idx1", 4);
memcpy (GST_BUFFER_DATA (buffer), "idx1", 4); GST_WRITE_UINT32_LE (buffdata + 4,
temp32 = LE_FROM_GUINT32 (avimux->idx_index * sizeof (gst_riff_index_entry)); avimux->idx_index * sizeof (gst_riff_index_entry));
memcpy (GST_BUFFER_DATA (buffer) + 4, &temp32, 4);
gst_pad_push (avimux->srcpad, GST_DATA (buffer)); gst_pad_push (avimux->srcpad, GST_DATA (buffer));
buffer = gst_buffer_new (); buffer = gst_buffer_new ();
GST_BUFFER_SIZE (buffer) = avimux->idx_index * sizeof (gst_riff_index_entry); 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->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)); gst_pad_push (avimux->srcpad, GST_DATA (buffer));
avimux->idx_size += avimux->idx_index * sizeof (gst_riff_index_entry) + 8; 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); header = gst_avimux_riff_get_avi_header (avimux);
avimux->total_data += GST_BUFFER_SIZE (header); avimux->total_data += GST_BUFFER_SIZE (header);
avimux->idx_offset = avimux->total_data;
gst_pad_push (avimux->srcpad, GST_DATA (header)); gst_pad_push (avimux->srcpad, GST_DATA (header));
avimux->idx_offset = avimux->total_data;
avimux->write_header = FALSE; avimux->write_header = FALSE;
avimux->restart = FALSE; avimux->restart = FALSE;
} }
@ -1141,6 +1070,14 @@ gst_avimux_handle_event (GstPad * pad, GstEvent * event)
g_warning ("Unknown pad for EOS!"); g_warning ("Unknown pad for EOS!");
} }
break; 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: default:
break; break;
} }
@ -1383,6 +1320,12 @@ gst_avimux_change_state (GstElement * element)
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
avimux->video_pad_eos = avimux->audio_pad_eos = FALSE; avimux->video_pad_eos = avimux->audio_pad_eos = FALSE;
break; 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) if (GST_ELEMENT_CLASS (parent_class)->change_state)

View File

@ -77,6 +77,9 @@ struct _GstAviMux {
gst_riff_strh auds_hdr; gst_riff_strh auds_hdr;
gst_riff_strf_auds auds; gst_riff_strf_auds auds;
/* tags */
GstTagList *tags;
/* information about the AVI index ('idx') */ /* information about the AVI index ('idx') */
gst_riff_index_entry *idx; gst_riff_index_entry *idx;
gint idx_index, idx_count; gint idx_index, idx_count;