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}_encoding_order_unique
    - gst_matroska_{demux,parse}_read_track_encoding

https://bugzilla.gnome.org/show_bug.cgi?id=650877
This commit is contained in:
Debarshi Ray 2011-05-23 18:06:44 +03:00 committed by Sebastian Dröge
parent 397dc60b71
commit f885e2721a
4 changed files with 186 additions and 356 deletions

View file

@ -588,183 +588,6 @@ gst_matroska_demux_encoding_cmp (GstMatroskaTrackEncoding * a,
return 0; return 0;
} }
static gboolean
gst_matroska_demux_encoding_order_unique (GArray * encodings, guint64 order)
{
gint i;
if (encodings == NULL || encodings->len == 0)
return TRUE;
for (i = 0; i < encodings->len; i++)
if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
return FALSE;
return TRUE;
}
static GstFlowReturn
gst_matroska_demux_read_track_encoding (GstMatroskaDemux * demux,
GstEbmlRead * ebml, GstMatroskaTrackContext * context)
{
GstMatroskaTrackEncoding enc = { 0, };
GstFlowReturn ret;
guint32 id;
DEBUG_ELEMENT_START (demux, ebml, "ContentEncoding");
/* Set default values */
enc.scope = 1;
/* All other default values are 0 */
if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
return ret;
}
while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
break;
switch (id) {
case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (!gst_matroska_demux_encoding_order_unique (context->encodings, num)) {
GST_ERROR_OBJECT (demux, "ContentEncodingOrder %" G_GUINT64_FORMAT
"is not unique for track %d", num, context->num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (demux, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
num);
enc.order = num;
break;
}
case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (num > 7 && num == 0) {
GST_ERROR_OBJECT (demux, "Invalid ContentEncodingScope %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (demux, "ContentEncodingScope: %" G_GUINT64_FORMAT,
num);
enc.scope = num;
break;
}
case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (num > 1) {
GST_ERROR_OBJECT (demux, "Invalid ContentEncodingType %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
} else if (num != 0) {
GST_ERROR_OBJECT (demux, "Encrypted tracks are not supported yet");
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (demux, "ContentEncodingType: %" G_GUINT64_FORMAT,
num);
enc.type = num;
break;
}
case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
DEBUG_ELEMENT_START (demux, ebml, "ContentCompression");
if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
break;
while (ret == GST_FLOW_OK &&
gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
break;
switch (id) {
case GST_MATROSKA_ID_CONTENTCOMPALGO:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
break;
}
if (num > 3) {
GST_ERROR_OBJECT (demux, "Invalid ContentCompAlgo %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (demux, "ContentCompAlgo: %" G_GUINT64_FORMAT,
num);
enc.comp_algo = num;
break;
}
case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
guint8 *data;
guint64 size;
if ((ret =
gst_ebml_read_binary (ebml, &id, &data,
&size)) != GST_FLOW_OK) {
break;
}
enc.comp_settings = data;
enc.comp_settings_length = size;
GST_DEBUG_OBJECT (demux,
"ContentCompSettings of size %" G_GUINT64_FORMAT, size);
break;
}
default:
GST_WARNING_OBJECT (demux,
"Unknown ContentCompression subelement 0x%x - ignoring", id);
ret = gst_ebml_read_skip (ebml);
break;
}
}
DEBUG_ELEMENT_STOP (demux, ebml, "ContentCompression", ret);
break;
}
case GST_MATROSKA_ID_CONTENTENCRYPTION:
GST_ERROR_OBJECT (demux, "Encrypted tracks not yet supported");
gst_ebml_read_skip (ebml);
ret = GST_FLOW_ERROR;
break;
default:
GST_WARNING_OBJECT (demux,
"Unknown ContentEncoding subelement 0x%x - ignoring", id);
ret = gst_ebml_read_skip (ebml);
break;
}
}
DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
return ret;
/* TODO: Check if the combination of values is valid */
g_array_append_val (context->encodings, enc);
return ret;
}
static gboolean static gboolean
gst_matroska_decode_data (GArray * encodings, guint8 ** data_out, gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free) guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
@ -884,7 +707,8 @@ gst_matroska_demux_read_track_encodings (GstMatroskaDemux * demux,
switch (id) { switch (id) {
case GST_MATROSKA_ID_CONTENTENCODING: case GST_MATROSKA_ID_CONTENTENCODING:
ret = gst_matroska_demux_read_track_encoding (demux, ebml, context); ret = gst_matroska_read_common_read_track_encoding (&demux->common,
ebml, context);
break; break;
default: default:
GST_WARNING_OBJECT (demux, GST_WARNING_OBJECT (demux,

View file

@ -511,183 +511,6 @@ gst_matroska_parse_encoding_cmp (GstMatroskaTrackEncoding * a,
return 0; return 0;
} }
static gboolean
gst_matroska_parse_encoding_order_unique (GArray * encodings, guint64 order)
{
gint i;
if (encodings == NULL || encodings->len == 0)
return TRUE;
for (i = 0; i < encodings->len; i++)
if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
return FALSE;
return TRUE;
}
static GstFlowReturn
gst_matroska_parse_read_track_encoding (GstMatroskaParse * parse,
GstEbmlRead * ebml, GstMatroskaTrackContext * context)
{
GstMatroskaTrackEncoding enc = { 0, };
GstFlowReturn ret;
guint32 id;
DEBUG_ELEMENT_START (parse, ebml, "ContentEncoding");
/* Set default values */
enc.scope = 1;
/* All other default values are 0 */
if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
DEBUG_ELEMENT_STOP (parse, ebml, "ContentEncoding", ret);
return ret;
}
while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
break;
switch (id) {
case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (!gst_matroska_parse_encoding_order_unique (context->encodings, num)) {
GST_ERROR_OBJECT (parse, "ContentEncodingOrder %" G_GUINT64_FORMAT
"is not unique for track %d", num, context->num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (parse, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
num);
enc.order = num;
break;
}
case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (num > 7 && num == 0) {
GST_ERROR_OBJECT (parse, "Invalid ContentEncodingScope %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (parse, "ContentEncodingScope: %" G_GUINT64_FORMAT,
num);
enc.scope = num;
break;
}
case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (num > 1) {
GST_ERROR_OBJECT (parse, "Invalid ContentEncodingType %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
} else if (num != 0) {
GST_ERROR_OBJECT (parse, "Encrypted tracks are not supported yet");
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (parse, "ContentEncodingType: %" G_GUINT64_FORMAT,
num);
enc.type = num;
break;
}
case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
DEBUG_ELEMENT_START (parse, ebml, "ContentCompression");
if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
break;
while (ret == GST_FLOW_OK &&
gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
break;
switch (id) {
case GST_MATROSKA_ID_CONTENTCOMPALGO:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
break;
}
if (num > 3) {
GST_ERROR_OBJECT (parse, "Invalid ContentCompAlgo %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (parse, "ContentCompAlgo: %" G_GUINT64_FORMAT,
num);
enc.comp_algo = num;
break;
}
case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
guint8 *data;
guint64 size;
if ((ret =
gst_ebml_read_binary (ebml, &id, &data,
&size)) != GST_FLOW_OK) {
break;
}
enc.comp_settings = data;
enc.comp_settings_length = size;
GST_DEBUG_OBJECT (parse,
"ContentCompSettings of size %" G_GUINT64_FORMAT, size);
break;
}
default:
GST_WARNING_OBJECT (parse,
"Unknown ContentCompression subelement 0x%x - ignoring", id);
ret = gst_ebml_read_skip (ebml);
break;
}
}
DEBUG_ELEMENT_STOP (parse, ebml, "ContentCompression", ret);
break;
}
case GST_MATROSKA_ID_CONTENTENCRYPTION:
GST_ERROR_OBJECT (parse, "Encrypted tracks not yet supported");
gst_ebml_read_skip (ebml);
ret = GST_FLOW_ERROR;
break;
default:
GST_WARNING_OBJECT (parse,
"Unknown ContentEncoding subelement 0x%x - ignoring", id);
ret = gst_ebml_read_skip (ebml);
break;
}
}
DEBUG_ELEMENT_STOP (parse, ebml, "ContentEncoding", ret);
if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
return ret;
/* TODO: Check if the combination of values is valid */
g_array_append_val (context->encodings, enc);
return ret;
}
static gboolean static gboolean
gst_matroska_decode_data (GArray * encodings, guint8 ** data_out, gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free) guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
@ -773,7 +596,8 @@ gst_matroska_parse_read_track_encodings (GstMatroskaParse * parse,
switch (id) { switch (id) {
case GST_MATROSKA_ID_CONTENTENCODING: case GST_MATROSKA_ID_CONTENTENCODING:
ret = gst_matroska_parse_read_track_encoding (parse, ebml, context); ret = gst_matroska_read_common_read_track_encoding (&parse->common,
ebml, context);
break; break;
default: default:
GST_WARNING_OBJECT (parse, GST_WARNING_OBJECT (parse,

View file

@ -280,6 +280,22 @@ gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
return 0; return 0;
} }
static gboolean
gst_matroska_read_common_encoding_order_unique (GArray * encodings, guint64
order)
{
gint i;
if (encodings == NULL || encodings->len == 0)
return TRUE;
for (i = 0; i < encodings->len; i++)
if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
return FALSE;
return TRUE;
}
/* skip unknown or alike element */ /* skip unknown or alike element */
GstFlowReturn GstFlowReturn
gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common, gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
@ -607,3 +623,166 @@ gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
return ret; return ret;
} }
GstFlowReturn
gst_matroska_read_common_read_track_encoding (GstMatroskaReadCommon * common,
GstEbmlRead * ebml, GstMatroskaTrackContext * context)
{
GstMatroskaTrackEncoding enc = { 0, };
GstFlowReturn ret;
guint32 id;
DEBUG_ELEMENT_START (common, ebml, "ContentEncoding");
/* Set default values */
enc.scope = 1;
/* All other default values are 0 */
if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
return ret;
}
while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
break;
switch (id) {
case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (!gst_matroska_read_common_encoding_order_unique (context->encodings,
num)) {
GST_ERROR_OBJECT (common, "ContentEncodingOrder %" G_GUINT64_FORMAT
"is not unique for track %d", num, context->num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (common, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
num);
enc.order = num;
break;
}
case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (num > 7 && num == 0) {
GST_ERROR_OBJECT (common, "Invalid ContentEncodingScope %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (common, "ContentEncodingScope: %" G_GUINT64_FORMAT,
num);
enc.scope = num;
break;
}
case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
break;
if (num > 1) {
GST_ERROR_OBJECT (common, "Invalid ContentEncodingType %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
} else if (num != 0) {
GST_ERROR_OBJECT (common, "Encrypted tracks are not supported yet");
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (common, "ContentEncodingType: %" G_GUINT64_FORMAT,
num);
enc.type = num;
break;
}
case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
DEBUG_ELEMENT_START (common, ebml, "ContentCompression");
if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
break;
while (ret == GST_FLOW_OK &&
gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
break;
switch (id) {
case GST_MATROSKA_ID_CONTENTCOMPALGO:{
guint64 num;
if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
break;
}
if (num > 3) {
GST_ERROR_OBJECT (common, "Invalid ContentCompAlgo %"
G_GUINT64_FORMAT, num);
ret = GST_FLOW_ERROR;
break;
}
GST_DEBUG_OBJECT (common, "ContentCompAlgo: %" G_GUINT64_FORMAT,
num);
enc.comp_algo = num;
break;
}
case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
guint8 *data;
guint64 size;
if ((ret =
gst_ebml_read_binary (ebml, &id, &data,
&size)) != GST_FLOW_OK) {
break;
}
enc.comp_settings = data;
enc.comp_settings_length = size;
GST_DEBUG_OBJECT (common,
"ContentCompSettings of size %" G_GUINT64_FORMAT, size);
break;
}
default:
GST_WARNING_OBJECT (common,
"Unknown ContentCompression subelement 0x%x - ignoring", id);
ret = gst_ebml_read_skip (ebml);
break;
}
}
DEBUG_ELEMENT_STOP (common, ebml, "ContentCompression", ret);
break;
}
case GST_MATROSKA_ID_CONTENTENCRYPTION:
GST_ERROR_OBJECT (common, "Encrypted tracks not yet supported");
gst_ebml_read_skip (ebml);
ret = GST_FLOW_ERROR;
break;
default:
GST_WARNING_OBJECT (common,
"Unknown ContentEncoding subelement 0x%x - ignoring", id);
ret = gst_ebml_read_skip (ebml);
break;
}
}
DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
return ret;
/* TODO: Check if the combination of values is valid */
g_array_append_val (context->encodings, enc);
return ret;
}

View file

@ -73,6 +73,9 @@ GstFlowReturn gst_matroska_read_common_parse_skip (GstMatroskaReadCommon *
common, GstEbmlRead * ebml, const gchar * parent_name, guint id); common, GstEbmlRead * ebml, const gchar * parent_name, guint id);
gint gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common, gint gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common,
guint track_num); guint track_num);
GstFlowReturn gst_matroska_read_common_read_track_encoding (
GstMatroskaReadCommon * common, GstEbmlRead * ebml,
GstMatroskaTrackContext * context);
G_END_DECLS G_END_DECLS