aiffmux: drop data after 4ish GB and moan

https://bugzilla.gnome.org/show_bug.cgi?id=654278
This commit is contained in:
Vincent Penquerc'h 2011-08-16 10:24:37 +01:00 committed by Tim-Philipp Müller
parent 76c0f9bfe7
commit 0381919e83
2 changed files with 27 additions and 0 deletions

View file

@ -130,6 +130,7 @@ gst_aiff_mux_change_state (GstElement * element, GstStateChange transition)
aiffmux->length = 0; aiffmux->length = 0;
aiffmux->rate = 0.0; aiffmux->rate = 0.0;
aiffmux->sent_header = FALSE; aiffmux->sent_header = FALSE;
aiffmux->overflow = FALSE;
break; break;
default: default:
break; break;
@ -296,12 +297,16 @@ gst_aiff_mux_chain (GstPad * pad, GstBuffer * buf)
{ {
GstAiffMux *aiffmux = GST_AIFF_MUX (GST_PAD_PARENT (pad)); GstAiffMux *aiffmux = GST_AIFF_MUX (GST_PAD_PARENT (pad));
GstFlowReturn flow = GST_FLOW_OK; GstFlowReturn flow = GST_FLOW_OK;
guint64 cur_size;
if (!aiffmux->channels) { if (!aiffmux->channels) {
gst_buffer_unref (buf); gst_buffer_unref (buf);
return GST_FLOW_NOT_NEGOTIATED; return GST_FLOW_NOT_NEGOTIATED;
} }
if (G_UNLIKELY (aiffmux->overflow))
goto overflow;
if (!aiffmux->sent_header) { if (!aiffmux->sent_header) {
/* use bogus size initially, we'll write the real /* use bogus size initially, we'll write the real
* header when we get EOS and know the exact length */ * header when we get EOS and know the exact length */
@ -316,6 +321,20 @@ gst_aiff_mux_chain (GstPad * pad, GstBuffer * buf)
aiffmux->sent_header = TRUE; aiffmux->sent_header = TRUE;
} }
/* AIFF has an audio data size limit of slightly under 4 GB.
A value of audiosize + AIFF_HEADER_LEN - 8 is written, so
I'll error out if writing data that makes this overflow. */
cur_size = aiffmux->length + AIFF_HEADER_LEN - 8;
if (G_UNLIKELY (cur_size + GST_BUFFER_SIZE (buf) >= G_MAXUINT32)) {
GST_ERROR_OBJECT (aiffmux, "AIFF only supports about 4 GB worth of "
"audio data, dropping any further data on the floor");
GST_ELEMENT_WARNING (aiffmux, STREAM, MUX, ("AIFF has a 4GB size limit"),
("AIFF only supports about 4 GB worth of audio data, "
"dropping any further data on the floor"));
aiffmux->overflow = TRUE;
goto overflow;
}
GST_LOG_OBJECT (aiffmux, "pushing %u bytes raw audio, ts=%" GST_TIME_FORMAT, GST_LOG_OBJECT (aiffmux, "pushing %u bytes raw audio, ts=%" GST_TIME_FORMAT,
GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
@ -330,6 +349,13 @@ gst_aiff_mux_chain (GstPad * pad, GstBuffer * buf)
flow = gst_pad_push (aiffmux->srcpad, buf); flow = gst_pad_push (aiffmux->srcpad, buf);
return flow; return flow;
overflow:
{
GST_WARNING_OBJECT (aiffmux, "output file too large, dropping buffer");
gst_buffer_unref (buf);
return GST_FLOW_OK;
}
} }
static gboolean static gboolean

View file

@ -81,6 +81,7 @@ struct _GstAiffMux
gdouble rate; gdouble rate;
gboolean sent_header; gboolean sent_header;
gboolean overflow;
}; };
struct _GstAiffMuxClass struct _GstAiffMuxClass