matroska: refactor code common to matroskademux and matroskaparse

Move the following functions to matroska-read-common.[ch] from
matroska-demux.c and matroska-parse.c:
    - gst_matroska_{demux,parse}_parse_header

https://bugzilla.gnome.org/show_bug.cgi?id=650877
This commit is contained in:
Debarshi Ray 2011-05-30 18:31:50 +05:30 committed by Sebastian Dröge
parent 63d350ceb3
commit 399fc9cd1c
4 changed files with 162 additions and 316 deletions

View file

@ -2221,163 +2221,6 @@ exit:
return ret;
}
static GstFlowReturn
gst_matroska_demux_parse_header (GstMatroskaDemux * demux, GstEbmlRead * ebml)
{
GstFlowReturn ret;
gchar *doctype;
guint version;
guint32 id;
/* this function is the first to be called */
/* default init */
doctype = NULL;
version = 1;
ret = gst_ebml_peek_id (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
GST_DEBUG_OBJECT (demux, "id: %08x", id);
if (id != GST_EBML_ID_HEADER) {
GST_ERROR_OBJECT (demux, "Failed to read header");
goto exit;
}
ret = gst_ebml_read_master (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
ret = gst_ebml_peek_id (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
switch (id) {
/* is our read version uptodate? */
case GST_EBML_ID_EBMLREADVERSION:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num != GST_EBML_VERSION) {
GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
break;
}
/* we only handle 8 byte lengths at max */
case GST_EBML_ID_EBMLMAXSIZELENGTH:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num > sizeof (guint64)) {
GST_ERROR_OBJECT (ebml,
"Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
break;
}
/* we handle 4 byte IDs at max */
case GST_EBML_ID_EBMLMAXIDLENGTH:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num > sizeof (guint32)) {
GST_ERROR_OBJECT (ebml,
"Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
break;
}
case GST_EBML_ID_DOCTYPE:{
gchar *text;
ret = gst_ebml_read_ascii (ebml, &id, &text);
if (ret != GST_FLOW_OK)
return ret;
GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
if (doctype)
g_free (doctype);
doctype = text;
break;
}
case GST_EBML_ID_DOCTYPEREADVERSION:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
version = num;
GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
break;
}
default:
ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
"EBML header", id);
if (ret != GST_FLOW_OK)
return ret;
break;
/* we ignore these two, as they don't tell us anything we care about */
case GST_EBML_ID_EBMLVERSION:
case GST_EBML_ID_DOCTYPEVERSION:
ret = gst_ebml_read_skip (ebml);
if (ret != GST_FLOW_OK)
return ret;
break;
}
}
exit:
if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
(doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
(doctype == NULL)) {
if (version <= 2) {
if (doctype) {
GST_INFO_OBJECT (demux, "Input is %s version %d", doctype, version);
} else {
GST_WARNING_OBJECT (demux, "Input is EBML without doctype, assuming "
"matroska (version %d)", version);
}
ret = GST_FLOW_OK;
} else {
GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
("Demuxer version (2) is too old to read %s version %d",
GST_STR_NULL (doctype), version));
ret = GST_FLOW_ERROR;
}
g_free (doctype);
} else {
GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
("Input is not a matroska stream (doctype=%s)", doctype));
ret = GST_FLOW_ERROR;
g_free (doctype);
}
return ret;
}
static GstFlowReturn
gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
{
@ -4722,7 +4565,7 @@ gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
switch (id) {
case GST_EBML_ID_HEADER:
GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
ret = gst_matroska_demux_parse_header (demux, &ebml);
ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
if (ret != GST_FLOW_OK)
goto parse_failed;
demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;

View file

@ -1523,163 +1523,6 @@ gst_matroska_parse_handle_src_event (GstPad * pad, GstEvent * event)
return res;
}
static GstFlowReturn
gst_matroska_parse_parse_header (GstMatroskaParse * parse, GstEbmlRead * ebml)
{
GstFlowReturn ret;
gchar *doctype;
guint version;
guint32 id;
/* this function is the first to be called */
/* default init */
doctype = NULL;
version = 1;
ret = gst_ebml_peek_id (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
GST_DEBUG_OBJECT (parse, "id: %08x", id);
if (id != GST_EBML_ID_HEADER) {
GST_ERROR_OBJECT (parse, "Failed to read header");
goto exit;
}
ret = gst_ebml_read_master (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
ret = gst_ebml_peek_id (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
switch (id) {
/* is our read version uptodate? */
case GST_EBML_ID_EBMLREADVERSION:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num != GST_EBML_VERSION) {
GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
break;
}
/* we only handle 8 byte lengths at max */
case GST_EBML_ID_EBMLMAXSIZELENGTH:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num > sizeof (guint64)) {
GST_ERROR_OBJECT (ebml,
"Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
break;
}
/* we handle 4 byte IDs at max */
case GST_EBML_ID_EBMLMAXIDLENGTH:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num > sizeof (guint32)) {
GST_ERROR_OBJECT (ebml,
"Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
break;
}
case GST_EBML_ID_DOCTYPE:{
gchar *text;
ret = gst_ebml_read_ascii (ebml, &id, &text);
if (ret != GST_FLOW_OK)
return ret;
GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
if (doctype)
g_free (doctype);
doctype = text;
break;
}
case GST_EBML_ID_DOCTYPEREADVERSION:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
version = num;
GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
break;
}
default:
ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
"EBML header", id);
if (ret != GST_FLOW_OK)
return ret;
break;
/* we ignore these two, as they don't tell us anything we care about */
case GST_EBML_ID_EBMLVERSION:
case GST_EBML_ID_DOCTYPEVERSION:
ret = gst_ebml_read_skip (ebml);
if (ret != GST_FLOW_OK)
return ret;
break;
}
}
exit:
if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
(doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
(doctype == NULL)) {
if (version <= 2) {
if (doctype) {
GST_INFO_OBJECT (parse, "Input is %s version %d", doctype, version);
} else {
GST_WARNING_OBJECT (parse, "Input is EBML without doctype, assuming "
"matroska (version %d)", version);
}
ret = GST_FLOW_OK;
} else {
GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
("Parser version (2) is too old to read %s version %d",
GST_STR_NULL (doctype), version));
ret = GST_FLOW_ERROR;
}
g_free (doctype);
} else {
GST_ELEMENT_ERROR (parse, STREAM, WRONG_TYPE, (NULL),
("Input is not a matroska stream (doctype=%s)", doctype));
ret = GST_FLOW_ERROR;
g_free (doctype);
}
return ret;
}
static GstFlowReturn
gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
{
@ -3349,7 +3192,7 @@ gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
switch (id) {
case GST_EBML_ID_HEADER:
GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
ret = gst_matroska_parse_parse_header (parse, &ebml);
ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
if (ret != GST_FLOW_OK)
goto parse_failed;
parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;

View file

@ -484,6 +484,164 @@ gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
return gst_ebml_read_skip (ebml);
}
GstFlowReturn
gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common,
GstEbmlRead * ebml)
{
GstFlowReturn ret;
gchar *doctype;
guint version;
guint32 id;
/* this function is the first to be called */
/* default init */
doctype = NULL;
version = 1;
ret = gst_ebml_peek_id (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
GST_DEBUG_OBJECT (common, "id: %08x", id);
if (id != GST_EBML_ID_HEADER) {
GST_ERROR_OBJECT (common, "Failed to read header");
goto exit;
}
ret = gst_ebml_read_master (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
ret = gst_ebml_peek_id (ebml, &id);
if (ret != GST_FLOW_OK)
return ret;
switch (id) {
/* is our read version uptodate? */
case GST_EBML_ID_EBMLREADVERSION:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num != GST_EBML_VERSION) {
GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
break;
}
/* we only handle 8 byte lengths at max */
case GST_EBML_ID_EBMLMAXSIZELENGTH:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num > sizeof (guint64)) {
GST_ERROR_OBJECT (ebml,
"Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
break;
}
/* we handle 4 byte IDs at max */
case GST_EBML_ID_EBMLMAXIDLENGTH:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
if (num > sizeof (guint32)) {
GST_ERROR_OBJECT (ebml,
"Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
return GST_FLOW_ERROR;
}
GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
break;
}
case GST_EBML_ID_DOCTYPE:{
gchar *text;
ret = gst_ebml_read_ascii (ebml, &id, &text);
if (ret != GST_FLOW_OK)
return ret;
GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
if (doctype)
g_free (doctype);
doctype = text;
break;
}
case GST_EBML_ID_DOCTYPEREADVERSION:{
guint64 num;
ret = gst_ebml_read_uint (ebml, &id, &num);
if (ret != GST_FLOW_OK)
return ret;
version = num;
GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
break;
}
default:
ret = gst_matroska_read_common_parse_skip (common, ebml,
"EBML header", id);
if (ret != GST_FLOW_OK)
return ret;
break;
/* we ignore these two, as they don't tell us anything we care about */
case GST_EBML_ID_EBMLVERSION:
case GST_EBML_ID_DOCTYPEVERSION:
ret = gst_ebml_read_skip (ebml);
if (ret != GST_FLOW_OK)
return ret;
break;
}
}
exit:
if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
(doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
(doctype == NULL)) {
if (version <= 2) {
if (doctype) {
GST_INFO_OBJECT (common, "Input is %s version %d", doctype, version);
} else {
GST_WARNING_OBJECT (common, "Input is EBML without doctype, assuming "
"matroska (version %d)", version);
}
ret = GST_FLOW_OK;
} else {
GST_ELEMENT_ERROR (common, STREAM, DEMUX, (NULL),
("Demuxer version (2) is too old to read %s version %d",
GST_STR_NULL (doctype), version));
ret = GST_FLOW_ERROR;
}
g_free (doctype);
} else {
GST_ELEMENT_ERROR (common, STREAM, WRONG_TYPE, (NULL),
("Input is not a matroska stream (doctype=%s)", doctype));
ret = GST_FLOW_ERROR;
g_free (doctype);
}
return ret;
}
static GstFlowReturn
gst_matroska_read_common_parse_index_cuetrack (GstMatroskaReadCommon * common,
GstEbmlRead * ebml, guint * nentries)

View file

@ -91,6 +91,8 @@ GstMatroskaTrackContext * gst_matroska_read_common_get_seek_track (
GstMatroskaReadCommon * common, GstMatroskaTrackContext * track);
GstFlowReturn gst_matroska_read_common_parse_index (GstMatroskaReadCommon *
common, GstEbmlRead * ebml);
GstFlowReturn gst_matroska_read_common_parse_header (GstMatroskaReadCommon *
common, GstEbmlRead * ebml);
GstFlowReturn gst_matroska_read_common_parse_skip (GstMatroskaReadCommon *
common, GstEbmlRead * ebml, const gchar * parent_name, guint id);
GstFlowReturn gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon *