@@ -82,7 +82,7 @@ public:
bool has_rw() const { return v4l_has_rw(this); }
bool has_streaming() const { return v4l_has_streaming(this); }
bool has_ext_pix_format() const { return v4l_has_ext_pix_format(this); }
- bool has_streams_support() const { return subdev_supports_streams; }
+ bool has_streams() const { return have_streams; }
int querycap(v4l2_capability &cap, bool force = false)
{
@@ -9,6 +9,7 @@
#ifndef _V4L_HELPERS_H_
#define _V4L_HELPERS_H_
+#include <linux/v4l2-subdev.h>
#include <linux/videodev2.h>
#include <string.h>
#include <stdlib.h>
@@ -39,7 +40,7 @@ struct v4l_fd {
bool have_selection;
bool is_subdev;
bool is_media;
- bool subdev_supports_streams;
+ bool have_streams;
int (*open)(struct v4l_fd *f, const char *file, int oflag, ...);
int (*close)(struct v4l_fd *f);
@@ -543,7 +544,7 @@ static inline int v4l_subdev_s_fd(struct v4l_fd *f, int fd, const char *devname)
ret = ioctl(f->fd, VIDIOC_SUBDEV_S_CLIENT_CAP, &clientcap);
client_streams = !ret && (clientcap.capabilities & V4L2_SUBDEV_CLIENT_CAP_STREAMS);
- f->subdev_supports_streams = subdev_streams && client_streams;
+ f->have_streams = subdev_streams && client_streams;
return f->fd;
}
@@ -909,6 +909,8 @@ struct media_pad *media_parse_pad_stream(struct media_device *media,
*stream = 0;
}
+ for (; isspace(*p); ++p);
+
if (endp)
*endp = (char*)p;
@@ -231,33 +231,6 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
return 0;
}
-int v4l2_subdev_set_routing(struct media_entity *entity,
- struct v4l2_subdev_route *routes,
- unsigned int num_routes)
-{
- struct v4l2_subdev_routing routing = {
- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
- .routes = (uintptr_t)routes,
- .num_routes = num_routes,
- };
- int ret;
-
- ret = v4l2_subdev_open(entity);
- if (ret < 0)
- return ret;
-
- if (!entity->supports_streams) {
- media_dbg(entity->media, "Streams API not supported\n");
- return -ENOTSUP;
- }
-
- ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_ROUTING, &routing);
- if (ret == -1)
- return -errno;
-
- return 0;
-}
-
int v4l2_subdev_get_routing(struct media_entity *entity,
struct v4l2_subdev_route **routes,
unsigned int *num_routes)
@@ -272,8 +245,10 @@ int v4l2_subdev_get_routing(struct media_entity *entity,
if (ret < 0)
return ret;
- if (!entity->supports_streams)
+ if (!entity->supports_streams) {
+ media_dbg(entity->media, "Streams API not supported\n");
return -ENOTSUP;
+ }
ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_ROUTING, &routing);
if (ret == -1 && errno != ENOSPC)
@@ -302,6 +277,33 @@ int v4l2_subdev_get_routing(struct media_entity *entity,
return 0;
}
+int v4l2_subdev_set_routing(struct media_entity *entity,
+ struct v4l2_subdev_route *routes,
+ unsigned int num_routes)
+{
+ struct v4l2_subdev_routing routing = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .routes = (uintptr_t)routes,
+ .num_routes = num_routes,
+ };
+ int ret;
+
+ ret = v4l2_subdev_open(entity);
+ if (ret < 0)
+ return ret;
+
+ if (!entity->supports_streams) {
+ media_dbg(entity->media, "Streams API not supported\n");
+ return -ENOTSUP;
+ }
+
+ ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_ROUTING, &routing);
+ if (ret == -1)
+ return -errno;
+
+ return 0;
+}
+
int v4l2_subdev_get_dv_timings_caps(struct media_entity *entity,
struct v4l2_dv_timings_cap *caps)
{
@@ -496,6 +498,8 @@ static int v4l2_subdev_parse_setup_route(struct media_device *media,
}
end++;
+ for (; isspace(*end); ++end);
+
*endp = end;
return 0;
@@ -506,9 +510,9 @@ int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p)
struct media_entity *entity;
struct v4l2_subdev_route *routes;
unsigned int num_routes;
+ unsigned int i;
char *end;
int ret;
- int i;
entity = media_parse_entity(media, p, &end);
if (!entity)
@@ -558,7 +562,7 @@ int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p)
struct v4l2_subdev_route *r = &routes[i];
media_dbg(entity->media,
- "Setting up route %s : %u/%u -> %u/%u, flags 0x%8.8x\n",
+ "Setting up route %s : %u/%u -> %u/%u [0x%08x]\n",
entity->info.name,
r->sink_pad, r->sink_stream,
r->source_pad, r->source_stream,
@@ -82,16 +82,16 @@ static void v4l2_subdev_print_routes(struct media_entity *entity,
{
unsigned int i;
- for (i = 0; i < num_routes; i++) {
- const struct v4l2_subdev_route *r = &routes[i];
+ if (num_routes)
+ printf("\troutes:\n");
- if (i == 0)
- printf("\troutes:\n");
+ for (i = 0; i < num_routes; i++) {
+ const struct v4l2_subdev_route *route = &routes[i];
printf("\t\t%u/%u -> %u/%u [%s]\n",
- r->sink_pad, r->sink_stream,
- r->source_pad, r->source_stream,
- r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE ? "ACTIVE" : "INACTIVE");
+ route->sink_pad, route->sink_stream,
+ route->source_pad, route->source_stream,
+ route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE ? "ACTIVE" : "INACTIVE");
}
}
@@ -480,54 +480,49 @@ static void media_print_pad_text(struct media_entity *entity,
struct v4l2_subdev_route *routes,
unsigned int num_routes)
{
+ uint64_t printed_streams_mask = 0;
unsigned int i;
- uint64_t printed_streams_mask;
if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV)
return;
if (!routes) {
- v4l2_subdev_print_format(entity, pad->index, 0, V4L2_SUBDEV_FORMAT_ACTIVE);
- v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
-
- if (pad->flags & MEDIA_PAD_FL_SOURCE)
- v4l2_subdev_print_subdev_dv(entity);
+ v4l2_subdev_print_format(entity, pad->index, 0,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ } else {
+ for (i = 0; i < num_routes; ++i) {
+ const struct v4l2_subdev_route *route = &routes[i];
+ unsigned int stream;
- return;
- }
+ if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
+ continue;
- printed_streams_mask = 0;
+ if (pad->flags & MEDIA_PAD_FL_SINK) {
+ if (route->sink_pad != pad->index)
+ continue;
- for (i = 0; i < num_routes; ++i) {
- const struct v4l2_subdev_route *r = &routes[i];
- unsigned int stream;
+ stream = route->sink_stream;
+ } else {
+ if (route->source_pad != pad->index)
+ continue;
- if (!(r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
- continue;
+ stream = route->source_stream;
+ }
- if (pad->flags & MEDIA_PAD_FL_SINK) {
- if (r->sink_pad != pad->index)
+ if (printed_streams_mask & (1 << stream))
continue;
- stream = r->sink_stream;
- } else {
- if (r->source_pad != pad->index)
- continue;
+ v4l2_subdev_print_format(entity, pad->index, stream,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
- stream = r->source_stream;
+ printed_streams_mask |= (1 << stream);
}
+ }
- if (printed_streams_mask & (1 << stream))
- continue;
-
- v4l2_subdev_print_format(entity, pad->index, stream, V4L2_SUBDEV_FORMAT_ACTIVE);
- v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
-
- if (pad->flags & MEDIA_PAD_FL_SOURCE)
- v4l2_subdev_print_subdev_dv(entity);
+ v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
- printed_streams_mask |= (1 << stream);
- }
+ if (pad->flags & MEDIA_PAD_FL_SOURCE)
+ v4l2_subdev_print_subdev_dv(entity);
}
static void media_print_topology_text_entity(struct media_device *media,
@@ -541,19 +536,24 @@ static void media_print_topology_text_entity(struct media_device *media,
const struct media_entity_desc *info = media_entity_get_info(entity);
const char *devname = media_entity_get_devname(entity);
unsigned int num_links = media_entity_get_links_count(entity);
- unsigned int j, k;
- unsigned int padding;
struct v4l2_subdev_route *routes = NULL;
unsigned int num_routes = 0;
+ unsigned int j, k;
+ unsigned int padding;
if (media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV)
v4l2_subdev_get_routing(entity, &routes, &num_routes);
padding = printf("- entity %u: ", info->id);
- printf("%s (%u pad%s, %u link%s, %u route%s)\n", info->name,
+ printf("%s (%u pad%s, %u link%s", info->name,
info->pads, info->pads > 1 ? "s" : "",
- num_links, num_links > 1 ? "s" : "",
- num_routes, num_routes > 1 ? "s" : "");
+ num_links, num_links > 1 ? "s" : "");
+
+ if (media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV)
+ printf(", %u route%s", num_routes, num_routes != 1 ? "s" : "");
+
+ printf(")\n");
+
printf("%*ctype %s subtype %s flags %x\n", padding, ' ',
media_entity_type_to_string(info->type),
media_entity_subtype_to_string(info->type),
@@ -52,6 +52,7 @@ void v4l2_subdev_close(struct media_entity *entity);
* @param entity - subdev-device media entity.
* @param format - format to be filled.
* @param pad - pad number.
+ * @param stream - stream number.
* @param which - identifier of the format to get.
*
* Retrieve the current format on the @a entity @a pad and store it in the
@@ -72,6 +73,7 @@ int v4l2_subdev_get_format(struct media_entity *entity,
* @param entity - subdev-device media entity.
* @param format - format.
* @param pad - pad number.
+ * @param stream - stream number.
* @param which - identifier of the format to set.
*
* Set the format on the @a entity @a pad to @a format. The driver is allowed to
@@ -94,6 +96,7 @@ int v4l2_subdev_set_format(struct media_entity *entity,
* @param entity - subdev-device media entity.
* @param r - rectangle to be filled.
* @param pad - pad number.
+ * @param stream - stream number.
* @param target - selection target
* @param which - identifier of the format to get.
*
@@ -116,6 +119,7 @@ int v4l2_subdev_get_selection(struct media_entity *entity,
* @param entity - subdev-device media entity.
* @param rect - crop rectangle.
* @param pad - pad number.
+ * @param stream - stream number.
* @param target - selection target
* @param which - identifier of the format to set.
*
@@ -222,6 +226,8 @@ int v4l2_subdev_set_dv_timings(struct media_entity *entity,
* @brief Retrieve the frame interval on a sub-device.
* @param entity - subdev-device media entity.
* @param interval - frame interval to be filled.
+ * @param pad - pad number.
+ * @param stream - stream number.
*
* Retrieve the current frame interval on subdev @a entity and store it in the
* @a interval structure.
@@ -239,6 +245,8 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
* @brief Set the frame interval on a sub-device.
* @param entity - subdev-device media entity.
* @param interval - frame interval.
+ * @param pad - pad number.
+ * @param stream - stream number.
*
* Set the frame interval on subdev @a entity to @a interval. The driver is
* allowed to modify the requested frame interval, in which case @a interval is
@@ -1255,8 +1255,8 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
which <= V4L2_SUBDEV_FORMAT_ACTIVE; which++) {
printf("\ttest %s VIDIOC_SUBDEV_G_ROUTING/VIDIOC_SUBDEV_S_ROUTING: %s\n",
- which ? "Active" : "Try",
- ok(testSubDevRouting(&node, which)));
+ which ? "Active" : "Try",
+ ok(testSubDevRouting(&node, which)));
}
printf("\n");
@@ -569,7 +569,7 @@ void subdev_set(cv4l_fd &_fd)
if (options[OptSetSubDevFormat] || options[OptTrySubDevFormat]) {
struct v4l2_subdev_format fmt;
- if (!_fd.has_streams_support() && set_fmt_stream) {
+ if (!_fd.has_streams() && set_fmt_stream) {
printf("Streams API not supported.\n");
return;
}
@@ -622,7 +622,7 @@ void subdev_set(cv4l_fd &_fd)
if (options[OptSetSubDevSelection] || options[OptTrySubDevSelection]) {
struct v4l2_subdev_selection sel;
- if (!_fd.has_streams_support() && vsel.stream) {
+ if (!_fd.has_streams() && vsel.stream) {
printf("Streams API not supported.\n");
return;
}
@@ -659,7 +659,7 @@ void subdev_set(cv4l_fd &_fd)
if (options[OptSetSubDevFPS]) {
struct v4l2_subdev_frame_interval fival;
- if (!_fd.has_streams_support() && set_fps_stream) {
+ if (!_fd.has_streams() && set_fps_stream) {
printf("Streams API not supported.\n");
return;
}
@@ -689,7 +689,7 @@ void subdev_set(cv4l_fd &_fd)
}
}
if (options[OptSetRouting]) {
- if (!_fd.has_streams_support()) {
+ if (!_fd.has_streams()) {
printf("Streams API not supported.\n");
return;
}
@@ -736,7 +736,7 @@ static void print_routes(const struct v4l2_subdev_routing *r)
};
for (i = 0; i < r->num_routes; i++) {
- printf("%d/%d -> %d/%d [",
+ printf("%u/%u -> %u/%u [",
routes[i].sink_pad, routes[i].sink_stream,
routes[i].source_pad, routes[i].source_stream);
print_flags(route_flags, ARRAY_SIZE(route_flags), routes[i].flags);
@@ -751,7 +751,7 @@ void subdev_get(cv4l_fd &_fd)
if (options[OptGetSubDevFormat]) {
struct v4l2_subdev_format fmt;
- if (!_fd.has_streams_support() && get_fmt_stream) {
+ if (!_fd.has_streams() && get_fmt_stream) {
printf("Streams API not supported.\n");
return;
}
@@ -761,7 +761,7 @@ void subdev_get(cv4l_fd &_fd)
fmt.pad = get_fmt_pad;
fmt.stream = get_fmt_stream;
- printf("ioctl: VIDIOC_SUBDEV_G_FMT (pad=%u, stream=%u)\n", fmt.pad, fmt.stream);
+ printf("ioctl: VIDIOC_SUBDEV_G_FMT (pad=%u,stream=%u)\n", fmt.pad, fmt.stream);
if (doioctl(fd, VIDIOC_SUBDEV_G_FMT, &fmt) == 0)
print_framefmt(fmt.format);
}
@@ -770,7 +770,7 @@ void subdev_get(cv4l_fd &_fd)
struct v4l2_subdev_selection sel;
unsigned idx = 0;
- if (!_fd.has_streams_support() && get_sel_stream) {
+ if (!_fd.has_streams() && get_sel_stream) {
printf("Streams API not supported.\n");
return;
}
@@ -797,7 +797,7 @@ void subdev_get(cv4l_fd &_fd)
if (options[OptGetSubDevFPS]) {
struct v4l2_subdev_frame_interval fival;
- if (!_fd.has_streams_support() && get_fps_stream) {
+ if (!_fd.has_streams() && get_fps_stream) {
printf("Streams API not supported.\n");
return;
}
@@ -819,7 +819,7 @@ void subdev_get(cv4l_fd &_fd)
}
if (options[OptGetRouting]) {
- if (!_fd.has_streams_support()) {
+ if (!_fd.has_streams()) {
printf("Streams API not supported.\n");
return;
}
@@ -907,7 +907,7 @@ void subdev_list(cv4l_fd &_fd)
int fd = _fd.g_fd();
if (options[OptListSubDevMBusCodes]) {
- if (!_fd.has_streams_support() && list_mbus_codes_stream) {
+ if (!_fd.has_streams() && list_mbus_codes_stream) {
printf("Streams API not supported.\n");
return;
}
@@ -917,7 +917,7 @@ void subdev_list(cv4l_fd &_fd)
print_mbus_codes(fd, list_mbus_codes_pad, list_mbus_codes_stream);
}
if (options[OptListSubDevFrameSizes]) {
- if (!_fd.has_streams_support() && frmsize.stream) {
+ if (!_fd.has_streams() && frmsize.stream) {
printf("Streams API not supported.\n");
return;
}
@@ -932,7 +932,7 @@ void subdev_list(cv4l_fd &_fd)
}
}
if (options[OptListSubDevFrameIntervals]) {
- if (!_fd.has_streams_support() && frmival.stream) {
+ if (!_fd.has_streams() && frmival.stream) {
printf("Streams API not supported.\n");
return;
}
@@ -64,8 +64,8 @@ static struct option long_options[] = {
{"get-fmt-video-out", no_argument, nullptr, OptGetVideoOutFormat},
{"set-fmt-video-out", required_argument, nullptr, OptSetVideoOutFormat},
{"try-fmt-video-out", required_argument, nullptr, OptTryVideoOutFormat},
- {"set-routing", required_argument, 0, OptSetRouting},
{"get-routing", no_argument, 0, OptGetRouting},
+ {"set-routing", required_argument, 0, OptSetRouting},
{"help", no_argument, nullptr, OptHelp},
{"help-tuner", no_argument, nullptr, OptHelpTuner},
{"help-io", no_argument, nullptr, OptHelpIO},
@@ -191,8 +191,8 @@ enum Option {
OptInfoEdid,
OptShowEdid,
OptFixEdidChecksums,
- OptSetRouting,
OptGetRouting,
+ OptSetRouting,
OptFreqSeek,
OptEncoderCmd,
OptTryEncoderCmd,