matroskaparse: better default caps when none set

Uses information gathered during EBML parsing to
forge a more suitable set of caps instead of blindly
assuming everything is video/x-matroska.

For consistency, stream type reset was added to
matroska-demux too.

https://bugzilla.gnome.org/show_bug.cgi?id=722311
This commit is contained in:
Reynaldo H. Verdejo Pinochet 2014-01-16 14:23:13 -03:00
parent 016e1562a6
commit cf0c780138
4 changed files with 45 additions and 4 deletions

View file

@ -407,6 +407,10 @@ gst_matroska_demux_reset (GstElement * element)
g_free (demux->common.muxing_app);
demux->common.muxing_app = NULL;
/* reset stream type */
demux->common.is_webm = FALSE;
demux->common.has_video = FALSE;
/* reset indexes */
if (demux->common.index) {
g_array_free (demux->common.index, TRUE);

View file

@ -135,6 +135,8 @@ static GstIndex *gst_matroska_parse_get_index (GstElement * element);
static void gst_matroska_parse_reset (GstElement * element);
static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
guint64 offset);
static GstCaps *gst_matroska_parse_forge_caps (gboolean is_webm,
gboolean has_video);
GType gst_matroska_parse_get_type (void);
#define parent_class gst_matroska_parse_parent_class
@ -306,6 +308,10 @@ gst_matroska_parse_reset (GstElement * element)
g_free (parse->common.muxing_app);
parse->common.muxing_app = NULL;
/* reset stream type */
parse->common.is_webm = FALSE;
parse->common.has_video = FALSE;
/* reset indexes */
if (parse->common.index) {
g_array_free (parse->common.index, TRUE);
@ -493,6 +499,7 @@ gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
switch (track_type) {
case GST_MATROSKA_TRACK_TYPE_VIDEO:
gst_matroska_track_init_video_context (&context);
parse->common.has_video = TRUE;
break;
case GST_MATROSKA_TRACK_TYPE_AUDIO:
gst_matroska_track_init_audio_context (&context);
@ -2526,10 +2533,10 @@ gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
GstBuffer *buf;
caps = gst_pad_get_current_caps (parse->common.sinkpad);
/* FIXME: could run typefinding over header and pick better default */
if (caps == NULL)
caps = gst_caps_new_empty_simple ("video/x-matroska");
else
if (caps == NULL) {
caps = gst_matroska_parse_forge_caps (parse->common.is_webm,
parse->common.has_video);
} else
caps = gst_caps_make_writable (caps);
s = gst_caps_get_structure (caps, 0);
@ -3037,6 +3044,31 @@ perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
return res;
}
/*
* Forge empty default caps when all we know is the stream's EBML
* type and whether it has video or not.
*
* FIXME: Do something with video/x-matroska-3d if possible
*/
static GstCaps *
gst_matroska_parse_forge_caps (gboolean is_webm, gboolean has_video)
{
GstCaps *caps;
if (is_webm) {
if (has_video)
caps = gst_caps_new_empty_simple ("video/webm");
else
caps = gst_caps_new_empty_simple ("audio/webm");
} else {
if (has_video)
caps = gst_caps_new_empty_simple ("video/x-matroska");
else
caps = gst_caps_new_empty_simple ("audio/x-matroska");
}
return caps;
}
static GstFlowReturn
gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{

View file

@ -1302,6 +1302,8 @@ exit:
if (version <= 2) {
if (doctype) {
GST_INFO_OBJECT (common, "Input is %s version %d", doctype, version);
if (!strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM))
common->is_webm = TRUE;
} else {
GST_WARNING_OBJECT (common, "Input is EBML without doctype, assuming "
"matroska (version %d)", version);

View file

@ -61,6 +61,9 @@ typedef struct _GstMatroskaReadCommon {
/* state */
GstMatroskaReadState state;
/* stream type */
gboolean is_webm;
gboolean has_video;
/* did we parse cues/tracks/segmentinfo already? */
gboolean index_parsed;