mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 12:32:29 +00:00
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:
parent
63d350ceb3
commit
399fc9cd1c
4 changed files with 162 additions and 316 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 *
|
||||
|
|
Loading…
Reference in a new issue