aboutsummaryrefslogtreecommitdiffstats
path: root/utils/common/media-info.cpp
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2018-02-04 18:28:10 +0100
committerHans Verkuil <hans.verkuil@cisco.com>2018-02-04 18:28:10 +0100
commit0561fdb4a972c4a169c121de4e866684d562c9ad (patch)
treef0fbf6bfa24e4154b5df9fedf3cc05a762bd717d /utils/common/media-info.cpp
parent0b0cb3188d953c3a8f706ebf49da83b98be5dce6 (diff)
v4l2-compliance: add -M option to test all /dev/mediaX interfaces
Add a new -M option to test all interfaces defines in the media controller. Also moved v4l2_type back from v4l2-info to media-info since the media device defines more than just v4l2 interfaces. It makes more sense to put this in media-info. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Diffstat (limited to 'utils/common/media-info.cpp')
-rw-r--r--utils/common/media-info.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/utils/common/media-info.cpp b/utils/common/media-info.cpp
index 0588b346..eef743e1 100644
--- a/utils/common/media-info.cpp
+++ b/utils/common/media-info.cpp
@@ -33,6 +33,7 @@
#include <linux/media.h>
#include <fstream>
+#include <media-info.h>
static std::string num2s(unsigned num, bool is_hex = true)
{
@@ -45,6 +46,94 @@ static std::string num2s(unsigned num, bool is_hex = true)
return buf;
}
+static struct {
+ const char *devname;
+ enum media_type type;
+} media_types[] = {
+ { "video", MEDIA_TYPE_VIDEO },
+ { "vbi", MEDIA_TYPE_VBI },
+ { "radio", MEDIA_TYPE_RADIO },
+ { "swradio", MEDIA_TYPE_SDR },
+ { "v4l-subdev", MEDIA_TYPE_SUBDEV },
+ { "v4l-touch", MEDIA_TYPE_TOUCH },
+ { "media", MEDIA_TYPE_MEDIA },
+ { "frontend", MEDIA_TYPE_DVB_FRONTEND },
+ { "demux", MEDIA_TYPE_DVB_DEMUX },
+ { "dvr", MEDIA_TYPE_DVB_DVR },
+ { "net", MEDIA_TYPE_DVB_NET },
+ { NULL, MEDIA_TYPE_UNKNOWN }
+};
+
+media_type media_detect_type(const char *device)
+{
+ struct stat sb;
+
+ if (stat(device, &sb) == -1)
+ return MEDIA_TYPE_CANT_STAT;
+
+ std::string uevent_path("/sys/dev/char/");
+
+ uevent_path += num2s(major(sb.st_rdev), false) + ":" +
+ num2s(minor(sb.st_rdev), false) + "/uevent";
+
+ std::ifstream uevent_file(uevent_path);
+ if (uevent_file.fail())
+ return MEDIA_TYPE_UNKNOWN;
+
+ std::string line;
+
+ while (std::getline(uevent_file, line)) {
+ if (line.compare(0, 8, "DEVNAME="))
+ continue;
+
+ line.erase(0, 8);
+ if (!line.compare(0, 11, "dvb/adapter")) {
+ line.erase(0, 11);
+ unsigned len = 0;
+ while (line[len] && line[len] != '/')
+ len++;
+ line.erase(0, len + 1);
+ }
+ for (size_t i = 0; media_types[i].devname; i++) {
+ const char *devname = media_types[i].devname;
+ size_t len = strlen(devname);
+
+ if (!line.compare(0, len, devname) && isdigit(line[0+len])) {
+ uevent_file.close();
+ return media_types[i].type;
+ }
+ }
+ }
+
+ uevent_file.close();
+ return MEDIA_TYPE_UNKNOWN;
+}
+
+std::string media_get_device(__u32 major, __u32 minor)
+{
+ char fmt[32];
+ std::string uevent_path("/sys/dev/char/");
+
+ sprintf(fmt, "%d:%d", major, minor);
+ uevent_path += std::string(fmt) + "/uevent";
+
+ std::ifstream uevent_file(uevent_path);
+ if (uevent_file.fail())
+ return "";
+
+ std::string line;
+
+ while (std::getline(uevent_file, line)) {
+ if (line.compare(0, 8, "DEVNAME="))
+ continue;
+ uevent_file.close();
+ return std::string("/dev/") + &line[8];
+ }
+
+ uevent_file.close();
+ return "";
+}
+
typedef struct {
unsigned flag;
const char *str;

Privacy Policy