mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 17:50:36 +00:00
gst/avi/gstavidemux.c: Use scaling code for added precission and more correct stop position in case scale==0.
Original commit message from CVS: * gst/avi/gstavidemux.c: (gst_avi_demux_src_convert), (gst_avi_demux_handle_src_query), (gst_avi_demux_handle_src_event), (gst_avi_demux_parse_file_header), (gst_avi_demux_stream_init), (gst_avi_demux_parse_avih), (gst_avi_demux_parse_superindex), (gst_avi_demux_parse_subindex), (gst_avi_demux_parse_stream), (gst_avi_demux_stream_header), (gst_avi_demux_change_state): Use scaling code for added precission and more correct stop position in case scale==0.
This commit is contained in:
parent
645eac79e8
commit
e9d173ccd5
2 changed files with 230 additions and 134 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2006-02-19 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/avi/gstavidemux.c: (gst_avi_demux_src_convert),
|
||||||
|
(gst_avi_demux_handle_src_query), (gst_avi_demux_handle_src_event),
|
||||||
|
(gst_avi_demux_parse_file_header), (gst_avi_demux_stream_init),
|
||||||
|
(gst_avi_demux_parse_avih), (gst_avi_demux_parse_superindex),
|
||||||
|
(gst_avi_demux_parse_subindex), (gst_avi_demux_parse_stream),
|
||||||
|
(gst_avi_demux_stream_header), (gst_avi_demux_change_state):
|
||||||
|
Use scaling code for added precission and more correct stop
|
||||||
|
position in case scale==0.
|
||||||
|
|
||||||
2006-02-19 Wim Taymans <wim@fluendo.com>
|
2006-02-19 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/flx/gstflxdec.c: (gst_flxdec_src_query_handler),
|
* gst/flx/gstflxdec.c: (gst_flxdec_src_query_handler),
|
||||||
|
|
|
@ -301,11 +301,13 @@ gst_avi_demux_src_convert (GstPad * pad,
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
switch (*dest_format) {
|
switch (*dest_format) {
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
*dest_value = src_value * stream->strf.auds->av_bps / GST_SECOND;
|
*dest_value =
|
||||||
|
gst_util_uint64_scale_int (src_value, stream->strf.auds->av_bps,
|
||||||
|
GST_SECOND);
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
*dest_value = src_value * stream->strh->rate /
|
*dest_value = gst_util_uint64_scale (src_value, stream->strh->rate,
|
||||||
(stream->strh->scale * GST_SECOND);
|
stream->strh->scale * GST_SECOND);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
|
@ -316,8 +318,8 @@ gst_avi_demux_src_convert (GstPad * pad,
|
||||||
switch (*dest_format) {
|
switch (*dest_format) {
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
if (stream->strf.auds->av_bps != 0) {
|
if (stream->strf.auds->av_bps != 0) {
|
||||||
*dest_value = ((gfloat) src_value) * GST_SECOND /
|
*dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
|
||||||
stream->strf.auds->av_bps;
|
stream->strf.auds->av_bps);
|
||||||
} else
|
} else
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
break;
|
break;
|
||||||
|
@ -329,8 +331,9 @@ gst_avi_demux_src_convert (GstPad * pad,
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
switch (*dest_format) {
|
switch (*dest_format) {
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
*dest_value = ((((gfloat) src_value) * stream->strh->scale) /
|
*dest_value =
|
||||||
stream->strh->rate) * GST_SECOND;
|
gst_util_uint64_scale (src_value,
|
||||||
|
stream->strh->scale * GST_SECOND, stream->strh->rate);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
|
@ -377,27 +380,30 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
|
||||||
|
|
||||||
if (stream->strh->type == GST_RIFF_FCC_auds) {
|
if (stream->strh->type == GST_RIFF_FCC_auds) {
|
||||||
if (!stream->strh->samplesize) {
|
if (!stream->strh->samplesize) {
|
||||||
pos = GST_SECOND * stream->current_frame *
|
pos = gst_util_uint64_scale_int ((gint64) stream->current_frame *
|
||||||
stream->strh->scale / stream->strh->rate;
|
stream->strh->scale, GST_SECOND, stream->strh->rate);
|
||||||
} else if (stream->strf.auds->av_bps != 0) {
|
} else if (stream->strf.auds->av_bps != 0) {
|
||||||
pos = ((gfloat) stream->current_byte) * GST_SECOND /
|
pos = gst_util_uint64_scale_int (stream->current_byte, GST_SECOND,
|
||||||
stream->strf.auds->av_bps;
|
stream->strf.auds->av_bps);
|
||||||
} else if (stream->total_frames != 0 && stream->total_bytes != 0) {
|
} else if (stream->total_frames != 0 && stream->total_bytes != 0) {
|
||||||
/* calculate timestamps based on video size */
|
/* calculate timestamps based on video size */
|
||||||
guint64 xlen = demux->avih->us_frame *
|
guint64 xlen = demux->avih->us_frame *
|
||||||
demux->avih->tot_frames * GST_USECOND;
|
demux->avih->tot_frames * GST_USECOND;
|
||||||
|
|
||||||
if (!stream->strh->samplesize)
|
if (!stream->strh->samplesize)
|
||||||
pos = xlen * stream->current_frame / stream->total_frames;
|
pos = gst_util_uint64_scale_int (xlen, stream->current_frame,
|
||||||
|
stream->total_frames);
|
||||||
else
|
else
|
||||||
pos = xlen * stream->current_byte / stream->total_bytes;
|
pos = gst_util_uint64_scale_int (xlen, stream->current_byte,
|
||||||
|
stream->total_bytes);
|
||||||
} else {
|
} else {
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (stream->strh->rate != 0) {
|
if (stream->strh->rate != 0) {
|
||||||
pos = ((gfloat) stream->current_frame * stream->strh->scale *
|
pos =
|
||||||
GST_SECOND / stream->strh->rate);
|
gst_util_uint64_scale_int ((guint64) stream->current_frame *
|
||||||
|
stream->strh->scale, GST_SECOND, stream->strh->rate);
|
||||||
} else {
|
} else {
|
||||||
pos = stream->current_frame * demux->avih->us_frame * GST_USECOND;
|
pos = stream->current_frame * demux->avih->us_frame * GST_USECOND;
|
||||||
}
|
}
|
||||||
|
@ -410,8 +416,9 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
|
||||||
{
|
{
|
||||||
gint64 len;
|
gint64 len;
|
||||||
|
|
||||||
len = (((gfloat) stream->strh->scale) * stream->strh->length /
|
len =
|
||||||
stream->strh->rate) * GST_SECOND;
|
gst_util_uint64_scale ((guint64) stream->strh->length *
|
||||||
|
stream->strh->scale, GST_SECOND, stream->strh->rate);
|
||||||
gst_query_set_duration (query, GST_FORMAT_TIME, len);
|
gst_query_set_duration (query, GST_FORMAT_TIME, len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -486,8 +493,9 @@ gst_avi_demux_handle_src_event (GstPad * pad, GstEvent * event)
|
||||||
tstop = stop;
|
tstop = stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
duration = (((gfloat) stream->strh->scale) * stream->strh->length /
|
duration =
|
||||||
stream->strh->rate) * GST_SECOND;
|
gst_util_uint64_scale ((guint64) stream->strh->length *
|
||||||
|
stream->strh->scale, GST_SECOND, stream->strh->rate);
|
||||||
|
|
||||||
switch (start_type) {
|
switch (start_type) {
|
||||||
case GST_SEEK_TYPE_CUR:
|
case GST_SEEK_TYPE_CUR:
|
||||||
|
@ -562,14 +570,19 @@ gst_avi_demux_parse_file_header (GstElement * element, GstBuffer * buf)
|
||||||
if (!gst_riff_parse_file_header (element, buf, &doctype))
|
if (!gst_riff_parse_file_header (element, buf, &doctype))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (doctype != GST_RIFF_RIFF_AVI) {
|
if (doctype != GST_RIFF_RIFF_AVI)
|
||||||
|
goto not_avi;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
not_avi:
|
||||||
|
{
|
||||||
GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
|
GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
|
||||||
("File is not an AVI file: %" GST_FOURCC_FORMAT,
|
("File is not an AVI file: %" GST_FOURCC_FORMAT,
|
||||||
GST_FOURCC_ARGS (doctype)));
|
GST_FOURCC_ARGS (doctype)));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -582,11 +595,19 @@ gst_avi_demux_stream_init (GstAviDemux * avi)
|
||||||
avi->offset, 12, &buf)) != GST_FLOW_OK)
|
avi->offset, 12, &buf)) != GST_FLOW_OK)
|
||||||
return res;
|
return res;
|
||||||
else if (!gst_avi_demux_parse_file_header (GST_ELEMENT (avi), buf))
|
else if (!gst_avi_demux_parse_file_header (GST_ELEMENT (avi), buf))
|
||||||
return GST_FLOW_ERROR;
|
goto wrong_header;
|
||||||
|
|
||||||
avi->offset += 12;
|
avi->offset += 12;
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
wrong_header:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (avi, "error parsing file header");
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -609,14 +630,11 @@ gst_avi_demux_parse_avih (GstElement * element,
|
||||||
{
|
{
|
||||||
gst_riff_avih *avih;
|
gst_riff_avih *avih;
|
||||||
|
|
||||||
if (!buf || GST_BUFFER_SIZE (buf) < sizeof (gst_riff_avih)) {
|
if (buf == NULL)
|
||||||
GST_ELEMENT_ERROR (element, STREAM, DEMUX, (NULL),
|
goto no_buffer;
|
||||||
("Too small avih (%d available, %d needed)",
|
|
||||||
GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_avih)));
|
if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_avih))
|
||||||
if (buf)
|
goto avih_too_small;
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
avih = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
avih = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
||||||
|
|
||||||
|
@ -658,6 +676,21 @@ gst_avi_demux_parse_avih (GstElement * element,
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_buffer:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (element, STREAM, DEMUX, (NULL), ("No buffer"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
avih_too_small:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (element, STREAM, DEMUX, (NULL),
|
||||||
|
("Too small avih (%d available, %d needed)",
|
||||||
|
GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_avih)));
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -684,14 +717,11 @@ gst_avi_demux_parse_superindex (GstElement * element,
|
||||||
|
|
||||||
*_indexes = NULL;
|
*_indexes = NULL;
|
||||||
|
|
||||||
if (!buf || GST_BUFFER_SIZE (buf) < 24) {
|
if (buf == NULL)
|
||||||
GST_ERROR_OBJECT (element,
|
goto no_buffer;
|
||||||
"Not enough data to parse superindex (%d available, %d needed)",
|
|
||||||
GST_BUFFER_SIZE (buf), 24);
|
if (!buf || GST_BUFFER_SIZE (buf) < 24)
|
||||||
if (buf)
|
goto too_small;
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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
|
||||||
|
@ -718,6 +748,21 @@ gst_avi_demux_parse_superindex (GstElement * element,
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_buffer:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (element, "No buffer");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
too_small:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (element,
|
||||||
|
"Not enough data to parse superindex (%d available, %d needed)",
|
||||||
|
GST_BUFFER_SIZE (buf), 24);
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -751,23 +796,15 @@ gst_avi_demux_parse_subindex (GstElement * element,
|
||||||
gint64 tmp;
|
gint64 tmp;
|
||||||
|
|
||||||
/* check size */
|
/* check size */
|
||||||
if (!buf || GST_BUFFER_SIZE (buf) < 24) {
|
if (buf == NULL)
|
||||||
GST_ERROR_OBJECT (element,
|
goto no_buffer;
|
||||||
"Not enough data to parse subindex (%d available, %d needed)",
|
|
||||||
GST_BUFFER_SIZE (buf), 24);
|
if (GST_BUFFER_SIZE (buf) < 24)
|
||||||
if (buf)
|
goto too_small;
|
||||||
gst_buffer_unref (buf);
|
|
||||||
*_entries_list = NULL;
|
|
||||||
return TRUE; /* continue */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We don't support index-data yet */
|
/* We don't support index-data yet */
|
||||||
if (data[3] & 0x80) {
|
if (data[3] & 0x80)
|
||||||
GST_ELEMENT_ERROR (element, STREAM, NOT_IMPLEMENTED, (NULL),
|
goto not_implemented;
|
||||||
("Subindex-is-data is not implemented"));
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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
|
||||||
|
@ -840,6 +877,29 @@ gst_avi_demux_parse_subindex (GstElement * element,
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_buffer:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (element, "No buffer");
|
||||||
|
return TRUE; /* continue */
|
||||||
|
}
|
||||||
|
too_small:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (element,
|
||||||
|
"Not enough data to parse subindex (%d available, %d needed)",
|
||||||
|
GST_BUFFER_SIZE (buf), 24);
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
*_entries_list = NULL;
|
||||||
|
return TRUE; /* continue */
|
||||||
|
}
|
||||||
|
not_implemented:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (element, STREAM, NOT_IMPLEMENTED, (NULL),
|
||||||
|
("Subindex-is-data is not implemented"));
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1060,14 +1120,10 @@ gst_avi_demux_parse_stream (GstElement * element, GstBuffer * buf)
|
||||||
gst_pad_use_fixed_caps (pad);
|
gst_pad_use_fixed_caps (pad);
|
||||||
#if 0
|
#if 0
|
||||||
gst_pad_set_formats_function (pad, gst_avi_demux_get_src_formats);
|
gst_pad_set_formats_function (pad, gst_avi_demux_get_src_formats);
|
||||||
gst_pad_set_event_mask_function (pad, gst_avi_demux_get_event_mask);
|
|
||||||
#endif
|
#endif
|
||||||
gst_pad_set_event_function (pad, gst_avi_demux_handle_src_event);
|
gst_pad_set_event_function (pad, gst_avi_demux_handle_src_event);
|
||||||
gst_pad_set_query_type_function (pad, gst_avi_demux_get_src_query_types);
|
gst_pad_set_query_type_function (pad, gst_avi_demux_get_src_query_types);
|
||||||
gst_pad_set_query_function (pad, gst_avi_demux_handle_src_query);
|
gst_pad_set_query_function (pad, gst_avi_demux_handle_src_query);
|
||||||
#if 0
|
|
||||||
gst_pad_set_convert_function (pad, gst_avi_demux_src_convert);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
stream->num = avi->num_streams;
|
stream->num = avi->num_streams;
|
||||||
stream->total_bytes = 0;
|
stream->total_bytes = 0;
|
||||||
|
@ -1093,24 +1149,27 @@ gst_avi_demux_parse_stream (GstElement * element, GstBuffer * buf)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
fail:
|
fail:
|
||||||
/* unref any mem that may be in use */
|
{
|
||||||
if (buf)
|
/* unref any mem that may be in use */
|
||||||
gst_buffer_unref (buf);
|
if (buf)
|
||||||
if (sub)
|
gst_buffer_unref (buf);
|
||||||
gst_buffer_unref (sub);
|
if (sub)
|
||||||
g_free (stream->strh);
|
gst_buffer_unref (sub);
|
||||||
g_free (stream->strf.data);
|
g_free (stream->strh);
|
||||||
g_free (stream->name);
|
g_free (stream->strf.data);
|
||||||
g_free (stream->indexes);
|
g_free (stream->name);
|
||||||
if (stream->initdata)
|
g_free (stream->indexes);
|
||||||
gst_buffer_unref (stream->initdata);
|
if (stream->initdata)
|
||||||
if (stream->extradata)
|
gst_buffer_unref (stream->initdata);
|
||||||
gst_buffer_unref (stream->extradata);
|
if (stream->extradata)
|
||||||
memset (stream, 0, sizeof (avi_stream_context));
|
gst_buffer_unref (stream->extradata);
|
||||||
avi->num_streams++;
|
memset (stream, 0, sizeof (avi_stream_context));
|
||||||
|
avi->num_streams++;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1942,19 +2001,13 @@ gst_avi_demux_stream_header (GstAviDemux * avi)
|
||||||
if ((res = gst_riff_read_chunk (GST_ELEMENT (avi), avi->sinkpad,
|
if ((res = gst_riff_read_chunk (GST_ELEMENT (avi), avi->sinkpad,
|
||||||
&avi->offset, &tag, &buf)) != GST_FLOW_OK)
|
&avi->offset, &tag, &buf)) != GST_FLOW_OK)
|
||||||
return res;
|
return res;
|
||||||
else if (tag != GST_RIFF_TAG_LIST) {
|
else if (tag != GST_RIFF_TAG_LIST)
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
goto no_list;
|
||||||
("Invalid AVI header (no LIST at start): %"
|
else if (GST_BUFFER_SIZE (buf) < 4)
|
||||||
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
|
goto no_header;
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
} else if (GST_BUFFER_SIZE (buf) < 4) {
|
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL), ("No header found"));
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the 'hdrl' LIST tag */
|
/* Find the 'hdrl' LIST tag */
|
||||||
while (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl) {
|
while (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != 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 (GST_BUFFER_DATA (buf))));
|
||||||
|
|
||||||
|
@ -1963,37 +2016,18 @@ gst_avi_demux_stream_header (GstAviDemux * avi)
|
||||||
if ((res = gst_riff_read_chunk (GST_ELEMENT (avi), avi->sinkpad,
|
if ((res = gst_riff_read_chunk (GST_ELEMENT (avi), avi->sinkpad,
|
||||||
&avi->offset, &tag, &buf)) != GST_FLOW_OK)
|
&avi->offset, &tag, &buf)) != GST_FLOW_OK)
|
||||||
return res;
|
return res;
|
||||||
else if (tag != GST_RIFF_TAG_LIST) {
|
else if (tag != GST_RIFF_TAG_LIST)
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
goto no_list;
|
||||||
("Invalid AVI header (no LIST at start): %"
|
else if (GST_BUFFER_SIZE (buf) < 4)
|
||||||
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
|
goto no_header;
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
} else if (GST_BUFFER_SIZE (buf) < 4) {
|
|
||||||
|
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
|
||||||
("Invalid AVI header (no hdrl at start): %"
|
|
||||||
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the hdrl starts with a 'avih' header */
|
/* the hdrl starts with a 'avih' header */
|
||||||
if (!gst_riff_parse_chunk (GST_ELEMENT (avi), buf, &offset, &tag, &sub) ||
|
if (!gst_riff_parse_chunk (GST_ELEMENT (avi), buf, &offset, &tag, &sub) ||
|
||||||
tag != GST_RIFF_TAG_avih) {
|
tag != GST_RIFF_TAG_avih)
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
goto no_avih;
|
||||||
("Invalid AVI header (no avih at start): %"
|
else if (!gst_avi_demux_parse_avih (GST_ELEMENT (avi), sub, &avi->avih))
|
||||||
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
|
goto invalid_avih;
|
||||||
if (sub) {
|
|
||||||
gst_buffer_unref (sub);
|
|
||||||
sub = NULL;
|
|
||||||
}
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
} else if (!gst_avi_demux_parse_avih (GST_ELEMENT (avi), sub, &avi->avih)) {
|
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 (GST_ELEMENT (avi), buf, &offset, &tag, &sub)) {
|
while (gst_riff_parse_chunk (GST_ELEMENT (avi), buf, &offset, &tag, &sub)) {
|
||||||
|
@ -2045,10 +2079,9 @@ gst_avi_demux_stream_header (GstAviDemux * avi)
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
/* check parsed streams */
|
/* check parsed streams */
|
||||||
if (avi->num_streams == 0) {
|
if (avi->num_streams == 0)
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL), ("No streams found"));
|
goto no_streams;
|
||||||
return GST_FLOW_ERROR;
|
else if (avi->num_streams != avi->avih->streams) {
|
||||||
} else if (avi->num_streams != avi->avih->streams) {
|
|
||||||
GST_WARNING_OBJECT (avi,
|
GST_WARNING_OBJECT (avi,
|
||||||
"Stream header mentioned %d streams, but %d available",
|
"Stream header mentioned %d streams, but %d available",
|
||||||
avi->avih->streams, avi->num_streams);
|
avi->avih->streams, avi->num_streams);
|
||||||
|
@ -2119,22 +2152,19 @@ done:
|
||||||
gst_avi_demux_stream_scan (avi, &index, &alloc);
|
gst_avi_demux_stream_scan (avi, &index, &alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index) {
|
if (!index)
|
||||||
gst_avi_demux_massage_index (avi, index, alloc);
|
goto no_index;
|
||||||
} else {
|
|
||||||
g_list_free (index);
|
|
||||||
g_list_foreach (alloc, (GFunc) g_free, NULL);
|
|
||||||
g_list_free (alloc);
|
|
||||||
|
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
|
gst_avi_demux_massage_index (avi, index, alloc);
|
||||||
("Could not get/create index"));
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send initial discont */
|
/* send initial discont */
|
||||||
avi->segment_start = 0;
|
avi->segment_start = 0;
|
||||||
avi->segment_stop = (gint64) (((gfloat) avi->stream[0].strh->scale) *
|
avi->segment_stop =
|
||||||
avi->stream[0].strh->length / avi->stream[0].strh->rate) * GST_SECOND;
|
gst_util_uint64_scale_int ((gint64) avi->stream[0].strh->scale *
|
||||||
|
avi->stream[0].strh->length, GST_SECOND, avi->stream[0].strh->rate);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (avi, "segment stop %" G_GINT64_FORMAT, avi->segment_stop);
|
||||||
|
|
||||||
avi->seek_event = gst_event_new_new_segment
|
avi->seek_event = gst_event_new_new_segment
|
||||||
(FALSE, avi->segment_rate, GST_FORMAT_TIME,
|
(FALSE, avi->segment_rate, GST_FORMAT_TIME,
|
||||||
avi->segment_start, avi->segment_stop, avi->segment_start);
|
avi->segment_start, avi->segment_stop, avi->segment_start);
|
||||||
|
@ -2145,6 +2175,62 @@ done:
|
||||||
gst_element_no_more_pads (GST_ELEMENT (avi));
|
gst_element_no_more_pads (GST_ELEMENT (avi));
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_list:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
||||||
|
("Invalid AVI header (no LIST at start): %"
|
||||||
|
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
no_header:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
||||||
|
("Invalid AVI header (no hdrl at start): %"
|
||||||
|
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
no_avih:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
||||||
|
("Invalid AVI header (no avih at start): %"
|
||||||
|
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (tag)));
|
||||||
|
if (sub) {
|
||||||
|
gst_buffer_unref (sub);
|
||||||
|
sub = NULL;
|
||||||
|
}
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
invalid_avih:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
||||||
|
("Invalid AVI header (cannot parse avih at start)"));
|
||||||
|
if (sub) {
|
||||||
|
gst_buffer_unref (sub);
|
||||||
|
sub = NULL;
|
||||||
|
}
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
no_streams:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL), ("No streams found"));
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
no_index:
|
||||||
|
{
|
||||||
|
g_list_free (index);
|
||||||
|
g_list_foreach (alloc, (GFunc) g_free, NULL);
|
||||||
|
g_list_free (alloc);
|
||||||
|
|
||||||
|
GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
|
||||||
|
("Could not get/create index"));
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2522,6 +2608,7 @@ gst_avi_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_avi_demux_change_state (GstElement * element, GstStateChange transition)
|
gst_avi_demux_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
|
GstStateChangeReturn ret;
|
||||||
GstAviDemux *avi = GST_AVI_DEMUX (element);
|
GstAviDemux *avi = GST_AVI_DEMUX (element);
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
|
@ -2531,13 +2618,10 @@ gst_avi_demux_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_ELEMENT_CLASS (parent_class)->change_state) {
|
|
||||||
GstStateChangeReturn ret;
|
|
||||||
|
|
||||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
if (ret != GST_STATE_CHANGE_SUCCESS)
|
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||||
return ret;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
|
@ -2547,5 +2631,6 @@ gst_avi_demux_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_STATE_CHANGE_SUCCESS;
|
done:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue