discoverer: Extract video information from caps manually without GstVideoInfo

The caps might not be fixated (which is required by GstVideoInfo) and we
would assert otherwise. However the caps often contain useful
information in the already-fixed parts that we can use here.
This commit is contained in:
Sebastian Dröge 2016-11-28 10:12:49 +02:00
parent bd74b102fa
commit 4efc15dffb

View file

@ -47,6 +47,8 @@
#include <gst/video/video.h> #include <gst/video/video.h>
#include <gst/audio/audio.h> #include <gst/audio/audio.h>
#include <string.h>
#include "pbutils.h" #include "pbutils.h"
#include "pbutils-private.h" #include "pbutils-private.h"
@ -806,7 +808,7 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
GstStructure *caps_st; GstStructure *caps_st;
GstTagList *tags_st; GstTagList *tags_st;
const gchar *name; const gchar *name;
int tmp; gint tmp, tmp2;
guint utmp; guint utmp;
if (!st || !gst_structure_id_has_field (st, _CAPS_QUARK)) { if (!st || !gst_structure_id_has_field (st, _CAPS_QUARK)) {
@ -840,7 +842,8 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
format = gst_audio_format_from_string (format_str); format = gst_audio_format_from_string (format_str);
finfo = gst_audio_format_get_info (format); finfo = gst_audio_format_get_info (format);
info->depth = GST_AUDIO_FORMAT_INFO_DEPTH (finfo); if (finfo)
info->depth = GST_AUDIO_FORMAT_INFO_DEPTH (finfo);
} }
if (gst_structure_id_has_field (st, _TAGS_QUARK)) { if (gst_structure_id_has_field (st, _TAGS_QUARK)) {
@ -872,27 +875,51 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
} else if (g_str_has_prefix (name, "video/") || } else if (g_str_has_prefix (name, "video/") ||
g_str_has_prefix (name, "image/")) { g_str_has_prefix (name, "image/")) {
GstDiscovererVideoInfo *info; GstDiscovererVideoInfo *info;
GstVideoInfo vinfo; const gchar *caps_str;
info = (GstDiscovererVideoInfo *) make_info (parent, info = (GstDiscovererVideoInfo *) make_info (parent,
GST_TYPE_DISCOVERER_VIDEO_INFO, caps); GST_TYPE_DISCOVERER_VIDEO_INFO, caps);
if (gst_video_info_from_caps (&vinfo, caps)) { if (gst_structure_get_int (caps_st, "width", &tmp))
info->width = (guint) vinfo.width; info->width = (guint) tmp;
info->height = (guint) vinfo.height; if (gst_structure_get_int (caps_st, "height", &tmp))
info->height = (guint) tmp;
info->depth = vinfo.finfo->bits * vinfo.finfo->n_components; if (gst_structure_get_fraction (caps_st, "framerate", &tmp, &tmp2)) {
info->framerate_num = (guint) tmp;
info->par_num = vinfo.par_n; info->framerate_denom = (guint) tmp2;
info->par_denom = vinfo.par_d; } else {
info->framerate_num = 0;
info->framerate_num = vinfo.fps_n; info->framerate_denom = 1;
info->framerate_denom = vinfo.fps_d;
info->interlaced =
vinfo.interlace_mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
} }
if (gst_structure_get_fraction (caps_st, "pixel-aspect-ratio", &tmp, &tmp2)) {
info->par_num = (guint) tmp;
info->par_denom = (guint) tmp2;
} else {
info->par_num = 1;
info->par_denom = 1;
}
/* FIXME: we only want to extract depth if raw video is what's in the
* container (i.e. not if there is a decoder involved) */
caps_str = gst_structure_get_string (caps_st, "format");
if (caps_str != NULL) {
const GstVideoFormatInfo *finfo;
GstVideoFormat format;
format = gst_video_format_from_string (caps_str);
finfo = gst_video_format_get_info (format);
if (finfo)
info->depth = finfo->bits * finfo->n_components;
}
caps_str = gst_structure_get_string (caps_st, "interlace-mode");
if (!caps_str || strcmp (caps_str, "progressive") == 0)
info->interlaced = FALSE;
else
info->interlaced = TRUE;
if (gst_structure_id_has_field (st, _TAGS_QUARK)) { if (gst_structure_id_has_field (st, _TAGS_QUARK)) {
gst_structure_id_get (st, _TAGS_QUARK, GST_TYPE_TAG_LIST, &tags_st, NULL); gst_structure_id_get (st, _TAGS_QUARK, GST_TYPE_TAG_LIST, &tags_st, NULL);
if (gst_tag_list_get_uint (tags_st, GST_TAG_BITRATE, &utmp) || if (gst_tag_list_get_uint (tags_st, GST_TAG_BITRATE, &utmp) ||