mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 13:06:23 +00:00
avi: port to 0.11 API
This commit is contained in:
parent
ea65d34cef
commit
14b65031bc
2 changed files with 268 additions and 184 deletions
|
@ -970,9 +970,10 @@ gst_avi_demux_peek_chunk_info (GstAviDemux * avi, guint32 * tag, guint32 * size)
|
||||||
if (gst_adapter_available (avi->adapter) < 8)
|
if (gst_adapter_available (avi->adapter) < 8)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
data = gst_adapter_peek (avi->adapter, 8);
|
data = gst_adapter_map (avi->adapter, 8);
|
||||||
*tag = GST_READ_UINT32_LE (data);
|
*tag = GST_READ_UINT32_LE (data);
|
||||||
*size = GST_READ_UINT32_LE (data + 4);
|
*size = GST_READ_UINT32_LE (data + 4);
|
||||||
|
gst_adapter_unmap (avi->adapter, 0);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1151,14 +1152,17 @@ gst_avi_demux_parse_avih (GstAviDemux * avi,
|
||||||
GstBuffer * buf, gst_riff_avih ** _avih)
|
GstBuffer * buf, gst_riff_avih ** _avih)
|
||||||
{
|
{
|
||||||
gst_riff_avih *avih;
|
gst_riff_avih *avih;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
goto no_buffer;
|
goto no_buffer;
|
||||||
|
|
||||||
if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_avih))
|
size = gst_buffer_get_size (buf);
|
||||||
|
if (size < sizeof (gst_riff_avih))
|
||||||
goto avih_too_small;
|
goto avih_too_small;
|
||||||
|
|
||||||
avih = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
avih = g_malloc (size);
|
||||||
|
gst_buffer_extract (buf, 0, avih, size);
|
||||||
|
|
||||||
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||||
avih->us_frame = GUINT32_FROM_LE (avih->us_frame);
|
avih->us_frame = GUINT32_FROM_LE (avih->us_frame);
|
||||||
|
@ -1218,7 +1222,7 @@ avih_too_small:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
||||||
("Too small avih (%d available, %d needed)",
|
("Too small avih (%d available, %d needed)",
|
||||||
GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_avih)));
|
size, (int) sizeof (gst_riff_avih)));
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1245,16 +1249,18 @@ gst_avi_demux_parse_superindex (GstAviDemux * avi,
|
||||||
guint16 bpe = 16;
|
guint16 bpe = 16;
|
||||||
guint32 num, i;
|
guint32 num, i;
|
||||||
guint64 *indexes;
|
guint64 *indexes;
|
||||||
guint size;
|
gsize size;
|
||||||
|
|
||||||
*_indexes = NULL;
|
*_indexes = NULL;
|
||||||
|
|
||||||
size = buf ? GST_BUFFER_SIZE (buf) : 0;
|
if (buf)
|
||||||
|
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||||
|
else
|
||||||
|
size = 0;
|
||||||
|
|
||||||
if (size < 24)
|
if (size < 24)
|
||||||
goto too_small;
|
goto too_small;
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buf);
|
|
||||||
|
|
||||||
/* check type of index. The opendml2 specs state that
|
/* check type of index. The opendml2 specs state that
|
||||||
* there should be 4 dwords per array entry. Type can be
|
* there should be 4 dwords per array entry. Type can be
|
||||||
* either frame or field (and we don't care). */
|
* either frame or field (and we don't care). */
|
||||||
|
@ -1285,6 +1291,7 @@ gst_avi_demux_parse_superindex (GstAviDemux * avi,
|
||||||
indexes[i] = GST_BUFFER_OFFSET_NONE;
|
indexes[i] = GST_BUFFER_OFFSET_NONE;
|
||||||
*_indexes = indexes;
|
*_indexes = indexes;
|
||||||
|
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1294,15 +1301,17 @@ too_small:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (avi,
|
GST_ERROR_OBJECT (avi,
|
||||||
"Not enough data to parse superindex (%d available, 24 needed)", size);
|
"Not enough data to parse superindex (%d available, 24 needed)", size);
|
||||||
if (buf)
|
if (buf) {
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
invalid_params:
|
invalid_params:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (avi, "invalid index parameters (num = %d, bpe = %d)",
|
GST_ERROR_OBJECT (avi, "invalid index parameters (num = %d, bpe = %d)",
|
||||||
num, bpe);
|
num, bpe);
|
||||||
if (buf)
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1508,19 +1517,16 @@ gst_avi_demux_parse_subindex (GstAviDemux * avi, GstAviStream * stream,
|
||||||
guint16 bpe;
|
guint16 bpe;
|
||||||
guint32 num, i;
|
guint32 num, i;
|
||||||
guint64 baseoff;
|
guint64 baseoff;
|
||||||
guint size;
|
gsize size;
|
||||||
|
|
||||||
if (!buf)
|
if (buf == NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
size = GST_BUFFER_SIZE (buf);
|
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||||
|
|
||||||
/* check size */
|
/* check size */
|
||||||
if (size < 24)
|
if (size < 24)
|
||||||
goto too_small;
|
goto too_small;
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buf);
|
|
||||||
|
|
||||||
/* We don't support index-data yet */
|
/* We don't support index-data yet */
|
||||||
if (data[3] & 0x80)
|
if (data[3] & 0x80)
|
||||||
goto not_implemented;
|
goto not_implemented;
|
||||||
|
@ -1570,6 +1576,8 @@ gst_avi_demux_parse_subindex (GstAviDemux * avi, GstAviStream * stream,
|
||||||
if (G_UNLIKELY (!gst_avi_demux_add_index (avi, stream, num, &entry)))
|
if (G_UNLIKELY (!gst_avi_demux_add_index (avi, stream, num, &entry)))
|
||||||
goto out_of_mem;
|
goto out_of_mem;
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1579,21 +1587,20 @@ too_small:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (avi,
|
GST_ERROR_OBJECT (avi,
|
||||||
"Not enough data to parse subindex (%d available, 24 needed)", size);
|
"Not enough data to parse subindex (%d available, 24 needed)", size);
|
||||||
gst_buffer_unref (buf);
|
goto done; /* continue */
|
||||||
return TRUE; /* continue */
|
|
||||||
}
|
}
|
||||||
not_implemented:
|
not_implemented:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
|
GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
|
||||||
("Subindex-is-data is not implemented"));
|
("Subindex-is-data is not implemented"));
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
empty_index:
|
empty_index:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (avi, "the index is empty");
|
GST_DEBUG_OBJECT (avi, "the index is empty");
|
||||||
gst_buffer_unref (buf);
|
goto done; /* continue */
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
out_of_mem:
|
out_of_mem:
|
||||||
{
|
{
|
||||||
|
@ -1601,6 +1608,7 @@ out_of_mem:
|
||||||
("Cannot allocate memory for %u*%u=%u bytes",
|
("Cannot allocate memory for %u*%u=%u bytes",
|
||||||
(guint) sizeof (GstAviIndexEntry), num,
|
(guint) sizeof (GstAviIndexEntry), num,
|
||||||
(guint) sizeof (GstAviIndexEntry) * num));
|
(guint) sizeof (GstAviIndexEntry) * num));
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1754,14 +1762,18 @@ gst_avi_demux_riff_parse_vprp (GstElement * element,
|
||||||
{
|
{
|
||||||
gst_riff_vprp *vprp;
|
gst_riff_vprp *vprp;
|
||||||
gint k;
|
gint k;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
g_return_val_if_fail (buf != NULL, FALSE);
|
g_return_val_if_fail (buf != NULL, FALSE);
|
||||||
g_return_val_if_fail (_vprp != NULL, FALSE);
|
g_return_val_if_fail (_vprp != NULL, FALSE);
|
||||||
|
|
||||||
if (GST_BUFFER_SIZE (buf) < G_STRUCT_OFFSET (gst_riff_vprp, field_info))
|
size = gst_buffer_get_size (buf);
|
||||||
|
|
||||||
|
if (size < G_STRUCT_OFFSET (gst_riff_vprp, field_info))
|
||||||
goto too_small;
|
goto too_small;
|
||||||
|
|
||||||
vprp = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
vprp = g_malloc (size);
|
||||||
|
gst_buffer_extract (buf, 0, vprp, size);
|
||||||
|
|
||||||
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||||
vprp->format_token = GUINT32_FROM_LE (vprp->format_token);
|
vprp->format_token = GUINT32_FROM_LE (vprp->format_token);
|
||||||
|
@ -1777,8 +1789,7 @@ gst_avi_demux_riff_parse_vprp (GstElement * element,
|
||||||
|
|
||||||
/* size checking */
|
/* size checking */
|
||||||
/* calculate fields based on size */
|
/* calculate fields based on size */
|
||||||
k = (GST_BUFFER_SIZE (buf) - G_STRUCT_OFFSET (gst_riff_vprp, field_info)) /
|
k = (size - G_STRUCT_OFFSET (gst_riff_vprp, field_info)) / vprp->fields;
|
||||||
vprp->fields;
|
|
||||||
if (vprp->fields > k) {
|
if (vprp->fields > k) {
|
||||||
GST_WARNING_OBJECT (element,
|
GST_WARNING_OBJECT (element,
|
||||||
"vprp header indicated %d fields, only %d available", vprp->fields, k);
|
"vprp header indicated %d fields, only %d available", vprp->fields, k);
|
||||||
|
@ -1850,8 +1861,7 @@ too_small:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (element,
|
GST_ERROR_OBJECT (element,
|
||||||
"Too small vprp (%d available, at least %d needed)",
|
"Too small vprp (%d available, at least %d needed)",
|
||||||
GST_BUFFER_SIZE (buf),
|
size, (int) G_STRUCT_OFFSET (gst_riff_vprp, field_info));
|
||||||
(int) G_STRUCT_OFFSET (gst_riff_vprp, field_info));
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1893,14 +1903,20 @@ gst_avi_demux_expose_streams (GstAviDemux * avi, gboolean force)
|
||||||
static inline void
|
static inline void
|
||||||
gst_avi_demux_roundup_list (GstAviDemux * avi, GstBuffer ** buf)
|
gst_avi_demux_roundup_list (GstAviDemux * avi, GstBuffer ** buf)
|
||||||
{
|
{
|
||||||
if (G_UNLIKELY (GST_BUFFER_SIZE (*buf) & 1)) {
|
gsize size;
|
||||||
GstBuffer *obuf;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (avi, "rounding up dubious list size %d",
|
size = gst_buffer_get_size (*buf);
|
||||||
GST_BUFFER_SIZE (*buf));
|
|
||||||
obuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + 1);
|
if (G_UNLIKELY (size & 1)) {
|
||||||
memcpy (GST_BUFFER_DATA (obuf), GST_BUFFER_DATA (*buf),
|
GstBuffer *obuf;
|
||||||
GST_BUFFER_SIZE (*buf));
|
guint8 *data;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (avi, "rounding up dubious list size %d", size);
|
||||||
|
obuf = gst_buffer_new_and_alloc (size + 1);
|
||||||
|
|
||||||
|
data = gst_buffer_map (obuf, NULL, NULL, GST_MAP_WRITE);
|
||||||
|
gst_buffer_extract (*buf, 0, data, size);
|
||||||
|
gst_buffer_unmap (obuf, data, size + 1);
|
||||||
gst_buffer_replace (buf, obuf);
|
gst_buffer_replace (buf, obuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2125,9 +2141,12 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
|
||||||
case GST_RIFF_TAG_strn:
|
case GST_RIFF_TAG_strn:
|
||||||
g_free (stream->name);
|
g_free (stream->name);
|
||||||
if (sub != NULL) {
|
if (sub != NULL) {
|
||||||
stream->name =
|
gchar *bdata;
|
||||||
g_strndup ((gchar *) GST_BUFFER_DATA (sub),
|
gsize bsize;
|
||||||
(gsize) GST_BUFFER_SIZE (sub));
|
|
||||||
|
bdata = gst_buffer_map (sub, &bsize, NULL, GST_MAP_READ);
|
||||||
|
stream->name = g_strndup (bdata, bsize);
|
||||||
|
gst_buffer_unmap (sub, bdata, bsize);
|
||||||
gst_buffer_unref (sub);
|
gst_buffer_unref (sub);
|
||||||
sub = NULL;
|
sub = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2363,20 +2382,26 @@ gst_avi_demux_parse_odml (GstAviDemux * avi, GstBuffer * buf)
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case GST_RIFF_TAG_dmlh:{
|
case GST_RIFF_TAG_dmlh:{
|
||||||
gst_riff_dmlh dmlh, *_dmlh;
|
gst_riff_dmlh dmlh, *_dmlh;
|
||||||
guint size;
|
gsize size;
|
||||||
|
guint8 *data;
|
||||||
|
|
||||||
/* sub == NULL is possible and means an empty buffer */
|
/* sub == NULL is possible and means an empty buffer */
|
||||||
size = sub ? GST_BUFFER_SIZE (sub) : 0;
|
if (sub == NULL)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
data = gst_buffer_map (sub, &size, NULL, GST_MAP_READ);
|
||||||
|
|
||||||
/* check size */
|
/* check size */
|
||||||
if (size < sizeof (gst_riff_dmlh)) {
|
if (size < sizeof (gst_riff_dmlh)) {
|
||||||
GST_ERROR_OBJECT (avi,
|
GST_ERROR_OBJECT (avi,
|
||||||
"DMLH entry is too small (%d bytes, %d needed)",
|
"DMLH entry is too small (%d bytes, %d needed)",
|
||||||
size, (int) sizeof (gst_riff_dmlh));
|
size, (int) sizeof (gst_riff_dmlh));
|
||||||
|
gst_buffer_unmap (sub, data, size);
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
_dmlh = (gst_riff_dmlh *) GST_BUFFER_DATA (sub);
|
_dmlh = (gst_riff_dmlh *) data;
|
||||||
dmlh.totalframes = GST_READ_UINT32_LE (&_dmlh->totalframes);
|
dmlh.totalframes = GST_READ_UINT32_LE (&_dmlh->totalframes);
|
||||||
|
gst_buffer_unmap (sub, data, size);
|
||||||
|
|
||||||
GST_INFO_OBJECT (avi, "dmlh tag found: totalframes: %u",
|
GST_INFO_OBJECT (avi, "dmlh tag found: totalframes: %u",
|
||||||
dmlh.totalframes);
|
dmlh.totalframes);
|
||||||
|
@ -2555,7 +2580,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
guint64 pos_before;
|
guint64 pos_before;
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
guint size;
|
gsize size;
|
||||||
guint i, num, n;
|
guint i, num, n;
|
||||||
gst_riff_index_entry *index;
|
gst_riff_index_entry *index;
|
||||||
GstClockTime stamp;
|
GstClockTime stamp;
|
||||||
|
@ -2566,8 +2591,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buf);
|
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||||
size = GST_BUFFER_SIZE (buf);
|
|
||||||
|
|
||||||
stamp = gst_util_get_timestamp ();
|
stamp = gst_util_get_timestamp ();
|
||||||
|
|
||||||
|
@ -2630,6 +2654,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
/* get stream stats now */
|
/* get stream stats now */
|
||||||
|
@ -2645,6 +2670,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
|
||||||
empty_list:
|
empty_list:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (avi, "empty index");
|
GST_DEBUG_OBJECT (avi, "empty index");
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2654,6 +2680,7 @@ out_of_mem:
|
||||||
("Cannot allocate memory for %u*%u=%u bytes",
|
("Cannot allocate memory for %u*%u=%u bytes",
|
||||||
(guint) sizeof (GstAviIndexEntry), num,
|
(guint) sizeof (GstAviIndexEntry), num,
|
||||||
(guint) sizeof (GstAviIndexEntry) * num));
|
(guint) sizeof (GstAviIndexEntry) * num));
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2673,6 +2700,8 @@ gst_avi_demux_stream_index (GstAviDemux * avi)
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
guint32 tag;
|
guint32 tag;
|
||||||
guint32 size;
|
guint32 size;
|
||||||
|
gsize bsize;
|
||||||
|
guint8 *bdata;
|
||||||
|
|
||||||
GST_DEBUG ("demux stream index at offset %" G_GUINT64_FORMAT, offset);
|
GST_DEBUG ("demux stream index at offset %" G_GUINT64_FORMAT, offset);
|
||||||
|
|
||||||
|
@ -2680,34 +2709,41 @@ gst_avi_demux_stream_index (GstAviDemux * avi)
|
||||||
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
|
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
|
||||||
if (res != GST_FLOW_OK)
|
if (res != GST_FLOW_OK)
|
||||||
goto pull_failed;
|
goto pull_failed;
|
||||||
else if (GST_BUFFER_SIZE (buf) < 8)
|
|
||||||
|
bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
|
||||||
|
if (bsize < 8)
|
||||||
goto too_small;
|
goto too_small;
|
||||||
|
|
||||||
/* check tag first before blindy trying to read 'size' bytes */
|
/* check tag first before blindy trying to read 'size' bytes */
|
||||||
tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
|
tag = GST_READ_UINT32_LE (bdata);
|
||||||
size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
|
size = GST_READ_UINT32_LE (bdata + 4);
|
||||||
if (tag == GST_RIFF_TAG_LIST) {
|
if (tag == GST_RIFF_TAG_LIST) {
|
||||||
/* this is the movi tag */
|
/* this is the movi tag */
|
||||||
GST_DEBUG_OBJECT (avi, "skip LIST chunk, size %" G_GUINT32_FORMAT,
|
GST_DEBUG_OBJECT (avi, "skip LIST chunk, size %" G_GUINT32_FORMAT,
|
||||||
(8 + GST_ROUND_UP_2 (size)));
|
(8 + GST_ROUND_UP_2 (size)));
|
||||||
offset += 8 + GST_ROUND_UP_2 (size);
|
offset += 8 + GST_ROUND_UP_2 (size);
|
||||||
|
gst_buffer_unmap (buf, bdata, bsize);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
|
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
|
||||||
if (res != GST_FLOW_OK)
|
if (res != GST_FLOW_OK)
|
||||||
goto pull_failed;
|
goto pull_failed;
|
||||||
else if (GST_BUFFER_SIZE (buf) < 8)
|
|
||||||
|
bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
|
||||||
|
if (bsize < 8)
|
||||||
goto too_small;
|
goto too_small;
|
||||||
tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
|
|
||||||
size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
|
tag = GST_READ_UINT32_LE (bdata);
|
||||||
|
size = GST_READ_UINT32_LE (bdata + 4);
|
||||||
}
|
}
|
||||||
|
gst_buffer_unmap (buf, bdata, bsize);
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
if (tag != GST_RIFF_TAG_idx1)
|
if (tag != GST_RIFF_TAG_idx1)
|
||||||
goto no_index;
|
goto no_index;
|
||||||
if (!size)
|
if (!size)
|
||||||
goto zero_index;
|
goto zero_index;
|
||||||
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
|
|
||||||
GST_DEBUG ("index found at offset %" G_GUINT64_FORMAT, offset);
|
GST_DEBUG ("index found at offset %" G_GUINT64_FORMAT, offset);
|
||||||
|
|
||||||
/* read chunk, advance offset */
|
/* read chunk, advance offset */
|
||||||
|
@ -2716,7 +2752,7 @@ gst_avi_demux_stream_index (GstAviDemux * avi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GST_DEBUG ("will parse index chunk size %u for tag %"
|
GST_DEBUG ("will parse index chunk size %u for tag %"
|
||||||
GST_FOURCC_FORMAT, GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag));
|
GST_FOURCC_FORMAT, gst_buffer_get_size (buf), GST_FOURCC_ARGS (tag));
|
||||||
|
|
||||||
gst_avi_demux_parse_index (avi, buf);
|
gst_avi_demux_parse_index (avi, buf);
|
||||||
|
|
||||||
|
@ -2745,6 +2781,7 @@ pull_failed:
|
||||||
too_small:
|
too_small:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (avi, "Buffer is too small");
|
GST_DEBUG_OBJECT (avi, "Buffer is too small");
|
||||||
|
gst_buffer_unmap (buf, bdata, bsize);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2753,13 +2790,11 @@ no_index:
|
||||||
GST_WARNING_OBJECT (avi,
|
GST_WARNING_OBJECT (avi,
|
||||||
"No index data (idx1) after movi chunk, but %" GST_FOURCC_FORMAT,
|
"No index data (idx1) after movi chunk, but %" GST_FOURCC_FORMAT,
|
||||||
GST_FOURCC_ARGS (tag));
|
GST_FOURCC_ARGS (tag));
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
zero_index:
|
zero_index:
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (avi, "Empty index data (idx1) after movi chunk");
|
GST_WARNING_OBJECT (avi, "Empty index data (idx1) after movi chunk");
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2810,7 +2845,7 @@ gst_avi_demux_stream_index_push (GstAviDemux * avi)
|
||||||
offset += 8 + GST_ROUND_UP_2 (size);
|
offset += 8 + GST_ROUND_UP_2 (size);
|
||||||
|
|
||||||
GST_DEBUG ("will parse index chunk size %u for tag %"
|
GST_DEBUG ("will parse index chunk size %u for tag %"
|
||||||
GST_FOURCC_FORMAT, GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag));
|
GST_FOURCC_FORMAT, gst_buffer_get_size (buf), GST_FOURCC_ARGS (tag));
|
||||||
|
|
||||||
avi->offset = avi->first_movi_offset;
|
avi->offset = avi->first_movi_offset;
|
||||||
gst_avi_demux_parse_index (avi, buf);
|
gst_avi_demux_parse_index (avi, buf);
|
||||||
|
@ -2858,19 +2893,17 @@ gst_avi_demux_peek_tag (GstAviDemux * avi, guint64 offset, guint32 * tag,
|
||||||
{
|
{
|
||||||
GstFlowReturn res = GST_FLOW_OK;
|
GstFlowReturn res = GST_FLOW_OK;
|
||||||
GstBuffer *buf = NULL;
|
GstBuffer *buf = NULL;
|
||||||
guint bufsize;
|
gsize bufsize;
|
||||||
guint8 *bufdata;
|
guint8 *bufdata;
|
||||||
|
|
||||||
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
|
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
|
||||||
if (res != GST_FLOW_OK)
|
if (res != GST_FLOW_OK)
|
||||||
goto pull_failed;
|
goto pull_failed;
|
||||||
|
|
||||||
bufsize = GST_BUFFER_SIZE (buf);
|
bufdata = gst_buffer_map (buf, &bufsize, NULL, GST_MAP_READ);
|
||||||
if (bufsize != 8)
|
if (bufsize != 8)
|
||||||
goto wrong_size;
|
goto wrong_size;
|
||||||
|
|
||||||
bufdata = GST_BUFFER_DATA (buf);
|
|
||||||
|
|
||||||
*tag = GST_READ_UINT32_LE (bufdata);
|
*tag = GST_READ_UINT32_LE (bufdata);
|
||||||
*size = GST_READ_UINT32_LE (bufdata + 4);
|
*size = GST_READ_UINT32_LE (bufdata + 4);
|
||||||
|
|
||||||
|
@ -2879,6 +2912,7 @@ gst_avi_demux_peek_tag (GstAviDemux * avi, guint64 offset, guint32 * tag,
|
||||||
*size, offset + 8, offset + 8 + (gint64) * size);
|
*size, offset + 8, offset + 8 + (gint64) * size);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
gst_buffer_unmap (buf, bufdata, bufsize);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -3152,6 +3186,7 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
|
||||||
gint64 stop;
|
gint64 stop;
|
||||||
gint i;
|
gint i;
|
||||||
GstTagList *tags = NULL;
|
GstTagList *tags = NULL;
|
||||||
|
guint8 fourcc[4];
|
||||||
|
|
||||||
GST_DEBUG ("Reading and parsing avi headers: %d", avi->header_state);
|
GST_DEBUG ("Reading and parsing avi headers: %d", avi->header_state);
|
||||||
|
|
||||||
|
@ -3167,7 +3202,9 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
|
||||||
GST_DEBUG ("Reading %d bytes", size);
|
GST_DEBUG ("Reading %d bytes", size);
|
||||||
buf = gst_adapter_take_buffer (avi->adapter, size);
|
buf = gst_adapter_take_buffer (avi->adapter, size);
|
||||||
|
|
||||||
if (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl)
|
gst_buffer_extract (buf, 0, fourcc, 4);
|
||||||
|
|
||||||
|
if (GST_READ_UINT32_LE (fourcc) != GST_RIFF_LIST_hdrl)
|
||||||
goto header_no_hdrl;
|
goto header_no_hdrl;
|
||||||
|
|
||||||
/* mind padding */
|
/* mind padding */
|
||||||
|
@ -3200,10 +3237,12 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case GST_RIFF_TAG_LIST:
|
case GST_RIFF_TAG_LIST:
|
||||||
if (GST_BUFFER_SIZE (sub) < 4)
|
if (gst_buffer_get_size (sub) < 4)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
switch (GST_READ_UINT32_LE (GST_BUFFER_DATA (sub))) {
|
gst_buffer_extract (sub, 0, fourcc, 4);
|
||||||
|
|
||||||
|
switch (GST_READ_UINT32_LE (fourcc)) {
|
||||||
case GST_RIFF_LIST_strl:
|
case GST_RIFF_LIST_strl:
|
||||||
if (!(gst_avi_demux_parse_stream (avi, sub))) {
|
if (!(gst_avi_demux_parse_stream (avi, sub))) {
|
||||||
sub = NULL;
|
sub = NULL;
|
||||||
|
@ -3220,14 +3259,13 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
|
||||||
default:
|
default:
|
||||||
GST_WARNING_OBJECT (avi,
|
GST_WARNING_OBJECT (avi,
|
||||||
"Unknown list %" GST_FOURCC_FORMAT " in AVI header",
|
"Unknown list %" GST_FOURCC_FORMAT " in AVI header",
|
||||||
GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA
|
GST_FOURCC_ARGS (GST_READ_UINT32_LE (fourcc)));
|
||||||
(sub))));
|
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case GST_RIFF_TAG_JUNQ:
|
case GST_RIFF_TAG_JUNQ:
|
||||||
case GST_RIFF_TAG_JUNK:
|
case GST_RIFF_TAG_JUNK:
|
||||||
goto next;
|
goto next;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GST_RIFF_IDIT:
|
case GST_RIFF_IDIT:
|
||||||
gst_avi_demux_parse_idit (avi, sub);
|
gst_avi_demux_parse_idit (avi, sub);
|
||||||
goto next;
|
goto next;
|
||||||
|
@ -3270,10 +3308,11 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
|
||||||
if (gst_adapter_available (avi->adapter) < 12)
|
if (gst_adapter_available (avi->adapter) < 12)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
data = gst_adapter_peek (avi->adapter, 12);
|
data = gst_adapter_map (avi->adapter, 12);
|
||||||
tag = GST_READ_UINT32_LE (data);
|
tag = GST_READ_UINT32_LE (data);
|
||||||
size = GST_READ_UINT32_LE (data + 4);
|
size = GST_READ_UINT32_LE (data + 4);
|
||||||
ltag = GST_READ_UINT32_LE (data + 8);
|
ltag = GST_READ_UINT32_LE (data + 8);
|
||||||
|
gst_adapter_unmap (avi->adapter, 0);
|
||||||
|
|
||||||
if (tag == GST_RIFF_TAG_LIST) {
|
if (tag == GST_RIFF_TAG_LIST) {
|
||||||
switch (ltag) {
|
switch (ltag) {
|
||||||
|
@ -3525,10 +3564,11 @@ gst_avi_demux_parse_idit_text (GstAviDemux * avi, gchar * data)
|
||||||
static void
|
static void
|
||||||
gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
|
gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
gchar *data = (gchar *) GST_BUFFER_DATA (buf);
|
gchar *data, *ptr;
|
||||||
guint size = GST_BUFFER_SIZE (buf);
|
gsize size, left;
|
||||||
gchar *safedata = NULL;
|
gchar *safedata = NULL;
|
||||||
|
|
||||||
|
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||||
/*
|
/*
|
||||||
* According to:
|
* According to:
|
||||||
* http://www.eden-foundation.org/products/code/film_date_stamp/index.html
|
* http://www.eden-foundation.org/products/code/film_date_stamp/index.html
|
||||||
|
@ -3542,24 +3582,27 @@ gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* skip eventual initial whitespace */
|
/* skip eventual initial whitespace */
|
||||||
while (size > 0 && g_ascii_isspace (data[0])) {
|
ptr = data;
|
||||||
data++;
|
left = size;
|
||||||
size--;
|
|
||||||
|
while (left > 0 && g_ascii_isspace (ptr[0])) {
|
||||||
|
ptr++;
|
||||||
|
left--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0) {
|
if (left == 0) {
|
||||||
goto non_parsable;
|
goto non_parsable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make a safe copy to add a \0 to the end of the string */
|
/* make a safe copy to add a \0 to the end of the string */
|
||||||
safedata = g_strndup (data, size);
|
safedata = g_strndup (ptr, left);
|
||||||
|
|
||||||
/* test if the first char is a alpha or a number */
|
/* test if the first char is a alpha or a number */
|
||||||
if (g_ascii_isdigit (data[0])) {
|
if (g_ascii_isdigit (ptr[0])) {
|
||||||
gst_avi_demux_parse_idit_nums_only (avi, safedata);
|
gst_avi_demux_parse_idit_nums_only (avi, safedata);
|
||||||
g_free (safedata);
|
g_free (safedata);
|
||||||
return;
|
return;
|
||||||
} else if (g_ascii_isalpha (data[0])) {
|
} else if (g_ascii_isalpha (ptr[0])) {
|
||||||
gst_avi_demux_parse_idit_text (avi, safedata);
|
gst_avi_demux_parse_idit_text (avi, safedata);
|
||||||
g_free (safedata);
|
g_free (safedata);
|
||||||
return;
|
return;
|
||||||
|
@ -3569,6 +3612,7 @@ gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
|
||||||
|
|
||||||
non_parsable:
|
non_parsable:
|
||||||
GST_WARNING_OBJECT (avi, "IDIT tag has no parsable info");
|
GST_WARNING_OBJECT (avi, "IDIT tag has no parsable info");
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3585,6 +3629,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
GstElement *element = GST_ELEMENT_CAST (avi);
|
GstElement *element = GST_ELEMENT_CAST (avi);
|
||||||
GstClockTime stamp;
|
GstClockTime stamp;
|
||||||
GstTagList *tags = NULL;
|
GstTagList *tags = NULL;
|
||||||
|
guint8 fourcc[4];
|
||||||
|
|
||||||
stamp = gst_util_get_timestamp ();
|
stamp = gst_util_get_timestamp ();
|
||||||
|
|
||||||
|
@ -3594,15 +3639,16 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
goto pull_range_failed;
|
goto pull_range_failed;
|
||||||
else if (tag != GST_RIFF_TAG_LIST)
|
else if (tag != GST_RIFF_TAG_LIST)
|
||||||
goto no_list;
|
goto no_list;
|
||||||
else if (GST_BUFFER_SIZE (buf) < 4)
|
else if (gst_buffer_get_size (buf) < 4)
|
||||||
goto no_header;
|
goto no_header;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (avi, "parsing headers");
|
GST_DEBUG_OBJECT (avi, "parsing headers");
|
||||||
|
|
||||||
/* Find the 'hdrl' LIST tag */
|
/* Find the 'hdrl' LIST tag */
|
||||||
while (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl) {
|
gst_buffer_extract (buf, 0, fourcc, 4);
|
||||||
|
while (GST_READ_UINT32_LE (fourcc) != GST_RIFF_LIST_hdrl) {
|
||||||
GST_LOG_OBJECT (avi, "buffer contains %" GST_FOURCC_FORMAT,
|
GST_LOG_OBJECT (avi, "buffer contains %" GST_FOURCC_FORMAT,
|
||||||
GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf))));
|
GST_FOURCC_ARGS (GST_READ_UINT32_LE (fourcc)));
|
||||||
|
|
||||||
/* Eat up */
|
/* Eat up */
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
@ -3613,8 +3659,9 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
goto pull_range_failed;
|
goto pull_range_failed;
|
||||||
else if (tag != GST_RIFF_TAG_LIST)
|
else if (tag != GST_RIFF_TAG_LIST)
|
||||||
goto no_list;
|
goto no_list;
|
||||||
else if (GST_BUFFER_SIZE (buf) < 4)
|
else if (gst_buffer_get_size (buf) < 4)
|
||||||
goto no_header;
|
goto no_header;
|
||||||
|
gst_buffer_extract (buf, 0, fourcc, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (avi, "hdrl LIST tag found");
|
GST_DEBUG_OBJECT (avi, "hdrl LIST tag found");
|
||||||
|
@ -3633,23 +3680,21 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
|
|
||||||
/* now, read the elements from the header until the end */
|
/* now, read the elements from the header until the end */
|
||||||
while (gst_riff_parse_chunk (element, buf, &offset, &tag, &sub)) {
|
while (gst_riff_parse_chunk (element, buf, &offset, &tag, &sub)) {
|
||||||
|
gsize size;
|
||||||
|
guint8 *data;
|
||||||
|
|
||||||
/* sub can be NULL on empty tags */
|
/* sub can be NULL on empty tags */
|
||||||
if (!sub)
|
if (!sub)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
data = gst_buffer_map (sub, &size, NULL, GST_MAP_READ);
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case GST_RIFF_TAG_LIST:
|
case GST_RIFF_TAG_LIST:
|
||||||
{
|
if (size < 4)
|
||||||
guint8 *data;
|
|
||||||
guint32 fourcc;
|
|
||||||
|
|
||||||
if (GST_BUFFER_SIZE (sub) < 4)
|
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (sub);
|
switch (GST_READ_UINT32_LE (data)) {
|
||||||
fourcc = GST_READ_UINT32_LE (data);
|
|
||||||
|
|
||||||
switch (fourcc) {
|
|
||||||
case GST_RIFF_LIST_strl:
|
case GST_RIFF_LIST_strl:
|
||||||
if (!(gst_avi_demux_parse_stream (avi, sub))) {
|
if (!(gst_avi_demux_parse_stream (avi, sub))) {
|
||||||
GST_ELEMENT_WARNING (avi, STREAM, DEMUX, (NULL),
|
GST_ELEMENT_WARNING (avi, STREAM, DEMUX, (NULL),
|
||||||
|
@ -3663,8 +3708,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
sub = NULL;
|
sub = NULL;
|
||||||
break;
|
break;
|
||||||
case GST_RIFF_LIST_INFO:
|
case GST_RIFF_LIST_INFO:
|
||||||
GST_BUFFER_DATA (sub) = data + 4;
|
gst_buffer_resize (sub, 4, -1);
|
||||||
GST_BUFFER_SIZE (sub) -= 4;
|
|
||||||
gst_riff_parse_info (element, sub, &tags);
|
gst_riff_parse_info (element, sub, &tags);
|
||||||
if (tags) {
|
if (tags) {
|
||||||
if (avi->globaltags) {
|
if (avi->globaltags) {
|
||||||
|
@ -3679,16 +3723,14 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
default:
|
default:
|
||||||
GST_WARNING_OBJECT (avi,
|
GST_WARNING_OBJECT (avi,
|
||||||
"Unknown list %" GST_FOURCC_FORMAT " in AVI header",
|
"Unknown list %" GST_FOURCC_FORMAT " in AVI header",
|
||||||
GST_FOURCC_ARGS (fourcc));
|
GST_FOURCC_ARGS (GST_READ_UINT32_LE (data)));
|
||||||
GST_MEMDUMP_OBJECT (avi, "Unknown list", GST_BUFFER_DATA (sub),
|
GST_MEMDUMP_OBJECT (avi, "Unknown list", data, size);
|
||||||
GST_BUFFER_SIZE (sub));
|
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case GST_RIFF_TAG_JUNQ:
|
case GST_RIFF_TAG_JUNQ:
|
||||||
case GST_RIFF_TAG_JUNK:
|
case GST_RIFF_TAG_JUNK:
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case GST_RIFF_IDIT:
|
case GST_RIFF_IDIT:
|
||||||
gst_avi_demux_parse_idit (avi, sub);
|
gst_avi_demux_parse_idit (avi, sub);
|
||||||
goto next;
|
goto next;
|
||||||
|
@ -3696,14 +3738,15 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
GST_WARNING_OBJECT (avi,
|
GST_WARNING_OBJECT (avi,
|
||||||
"Unknown tag %" GST_FOURCC_FORMAT " in AVI header at off %d",
|
"Unknown tag %" GST_FOURCC_FORMAT " in AVI header at off %d",
|
||||||
GST_FOURCC_ARGS (tag), offset);
|
GST_FOURCC_ARGS (tag), offset);
|
||||||
GST_MEMDUMP_OBJECT (avi, "Unknown tag", GST_BUFFER_DATA (sub),
|
GST_MEMDUMP_OBJECT (avi, "Unknown tag", data, size);
|
||||||
GST_BUFFER_SIZE (sub));
|
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case GST_RIFF_TAG_JUNQ:
|
case GST_RIFF_TAG_JUNQ:
|
||||||
case GST_RIFF_TAG_JUNK:
|
case GST_RIFF_TAG_JUNK:
|
||||||
next:
|
next:
|
||||||
if (sub)
|
if (sub) {
|
||||||
|
gst_buffer_unmap (sub, data, size);
|
||||||
gst_buffer_unref (sub);
|
gst_buffer_unref (sub);
|
||||||
|
}
|
||||||
sub = NULL;
|
sub = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3726,6 +3769,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
/* Now, find the data (i.e. skip all junk between header and data) */
|
/* Now, find the data (i.e. skip all junk between header and data) */
|
||||||
do {
|
do {
|
||||||
guint size;
|
guint size;
|
||||||
|
gsize bsize;
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
guint32 tag, ltag;
|
guint32 tag, ltag;
|
||||||
|
|
||||||
|
@ -3733,22 +3777,22 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
if (res != GST_FLOW_OK) {
|
if (res != GST_FLOW_OK) {
|
||||||
GST_DEBUG_OBJECT (avi, "pull_range failure while looking for tags");
|
GST_DEBUG_OBJECT (avi, "pull_range failure while looking for tags");
|
||||||
goto pull_range_failed;
|
goto pull_range_failed;
|
||||||
} else if (GST_BUFFER_SIZE (buf) < 12) {
|
} else if (gst_buffer_get_size (buf) < 12) {
|
||||||
GST_DEBUG_OBJECT (avi, "got %d bytes which is less than 12 bytes",
|
GST_DEBUG_OBJECT (avi, "got %d bytes which is less than 12 bytes",
|
||||||
GST_BUFFER_SIZE (buf));
|
gst_buffer_get_size (buf));
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buf);
|
data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
|
||||||
|
|
||||||
tag = GST_READ_UINT32_LE (data);
|
tag = GST_READ_UINT32_LE (data);
|
||||||
size = GST_READ_UINT32_LE (data + 4);
|
size = GST_READ_UINT32_LE (data + 4);
|
||||||
ltag = GST_READ_UINT32_LE (data + 8);
|
ltag = GST_READ_UINT32_LE (data + 8);
|
||||||
|
|
||||||
GST_DEBUG ("tag %" GST_FOURCC_FORMAT ", size %u",
|
GST_DEBUG ("tag %" GST_FOURCC_FORMAT ", size %u",
|
||||||
GST_FOURCC_ARGS (tag), size);
|
GST_FOURCC_ARGS (tag), size);
|
||||||
GST_MEMDUMP ("Tag content", data, GST_BUFFER_SIZE (buf));
|
GST_MEMDUMP ("Tag content", data, bsize);
|
||||||
|
gst_buffer_unmap (buf, data, bsize);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
|
@ -3766,7 +3810,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
|
GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
|
||||||
goto pull_range_failed;
|
goto pull_range_failed;
|
||||||
}
|
}
|
||||||
GST_DEBUG ("got size %u", GST_BUFFER_SIZE (buf));
|
GST_DEBUG ("got size %u", gst_buffer_get_size (buf));
|
||||||
if (size < 4) {
|
if (size < 4) {
|
||||||
GST_DEBUG ("skipping INFO LIST prefix");
|
GST_DEBUG ("skipping INFO LIST prefix");
|
||||||
avi->offset += (4 - GST_ROUND_UP_2 (size));
|
avi->offset += (4 - GST_ROUND_UP_2 (size));
|
||||||
|
@ -3774,7 +3818,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub = gst_buffer_create_sub (buf, 4, GST_BUFFER_SIZE (buf) - 4);
|
sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, 4, -1);
|
||||||
gst_riff_parse_info (element, sub, &tags);
|
gst_riff_parse_info (element, sub, &tags);
|
||||||
if (tags) {
|
if (tags) {
|
||||||
if (avi->globaltags) {
|
if (avi->globaltags) {
|
||||||
|
@ -3814,7 +3858,9 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
|
GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
|
||||||
goto pull_range_failed;
|
goto pull_range_failed;
|
||||||
}
|
}
|
||||||
GST_MEMDUMP ("Junk", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
|
||||||
|
GST_MEMDUMP ("Junk", data, bsize);
|
||||||
|
gst_buffer_unmap (buf, data, bsize);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
}
|
}
|
||||||
avi->offset += 8 + GST_ROUND_UP_2 (size);
|
avi->offset += 8 + GST_ROUND_UP_2 (size);
|
||||||
|
@ -4450,7 +4496,8 @@ gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
gint y, w, h;
|
gint y, w, h;
|
||||||
gint bpp, stride;
|
gint bpp, stride;
|
||||||
guint8 *tmp = NULL;
|
guint8 *tmp = NULL, *data;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
if (stream->strh->type != GST_RIFF_FCC_vids)
|
if (stream->strh->type != GST_RIFF_FCC_vids)
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -4475,20 +4522,24 @@ gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
|
||||||
stride = w * (bpp / 8);
|
stride = w * (bpp / 8);
|
||||||
|
|
||||||
buf = gst_buffer_make_writable (buf);
|
buf = gst_buffer_make_writable (buf);
|
||||||
if (GST_BUFFER_SIZE (buf) < (stride * h)) {
|
|
||||||
|
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
|
||||||
|
if (size < (stride * h)) {
|
||||||
GST_WARNING ("Buffer is smaller than reported Width x Height x Depth");
|
GST_WARNING ("Buffer is smaller than reported Width x Height x Depth");
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = g_malloc (stride);
|
tmp = g_malloc (stride);
|
||||||
|
|
||||||
for (y = 0; y < h / 2; y++) {
|
for (y = 0; y < h / 2; y++) {
|
||||||
swap_line (GST_BUFFER_DATA (buf) + stride * y,
|
swap_line (data + stride * y, data + stride * (h - 1 - y), tmp, stride);
|
||||||
GST_BUFFER_DATA (buf) + stride * (h - 1 - y), tmp, stride);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
|
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4742,7 +4793,7 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
|
||||||
goto pull_failed;
|
goto pull_failed;
|
||||||
|
|
||||||
/* check for short buffers, this is EOS as well */
|
/* check for short buffers, this is EOS as well */
|
||||||
if (GST_BUFFER_SIZE (buf) < size)
|
if (gst_buffer_get_size (buf) < size)
|
||||||
goto short_buffer;
|
goto short_buffer;
|
||||||
|
|
||||||
/* invert the picture if needed */
|
/* invert the picture if needed */
|
||||||
|
@ -4776,7 +4827,7 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
|
||||||
GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %"
|
GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %"
|
||||||
GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
|
GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
|
||||||
", off_end %" G_GUINT64_FORMAT,
|
", off_end %" G_GUINT64_FORMAT,
|
||||||
GST_BUFFER_SIZE (buf), GST_TIME_ARGS (timestamp),
|
gst_buffer_get_size (buf), GST_TIME_ARGS (timestamp),
|
||||||
GST_TIME_ARGS (duration), out_offset, out_offset_end);
|
GST_TIME_ARGS (duration), out_offset, out_offset_end);
|
||||||
|
|
||||||
ret = gst_pad_push (stream->pad, buf);
|
ret = gst_pad_push (stream->pad, buf);
|
||||||
|
@ -4831,7 +4882,7 @@ short_buffer:
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (avi, "Short read at offset %" G_GUINT64_FORMAT
|
GST_WARNING_OBJECT (avi, "Short read at offset %" G_GUINT64_FORMAT
|
||||||
", only got %d/%" G_GUINT64_FORMAT " bytes (truncated file?)", offset,
|
", only got %d/%" G_GUINT64_FORMAT " bytes (truncated file?)", offset,
|
||||||
GST_BUFFER_SIZE (buf), size);
|
gst_buffer_get_size (buf), size);
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
ret = GST_FLOW_UNEXPECTED;
|
ret = GST_FLOW_UNEXPECTED;
|
||||||
goto beach;
|
goto beach;
|
||||||
|
@ -4976,7 +5027,7 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
|
||||||
if (size) {
|
if (size) {
|
||||||
buf = gst_adapter_take_buffer (avi->adapter, GST_ROUND_UP_2 (size));
|
buf = gst_adapter_take_buffer (avi->adapter, GST_ROUND_UP_2 (size));
|
||||||
/* patch the size */
|
/* patch the size */
|
||||||
GST_BUFFER_SIZE (buf) = size;
|
gst_buffer_resize (buf, 0, size);
|
||||||
} else {
|
} else {
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
}
|
}
|
||||||
|
@ -5233,7 +5284,7 @@ gst_avi_demux_chain (GstPad * pad, GstBuffer * buf)
|
||||||
avi->stream[i].discont = TRUE;
|
avi->stream[i].discont = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG ("Store %d bytes in adapter", GST_BUFFER_SIZE (buf));
|
GST_DEBUG ("Store %d bytes in adapter", gst_buffer_get_size (buf));
|
||||||
gst_adapter_push (avi->adapter, buf);
|
gst_adapter_push (avi->adapter, buf);
|
||||||
|
|
||||||
switch (avi->state) {
|
switch (avi->state) {
|
||||||
|
|
|
@ -634,7 +634,7 @@ gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
|
||||||
avipad->vids_codec_data = gst_value_get_buffer (codec_data);
|
avipad->vids_codec_data = gst_value_get_buffer (codec_data);
|
||||||
gst_buffer_ref (avipad->vids_codec_data);
|
gst_buffer_ref (avipad->vids_codec_data);
|
||||||
/* keep global track of size */
|
/* keep global track of size */
|
||||||
avimux->codec_data_size += GST_BUFFER_SIZE (avipad->vids_codec_data);
|
avimux->codec_data_size += gst_buffer_get_size (avipad->vids_codec_data);
|
||||||
} else {
|
} else {
|
||||||
avipad->prepend_buffer =
|
avipad->prepend_buffer =
|
||||||
gst_buffer_ref (gst_value_get_buffer (codec_data));
|
gst_buffer_ref (gst_value_get_buffer (codec_data));
|
||||||
|
@ -665,16 +665,14 @@ gst_avi_mux_audsink_scan_mpeg_audio (GstAviMux * avimux, GstAviPad * avipad,
|
||||||
GstBuffer * buffer)
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
guint size;
|
gsize size;
|
||||||
guint spf;
|
guint spf;
|
||||||
guint32 header;
|
guint32 header;
|
||||||
gulong layer;
|
gulong layer;
|
||||||
gulong version;
|
gulong version;
|
||||||
gint lsf, mpg25;
|
gint lsf, mpg25;
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buffer);
|
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
|
||||||
size = GST_BUFFER_SIZE (buffer);
|
|
||||||
|
|
||||||
if (size < 4)
|
if (size < 4)
|
||||||
goto not_parsed;
|
goto not_parsed;
|
||||||
|
|
||||||
|
@ -713,6 +711,8 @@ gst_avi_mux_audsink_scan_mpeg_audio (GstAviMux * avimux, GstAviPad * avipad,
|
||||||
GST_WARNING_OBJECT (avimux, "input mpeg audio has varying frame size");
|
GST_WARNING_OBJECT (avimux, "input mpeg audio has varying frame size");
|
||||||
goto cbr_fallback;
|
goto cbr_fallback;
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
|
gst_buffer_unmap (buffer, data, size);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
@ -728,7 +728,7 @@ cbr_fallback:
|
||||||
avipad->hdr.scale = 1;
|
avipad->hdr.scale = 1;
|
||||||
/* no need to check further */
|
/* no need to check further */
|
||||||
avipad->hook = NULL;
|
avipad->hook = NULL;
|
||||||
return GST_FLOW_OK;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,7 +792,7 @@ gst_avi_mux_audsink_set_caps (GstPad * pad, GstCaps * vscaps)
|
||||||
avipad->auds_codec_data = gst_value_get_buffer (codec_data);
|
avipad->auds_codec_data = gst_value_get_buffer (codec_data);
|
||||||
gst_buffer_ref (avipad->auds_codec_data);
|
gst_buffer_ref (avipad->auds_codec_data);
|
||||||
/* keep global track of size */
|
/* keep global track of size */
|
||||||
avimux->codec_data_size += GST_BUFFER_SIZE (avipad->auds_codec_data);
|
avimux->codec_data_size += gst_buffer_get_size (avipad->auds_codec_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp (mimetype, "audio/x-raw-int")) {
|
if (!strcmp (mimetype, "audio/x-raw-int")) {
|
||||||
|
@ -871,6 +871,7 @@ gst_avi_mux_audsink_set_caps (GstPad * pad, GstCaps * vscaps)
|
||||||
GstBuffer *codec_data_buf = avipad->auds_codec_data;
|
GstBuffer *codec_data_buf = avipad->auds_codec_data;
|
||||||
const gchar *stream_format;
|
const gchar *stream_format;
|
||||||
guint codec;
|
guint codec;
|
||||||
|
guint8 data[2];
|
||||||
|
|
||||||
stream_format = gst_structure_get_string (structure, "stream-format");
|
stream_format = gst_structure_get_string (structure, "stream-format");
|
||||||
if (stream_format) {
|
if (stream_format) {
|
||||||
|
@ -885,13 +886,14 @@ gst_avi_mux_audsink_set_caps (GstPad * pad, GstCaps * vscaps)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vbr case needs some special handling */
|
/* vbr case needs some special handling */
|
||||||
if (!codec_data_buf || GST_BUFFER_SIZE (codec_data_buf) < 2) {
|
if (!codec_data_buf || gst_buffer_get_size (codec_data_buf) < 2) {
|
||||||
GST_WARNING_OBJECT (avimux, "no (valid) codec_data for AAC audio");
|
GST_WARNING_OBJECT (avimux, "no (valid) codec_data for AAC audio");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
avipad->auds.format = GST_RIFF_WAVE_FORMAT_AAC;
|
avipad->auds.format = GST_RIFF_WAVE_FORMAT_AAC;
|
||||||
/* need to determine frame length */
|
/* need to determine frame length */
|
||||||
codec = GST_READ_UINT16_BE (GST_BUFFER_DATA (codec_data_buf));
|
gst_buffer_extract (codec_data_buf, 0, data, 2);
|
||||||
|
codec = GST_READ_UINT16_BE (data);
|
||||||
avipad->parent.hdr.scale = (codec & 0x4) ? 960 : 1024;
|
avipad->parent.hdr.scale = (codec & 0x4) ? 960 : 1024;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1190,6 +1192,8 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux)
|
||||||
GstByteWriter bw;
|
GstByteWriter bw;
|
||||||
GSList *node;
|
GSList *node;
|
||||||
guint avih, riff, hdrl;
|
guint avih, riff, hdrl;
|
||||||
|
guint8 *bdata;
|
||||||
|
gsize bsize;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (avimux, "creating avi header, data_size %u, idx_size %u",
|
GST_DEBUG_OBJECT (avimux, "creating avi header, data_size %u, idx_size %u",
|
||||||
avimux->data_size, avimux->idx_size);
|
avimux->data_size, avimux->idx_size);
|
||||||
|
@ -1265,7 +1269,7 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux)
|
||||||
|
|
||||||
if (avipad->is_video) {
|
if (avipad->is_video) {
|
||||||
codec_size = vidpad->vids_codec_data ?
|
codec_size = vidpad->vids_codec_data ?
|
||||||
GST_BUFFER_SIZE (vidpad->vids_codec_data) : 0;
|
gst_buffer_get_size (vidpad->vids_codec_data) : 0;
|
||||||
/* the video header */
|
/* the video header */
|
||||||
strf = gst_avi_mux_start_chunk (&bw, "strf", 0);
|
strf = gst_avi_mux_start_chunk (&bw, "strf", 0);
|
||||||
/* the actual header */
|
/* the actual header */
|
||||||
|
@ -1281,9 +1285,11 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux)
|
||||||
gst_byte_writer_put_uint32_le (&bw, vidpad->vids.num_colors);
|
gst_byte_writer_put_uint32_le (&bw, vidpad->vids.num_colors);
|
||||||
gst_byte_writer_put_uint32_le (&bw, vidpad->vids.imp_colors);
|
gst_byte_writer_put_uint32_le (&bw, vidpad->vids.imp_colors);
|
||||||
if (vidpad->vids_codec_data) {
|
if (vidpad->vids_codec_data) {
|
||||||
gst_byte_writer_put_data (&bw,
|
bdata =
|
||||||
GST_BUFFER_DATA (vidpad->vids_codec_data),
|
gst_buffer_map (vidpad->vids_codec_data, &bsize, NULL,
|
||||||
GST_BUFFER_SIZE (vidpad->vids_codec_data));
|
GST_MAP_READ);
|
||||||
|
gst_byte_writer_put_data (&bw, bdata, bsize);
|
||||||
|
gst_buffer_unmap (vidpad->vids_codec_data, bdata, bsize);
|
||||||
}
|
}
|
||||||
gst_avi_mux_end_chunk (&bw, strf);
|
gst_avi_mux_end_chunk (&bw, strf);
|
||||||
|
|
||||||
|
@ -1325,7 +1331,7 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
codec_size = audpad->auds_codec_data ?
|
codec_size = audpad->auds_codec_data ?
|
||||||
GST_BUFFER_SIZE (audpad->auds_codec_data) : 0;
|
gst_buffer_get_size (audpad->auds_codec_data) : 0;
|
||||||
/* the audio header */
|
/* the audio header */
|
||||||
strf = gst_avi_mux_start_chunk (&bw, "strf", 0);
|
strf = gst_avi_mux_start_chunk (&bw, "strf", 0);
|
||||||
/* the actual header */
|
/* the actual header */
|
||||||
|
@ -1337,9 +1343,11 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux)
|
||||||
gst_byte_writer_put_uint16_le (&bw, audpad->auds.size);
|
gst_byte_writer_put_uint16_le (&bw, audpad->auds.size);
|
||||||
gst_byte_writer_put_uint16_le (&bw, codec_size);
|
gst_byte_writer_put_uint16_le (&bw, codec_size);
|
||||||
if (audpad->auds_codec_data) {
|
if (audpad->auds_codec_data) {
|
||||||
gst_byte_writer_put_data (&bw,
|
bdata =
|
||||||
GST_BUFFER_DATA (audpad->auds_codec_data),
|
gst_buffer_map (audpad->auds_codec_data, &bsize, NULL,
|
||||||
GST_BUFFER_SIZE (audpad->auds_codec_data));
|
GST_MAP_READ);
|
||||||
|
gst_byte_writer_put_data (&bw, bdata, bsize);
|
||||||
|
gst_buffer_unmap (vidpad->vids_codec_data, bdata, bsize);
|
||||||
}
|
}
|
||||||
gst_avi_mux_end_chunk (&bw, strf);
|
gst_avi_mux_end_chunk (&bw, strf);
|
||||||
}
|
}
|
||||||
|
@ -1410,12 +1418,13 @@ gst_avi_mux_riff_get_avi_header (GstAviMux * avimux)
|
||||||
buffer = gst_byte_writer_reset_and_get_buffer (&bw);
|
buffer = gst_byte_writer_reset_and_get_buffer (&bw);
|
||||||
|
|
||||||
/* ... but RIFF includes more than just header */
|
/* ... but RIFF includes more than just header */
|
||||||
size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buffer) + 4);
|
bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READWRITE);
|
||||||
|
size = GST_READ_UINT32_LE (bdata + 4);
|
||||||
size += 8 + avimux->data_size + avimux->idx_size;
|
size += 8 + avimux->data_size + avimux->idx_size;
|
||||||
GST_WRITE_UINT32_LE (GST_BUFFER_DATA (buffer) + 4, size);
|
GST_WRITE_UINT32_LE (bdata + 4, size);
|
||||||
|
|
||||||
GST_MEMDUMP_OBJECT (avimux, "avi header", GST_BUFFER_DATA (buffer),
|
GST_MEMDUMP_OBJECT (avimux, "avi header", bdata, bsize);
|
||||||
GST_BUFFER_SIZE (buffer));
|
gst_buffer_unmap (buffer, bdata, bsize);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -1424,17 +1433,19 @@ static GstBuffer *
|
||||||
gst_avi_mux_riff_get_avix_header (guint32 datax_size)
|
gst_avi_mux_riff_get_avix_header (guint32 datax_size)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
guint8 *buffdata;
|
guint8 *bdata;
|
||||||
|
gsize bsize;
|
||||||
|
|
||||||
buffer = gst_buffer_new_and_alloc (24);
|
buffer = gst_buffer_new_and_alloc (24);
|
||||||
buffdata = GST_BUFFER_DATA (buffer);
|
|
||||||
|
|
||||||
memcpy (buffdata + 0, "RIFF", 4);
|
bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
|
||||||
GST_WRITE_UINT32_LE (buffdata + 4, datax_size + 3 * 4);
|
memcpy (bdata + 0, "RIFF", 4);
|
||||||
memcpy (buffdata + 8, "AVIX", 4);
|
GST_WRITE_UINT32_LE (bdata + 4, datax_size + 3 * 4);
|
||||||
memcpy (buffdata + 12, "LIST", 4);
|
memcpy (bdata + 8, "AVIX", 4);
|
||||||
GST_WRITE_UINT32_LE (buffdata + 16, datax_size);
|
memcpy (bdata + 12, "LIST", 4);
|
||||||
memcpy (buffdata + 20, "movi", 4);
|
GST_WRITE_UINT32_LE (bdata + 16, datax_size);
|
||||||
|
memcpy (bdata + 20, "movi", 4);
|
||||||
|
gst_buffer_unmap (buffer, bdata, bsize);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -1443,12 +1454,15 @@ static inline GstBuffer *
|
||||||
gst_avi_mux_riff_get_header (GstAviPad * avipad, guint32 video_frame_size)
|
gst_avi_mux_riff_get_header (GstAviPad * avipad, guint32 video_frame_size)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
guint8 *buffdata;
|
guint8 *bdata;
|
||||||
|
gsize bsize;
|
||||||
|
|
||||||
buffer = gst_buffer_new_and_alloc (8);
|
buffer = gst_buffer_new_and_alloc (8);
|
||||||
buffdata = GST_BUFFER_DATA (buffer);
|
|
||||||
memcpy (buffdata + 0, avipad->tag, 4);
|
bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
|
||||||
GST_WRITE_UINT32_LE (buffdata + 4, video_frame_size);
|
memcpy (bdata + 0, avipad->tag, 4);
|
||||||
|
GST_WRITE_UINT32_LE (bdata + 4, video_frame_size);
|
||||||
|
gst_buffer_unmap (buffer, bdata, bsize);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -1461,12 +1475,14 @@ gst_avi_mux_write_avix_index (GstAviMux * avimux, GstAviPad * avipad,
|
||||||
{
|
{
|
||||||
GstFlowReturn res;
|
GstFlowReturn res;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
guint8 *buffdata, *data;
|
guint8 *data;
|
||||||
gst_riff_index_entry *entry;
|
gst_riff_index_entry *entry;
|
||||||
gint i;
|
gint i;
|
||||||
guint32 size, entry_count;
|
guint32 size, entry_count;
|
||||||
gboolean is_pcm = FALSE;
|
gboolean is_pcm = FALSE;
|
||||||
guint32 pcm_samples = 0;
|
guint32 pcm_samples = 0;
|
||||||
|
guint8 *bdata;
|
||||||
|
gsize bsize;
|
||||||
|
|
||||||
/* check if it is pcm */
|
/* check if it is pcm */
|
||||||
if (avipad && !avipad->is_video) {
|
if (avipad && !avipad->is_video) {
|
||||||
|
@ -1479,19 +1495,21 @@ gst_avi_mux_write_avix_index (GstAviMux * avimux, GstAviPad * avipad,
|
||||||
|
|
||||||
/* allocate the maximum possible */
|
/* allocate the maximum possible */
|
||||||
buffer = gst_buffer_new_and_alloc (32 + 8 * avimux->idx_index);
|
buffer = gst_buffer_new_and_alloc (32 + 8 * avimux->idx_index);
|
||||||
buffdata = GST_BUFFER_DATA (buffer);
|
|
||||||
|
bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
|
||||||
|
data = bdata;
|
||||||
|
|
||||||
/* general index chunk info */
|
/* general index chunk info */
|
||||||
memcpy (buffdata + 0, chunk, 4); /* chunk id */
|
memcpy (bdata + 0, chunk, 4); /* chunk id */
|
||||||
GST_WRITE_UINT32_LE (buffdata + 4, 0); /* chunk size; fill later */
|
GST_WRITE_UINT32_LE (bdata + 4, 0); /* chunk size; fill later */
|
||||||
GST_WRITE_UINT16_LE (buffdata + 8, 2); /* index entry is 2 words */
|
GST_WRITE_UINT16_LE (bdata + 8, 2); /* index entry is 2 words */
|
||||||
buffdata[10] = 0; /* index subtype */
|
bdata[10] = 0; /* index subtype */
|
||||||
buffdata[11] = GST_AVI_INDEX_OF_CHUNKS; /* index type: AVI_INDEX_OF_CHUNKS */
|
bdata[11] = GST_AVI_INDEX_OF_CHUNKS; /* index type: AVI_INDEX_OF_CHUNKS */
|
||||||
GST_WRITE_UINT32_LE (buffdata + 12, 0); /* entries in use; fill later */
|
GST_WRITE_UINT32_LE (bdata + 12, 0); /* entries in use; fill later */
|
||||||
memcpy (buffdata + 16, code, 4); /* stream to which index refers */
|
memcpy (bdata + 16, code, 4); /* stream to which index refers */
|
||||||
GST_WRITE_UINT64_LE (buffdata + 20, avimux->avix_start); /* base offset */
|
GST_WRITE_UINT64_LE (bdata + 20, avimux->avix_start); /* base offset */
|
||||||
GST_WRITE_UINT32_LE (buffdata + 28, 0); /* reserved */
|
GST_WRITE_UINT32_LE (bdata + 28, 0); /* reserved */
|
||||||
buffdata += 32;
|
bdata += 32;
|
||||||
|
|
||||||
/* now the actual index entries */
|
/* now the actual index entries */
|
||||||
i = avimux->idx_index;
|
i = avimux->idx_index;
|
||||||
|
@ -1499,23 +1517,23 @@ gst_avi_mux_write_avix_index (GstAviMux * avimux, GstAviPad * avipad,
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
if (memcmp (&entry->id, code, 4) == 0) {
|
if (memcmp (&entry->id, code, 4) == 0) {
|
||||||
/* enter relative offset to the data (!) */
|
/* enter relative offset to the data (!) */
|
||||||
GST_WRITE_UINT32_LE (buffdata, GUINT32_FROM_LE (entry->offset) + 8);
|
GST_WRITE_UINT32_LE (bdata, GUINT32_FROM_LE (entry->offset) + 8);
|
||||||
/* msb is set if not (!) keyframe */
|
/* msb is set if not (!) keyframe */
|
||||||
GST_WRITE_UINT32_LE (buffdata + 4, GUINT32_FROM_LE (entry->size)
|
GST_WRITE_UINT32_LE (bdata + 4, GUINT32_FROM_LE (entry->size)
|
||||||
| (GUINT32_FROM_LE (entry->flags)
|
| (GUINT32_FROM_LE (entry->flags)
|
||||||
& GST_RIFF_IF_KEYFRAME ? 0 : 1U << 31));
|
& GST_RIFF_IF_KEYFRAME ? 0 : 1U << 31));
|
||||||
buffdata += 8;
|
bdata += 8;
|
||||||
}
|
}
|
||||||
i--;
|
i--;
|
||||||
entry++;
|
entry++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ok, now we know the size and no of entries, fill in where needed */
|
/* ok, now we know the size and no of entries, fill in where needed */
|
||||||
data = GST_BUFFER_DATA (buffer);
|
size = bdata - data;
|
||||||
GST_BUFFER_SIZE (buffer) = size = buffdata - data;
|
|
||||||
GST_WRITE_UINT32_LE (data + 4, size - 8);
|
GST_WRITE_UINT32_LE (data + 4, size - 8);
|
||||||
entry_count = (size - 32) / 8;
|
entry_count = (size - 32) / 8;
|
||||||
GST_WRITE_UINT32_LE (data + 12, entry_count);
|
GST_WRITE_UINT32_LE (data + 12, entry_count);
|
||||||
|
gst_buffer_unmap (buffer, data, size);
|
||||||
|
|
||||||
/* decorate and send */
|
/* decorate and send */
|
||||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
|
gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
|
||||||
|
@ -1583,12 +1601,15 @@ gst_avi_mux_write_index (GstAviMux * avimux)
|
||||||
GstFlowReturn res;
|
GstFlowReturn res;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
guint8 *buffdata;
|
guint8 *buffdata;
|
||||||
|
gsize buffsize;
|
||||||
|
|
||||||
buffer = gst_buffer_new_and_alloc (8);
|
buffer = gst_buffer_new_and_alloc (8);
|
||||||
buffdata = GST_BUFFER_DATA (buffer);
|
|
||||||
|
buffdata = gst_buffer_map (buffer, &buffsize, NULL, GST_MAP_WRITE);
|
||||||
memcpy (buffdata + 0, "idx1", 4);
|
memcpy (buffdata + 0, "idx1", 4);
|
||||||
GST_WRITE_UINT32_LE (buffdata + 4,
|
GST_WRITE_UINT32_LE (buffdata + 4,
|
||||||
avimux->idx_index * sizeof (gst_riff_index_entry));
|
avimux->idx_index * sizeof (gst_riff_index_entry));
|
||||||
|
gst_buffer_unmap (buffer, buffdata, buffsize);
|
||||||
|
|
||||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
|
gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
|
||||||
res = gst_pad_push (avimux->srcpad, buffer);
|
res = gst_pad_push (avimux->srcpad, buffer);
|
||||||
|
@ -1596,11 +1617,15 @@ gst_avi_mux_write_index (GstAviMux * avimux)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
buffer = gst_buffer_new ();
|
buffer = gst_buffer_new ();
|
||||||
GST_BUFFER_SIZE (buffer) = avimux->idx_index * sizeof (gst_riff_index_entry);
|
|
||||||
GST_BUFFER_DATA (buffer) = (guint8 *) avimux->idx;
|
buffsize = avimux->idx_index * sizeof (gst_riff_index_entry);
|
||||||
GST_BUFFER_MALLOCDATA (buffer) = GST_BUFFER_DATA (buffer);
|
buffdata = (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) + 8;
|
|
||||||
|
gst_buffer_take_memory (buffer,
|
||||||
|
gst_memory_new_wrapped (0, buffdata, g_free, buffsize, 0, buffsize));
|
||||||
|
|
||||||
|
avimux->total_data += buffsize + 8;
|
||||||
|
|
||||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
|
gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
|
||||||
res = gst_pad_push (avimux->srcpad, buffer);
|
res = gst_pad_push (avimux->srcpad, buffer);
|
||||||
|
@ -1682,7 +1707,7 @@ gst_avi_mux_bigfile (GstAviMux * avimux, gboolean last)
|
||||||
}
|
}
|
||||||
|
|
||||||
header = gst_avi_mux_riff_get_avix_header (0);
|
header = gst_avi_mux_riff_get_avix_header (0);
|
||||||
avimux->total_data += GST_BUFFER_SIZE (header);
|
avimux->total_data += gst_buffer_get_size (header);
|
||||||
/* avix_start is used as base offset for the odml index chunk */
|
/* avix_start is used as base offset for the odml index chunk */
|
||||||
avimux->idx_offset = avimux->total_data - avimux->avix_start;
|
avimux->idx_offset = avimux->total_data - avimux->avix_start;
|
||||||
gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
|
gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
|
||||||
|
@ -1753,7 +1778,7 @@ gst_avi_mux_start_file (GstAviMux * avimux)
|
||||||
avimux->is_bigfile = FALSE;
|
avimux->is_bigfile = FALSE;
|
||||||
|
|
||||||
header = gst_avi_mux_riff_get_avi_header (avimux);
|
header = gst_avi_mux_riff_get_avi_header (avimux);
|
||||||
avimux->total_data += GST_BUFFER_SIZE (header);
|
avimux->total_data += gst_buffer_get_size (header);
|
||||||
|
|
||||||
gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
|
gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
|
||||||
res = gst_pad_push (avimux->srcpad, header);
|
res = gst_pad_push (avimux->srcpad, header);
|
||||||
|
@ -1899,9 +1924,14 @@ static GstFlowReturn
|
||||||
gst_avi_mux_send_pad_data (GstAviMux * avimux, gulong num_bytes)
|
gst_avi_mux_send_pad_data (GstAviMux * avimux, gulong num_bytes)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
guint8 *bdata;
|
||||||
|
gsize bsize;
|
||||||
|
|
||||||
buffer = gst_buffer_new_and_alloc (num_bytes);
|
buffer = gst_buffer_new_and_alloc (num_bytes);
|
||||||
memset (GST_BUFFER_DATA (buffer), 0, num_bytes);
|
|
||||||
|
bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
|
||||||
|
memset (bdata, 0, num_bytes);
|
||||||
|
gst_buffer_unmap (buffer, bdata, bsize);
|
||||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
|
gst_buffer_set_caps (buffer, GST_PAD_CAPS (avimux->srcpad));
|
||||||
return gst_pad_push (avimux->srcpad, buffer);
|
return gst_pad_push (avimux->srcpad, buffer);
|
||||||
}
|
}
|
||||||
|
@ -1914,10 +1944,11 @@ gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
|
||||||
GstBuffer *data, *header;
|
GstBuffer *data, *header;
|
||||||
gulong total_size, pad_bytes = 0;
|
gulong total_size, pad_bytes = 0;
|
||||||
guint flags;
|
guint flags;
|
||||||
|
gsize datasize;
|
||||||
|
|
||||||
data = gst_collect_pads_pop (avimux->collect, avipad->collect);
|
data = gst_collect_pads_pop (avimux->collect, avipad->collect);
|
||||||
/* arrange downstream running time */
|
/* arrange downstream running time */
|
||||||
data = gst_buffer_make_metadata_writable (data);
|
data = gst_buffer_make_writable (data);
|
||||||
GST_BUFFER_TIMESTAMP (data) =
|
GST_BUFFER_TIMESTAMP (data) =
|
||||||
gst_segment_to_running_time (&avipad->collect->segment,
|
gst_segment_to_running_time (&avipad->collect->segment,
|
||||||
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (data));
|
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (data));
|
||||||
|
@ -1928,7 +1959,7 @@ gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
|
||||||
|
|
||||||
if (vidpad->prepend_buffer) {
|
if (vidpad->prepend_buffer) {
|
||||||
GstBuffer *newdata = gst_buffer_merge (vidpad->prepend_buffer, data);
|
GstBuffer *newdata = gst_buffer_merge (vidpad->prepend_buffer, data);
|
||||||
gst_buffer_copy_metadata (newdata, data, GST_BUFFER_COPY_TIMESTAMPS);
|
gst_buffer_copy_into (newdata, data, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
|
||||||
gst_buffer_unref (data);
|
gst_buffer_unref (data);
|
||||||
gst_buffer_unref (vidpad->prepend_buffer);
|
gst_buffer_unref (vidpad->prepend_buffer);
|
||||||
|
|
||||||
|
@ -1942,9 +1973,11 @@ gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
datasize = gst_buffer_get_size (data);
|
||||||
|
|
||||||
/* need to restart or start a next avix chunk ? */
|
/* need to restart or start a next avix chunk ? */
|
||||||
if ((avimux->is_bigfile ? avimux->datax_size : avimux->data_size) +
|
if ((avimux->is_bigfile ? avimux->datax_size : avimux->data_size) +
|
||||||
GST_BUFFER_SIZE (data) > GST_AVI_MAX_SIZE) {
|
datasize > GST_AVI_MAX_SIZE) {
|
||||||
if (avimux->enable_large_avi) {
|
if (avimux->enable_large_avi) {
|
||||||
if ((res = gst_avi_mux_bigfile (avimux, FALSE)) != GST_FLOW_OK)
|
if ((res = gst_avi_mux_bigfile (avimux, FALSE)) != GST_FLOW_OK)
|
||||||
return res;
|
return res;
|
||||||
|
@ -1955,11 +1988,11 @@ gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get header and record some stats */
|
/* get header and record some stats */
|
||||||
if (GST_BUFFER_SIZE (data) & 1) {
|
if (datasize & 1) {
|
||||||
pad_bytes = 2 - (GST_BUFFER_SIZE (data) & 1);
|
pad_bytes = 2 - (datasize & 1);
|
||||||
}
|
}
|
||||||
header = gst_avi_mux_riff_get_header (avipad, GST_BUFFER_SIZE (data));
|
header = gst_avi_mux_riff_get_header (avipad, datasize);
|
||||||
total_size = GST_BUFFER_SIZE (header) + GST_BUFFER_SIZE (data) + pad_bytes;
|
total_size = gst_buffer_get_size (header) + datasize + pad_bytes;
|
||||||
|
|
||||||
if (avimux->is_bigfile) {
|
if (avimux->is_bigfile) {
|
||||||
avimux->datax_size += total_size;
|
avimux->datax_size += total_size;
|
||||||
|
@ -1971,8 +2004,8 @@ gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
|
||||||
avipad->hook (avimux, avipad, data);
|
avipad->hook (avimux, avipad, data);
|
||||||
|
|
||||||
/* the suggested buffer size is the max frame size */
|
/* the suggested buffer size is the max frame size */
|
||||||
if (avipad->hdr.bufsize < GST_BUFFER_SIZE (data))
|
if (avipad->hdr.bufsize < datasize)
|
||||||
avipad->hdr.bufsize = GST_BUFFER_SIZE (data);
|
avipad->hdr.bufsize = datasize;
|
||||||
|
|
||||||
if (avipad->is_video) {
|
if (avipad->is_video) {
|
||||||
avimux->total_frames++;
|
avimux->total_frames++;
|
||||||
|
@ -1990,15 +2023,15 @@ gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
|
||||||
GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;
|
GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
audpad->audio_size += GST_BUFFER_SIZE (data);
|
audpad->audio_size += datasize;
|
||||||
audpad->audio_time += GST_BUFFER_DURATION (data);
|
audpad->audio_time += GST_BUFFER_DURATION (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_avi_mux_add_index (avimux, avipad, flags, GST_BUFFER_SIZE (data));
|
gst_avi_mux_add_index (avimux, avipad, flags, datasize);
|
||||||
|
|
||||||
/* prepare buffers for sending */
|
/* prepare buffers for sending */
|
||||||
gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
|
gst_buffer_set_caps (header, GST_PAD_CAPS (avimux->srcpad));
|
||||||
data = gst_buffer_make_metadata_writable (data);
|
data = gst_buffer_make_writable (data);
|
||||||
gst_buffer_set_caps (data, GST_PAD_CAPS (avimux->srcpad));
|
gst_buffer_set_caps (data, GST_PAD_CAPS (avimux->srcpad));
|
||||||
|
|
||||||
GST_LOG_OBJECT (avimux, "pushing buffers: head, data");
|
GST_LOG_OBJECT (avimux, "pushing buffers: head, data");
|
||||||
|
|
Loading…
Reference in a new issue