Compare commits
9 Commits
1050492058
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f934fced64 | ||
|
|
524f5dfc3f | ||
|
|
a11b16cc83 | ||
|
|
4c8df679c5 | ||
|
|
5d147cc5c8 | ||
|
|
7839206c7f | ||
|
|
e4f5f44f85 | ||
|
|
17193163d8 | ||
|
|
61c1157d81 |
123
pinesrcbin.c
123
pinesrcbin.c
@@ -36,6 +36,10 @@ enum
|
||||
PROP_CAPS,
|
||||
PROP_SYNC,
|
||||
PROP_NUM_BUFFERS,
|
||||
PROP_TEST_PATTERN,
|
||||
PROP_HUE,
|
||||
PROP_DEVICE,
|
||||
PROP_MODE
|
||||
};
|
||||
|
||||
|
||||
@@ -96,6 +100,7 @@ gst_pinesrcbin_create_fake_element (GstPineSrcBin * self)
|
||||
static gboolean
|
||||
gst_pinesrcbin_attach_ghost_pad (GstPineSrcBin * self)
|
||||
{
|
||||
g_print("gst_pinesrcbin_attach_ghost_pad()\n");
|
||||
GstPad *target = gst_element_get_static_pad (self->filter, self->type_klass_lc);
|
||||
gboolean res = gst_ghost_pad_set_target (GST_GHOST_PAD (self->pad), target);
|
||||
gst_object_unref (target);
|
||||
@@ -105,18 +110,25 @@ gst_pinesrcbin_attach_ghost_pad (GstPineSrcBin * self)
|
||||
static void
|
||||
gst_pinesrcbin_reset (GstPineSrcBin * self)
|
||||
{
|
||||
g_print("gst_pinesrcbin_reset()\n");
|
||||
gst_pinesrcbin_clear_kid (self);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "gst_pinesrcbin_reset()");
|
||||
/* placeholder element */
|
||||
// self->kid = gst_pinesrcbin_create_fake_element (self);
|
||||
// gst_element_set_state (self->kid, GST_STATE_NULL);
|
||||
// gst_element_set_state (self->filter, GST_STATE_NULL);
|
||||
self->kid = gst_pinesrcbin_create_fake_element (self);
|
||||
self->filter = gst_element_factory_make ("capsfilter", NULL);
|
||||
g_object_set (self->filter, "sync", self->sync, NULL);
|
||||
if (g_object_class_find_property (G_OBJECT_GET_CLASS(self->filter), "sync"))
|
||||
g_object_set (self->filter, "sync", self->sync, NULL);
|
||||
g_object_set (self->filter, "caps", self->filter_caps, NULL);
|
||||
gst_bin_add_many (GST_BIN (self), self->kid, self->filter, NULL);
|
||||
gst_element_link(self->kid, self->filter);
|
||||
|
||||
gst_pinesrcbin_attach_ghost_pad (self);
|
||||
gst_pinesrcbin_free_device(self);
|
||||
GST_DEBUG_OBJECT (self, "gst_pinesrcbin_reset() done");
|
||||
}
|
||||
|
||||
static GstStaticCaps raw_video_caps = GST_STATIC_CAPS ("video/x-raw");
|
||||
@@ -127,11 +139,15 @@ gst_pinesrcbin_constructed (GObject * object)
|
||||
const char *format;
|
||||
struct v4l2_fract interval;
|
||||
GstPineSrcBin *self = GST_PINESRCBIN (object);
|
||||
g_print("gst_pinesrcbin_constructed()\n");
|
||||
if (G_OBJECT_CLASS (parent_class)->constructed)
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
GST_DEBUG_OBJECT (self, "gst_pinesrcbin_constructed: start");
|
||||
self->type_klass = (self->flag == GST_ELEMENT_FLAG_SINK) ? "Sink" : "Source";
|
||||
self->filter_caps = gst_static_caps_get (&raw_video_caps);
|
||||
gst_pinesrcbin_get_gst_caps_data("rear", &width, &height, &format, &interval);
|
||||
gst_pinesrcbin_get_gst_caps_data(self->device, &width, &height, &format, &interval);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "gst_pinesrcbin_constructed: got caps for %s %d %d", self->device, width, height);
|
||||
self->filter_caps = gst_caps_new_simple ("video/x-raw",
|
||||
"format", G_TYPE_STRING, format,
|
||||
/* we "flip" interval to get frame rate */
|
||||
@@ -149,13 +165,16 @@ gst_pinesrcbin_constructed (GObject * object)
|
||||
GST_OBJECT_FLAG_SET (self, self->flag);
|
||||
gst_bin_set_suppressed_flags (GST_BIN (self),
|
||||
GST_ELEMENT_FLAG_SOURCE | GST_ELEMENT_FLAG_SINK);
|
||||
GST_DEBUG_OBJECT (self, "gst_pinesrcbin_constructed: done");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pinesrcbin_dispose (GObject * object)
|
||||
{
|
||||
GstPineSrcBin *self = GST_PINESRCBIN (object);
|
||||
g_print ("gst_pinesrcbin_dispose()\n");
|
||||
|
||||
GST_DEBUG_OBJECT (self, "gst_pinesrcbin_dispose: start");
|
||||
gst_pinesrcbin_clear_kid (self);
|
||||
|
||||
if (self->filter_caps)
|
||||
@@ -163,6 +182,7 @@ gst_pinesrcbin_dispose (GObject * object)
|
||||
self->filter_caps = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose ((GObject *) self);
|
||||
GST_DEBUG_OBJECT (self, "gst_pinesrcbin_dispose: done");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -170,6 +190,8 @@ gst_pinesrcbin_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstPineSrcBin *self = GST_PINESRCBIN (object);
|
||||
GstState next_state = GST_STATE(self);
|
||||
g_print ("gst_pinesrcbin_set_property()\n");
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CAPS:
|
||||
@@ -187,10 +209,47 @@ gst_pinesrcbin_set_property (GObject * object, guint prop_id,
|
||||
if (self->kid)
|
||||
g_object_set_property (G_OBJECT (self->kid), pspec->name, value);
|
||||
break;
|
||||
case PROP_TEST_PATTERN:
|
||||
self->test_pattern = g_value_get_int (value);
|
||||
g_print("setting prop test-pattern: %d\n", self->test_pattern);
|
||||
if (GST_STATE(self) == GST_STATE_PLAYING)
|
||||
set_camera_control(self->device, CONTROL_TEST_PATTERN, self->test_pattern);
|
||||
break;
|
||||
case PROP_HUE:
|
||||
self->hue = g_value_get_int (value);
|
||||
g_print("setting prop hue: %d\n", self->hue);
|
||||
if (GST_STATE(self) == GST_STATE_PLAYING)
|
||||
set_camera_control(self->device, CONTROL_HUE, self->hue);
|
||||
break;
|
||||
case PROP_MODE:
|
||||
{
|
||||
if (GST_STATE(self) > GST_STATE_NULL)
|
||||
gst_element_set_state (self, GST_STATE_NULL);
|
||||
self->mode = g_value_get_int (value);
|
||||
g_print("setting prop mode: %d\n", self->mode);
|
||||
if (GST_STATE(self) > GST_STATE_NULL)
|
||||
gst_element_set_state (self, next_state);
|
||||
}
|
||||
break;
|
||||
case PROP_DEVICE:
|
||||
{
|
||||
if (GST_STATE(self) > GST_STATE_NULL)
|
||||
gst_element_set_state (self, GST_STATE_NULL);
|
||||
const char * devname = g_value_get_string (value);
|
||||
g_print("!!!setting prop device: %s\n", devname);
|
||||
if (devname && strlen(devname) > 0) {
|
||||
if (self->device)
|
||||
g_free(self->device);
|
||||
self->device = g_strdup(devname);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
if (GST_STATE(self) != next_state)
|
||||
gst_element_set_state (self, next_state);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -198,6 +257,7 @@ gst_pinesrcbin_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstPineSrcBin *self = GST_PINESRCBIN (object);
|
||||
g_print ("gst_pinesrcbin_get_property()\n");
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CAPS:
|
||||
@@ -209,6 +269,21 @@ gst_pinesrcbin_get_property (GObject * object, guint prop_id,
|
||||
case PROP_NUM_BUFFERS:
|
||||
g_value_set_int (value, self->num_buffers);
|
||||
break;
|
||||
case PROP_TEST_PATTERN:
|
||||
g_value_set_int (value, self->test_pattern);
|
||||
break;
|
||||
case PROP_HUE:
|
||||
g_print("getting prop hue: %d\n", self->hue);
|
||||
g_value_set_int (value, self->hue);
|
||||
break;
|
||||
case PROP_MODE:
|
||||
g_print("getting prop mode: %d\n", self->mode);
|
||||
g_value_set_int (value, self->mode);
|
||||
break;
|
||||
case PROP_DEVICE:
|
||||
g_print("getting prop device: %s\n", self->device);
|
||||
g_value_set_string (value, self->device);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -221,6 +296,10 @@ gst_pinesrcbin_detect (GstPineSrcBin * self)
|
||||
GstElement *kid, *filter;
|
||||
GstPad *target;
|
||||
GstPineSrcBinClass *klass = GST_PINESRCBIN_GET_CLASS (self);
|
||||
g_print ("gst_pinesrcbin_detect start\n");
|
||||
GST_DEBUG_OBJECT (self, "gst_pinesrcbin_detect: setting up element");
|
||||
|
||||
gst_pinesrcbin_configure_device(self, self->device);
|
||||
|
||||
gst_pinesrcbin_clear_kid (self);
|
||||
|
||||
@@ -241,7 +320,7 @@ gst_pinesrcbin_detect (GstPineSrcBin * self)
|
||||
gst_pad_use_fixed_caps (target);
|
||||
gst_pad_set_caps(target, self->filter_caps);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Setting default properties for v4l2src element");
|
||||
GST_DEBUG_OBJECT (self, "Setting properties defaults for v4l2src element");
|
||||
self->has_sync =
|
||||
g_object_class_find_property (G_OBJECT_GET_CLASS (kid), "sync") != NULL;
|
||||
if (self->has_sync)
|
||||
@@ -302,7 +381,9 @@ gst_pinesrcbin_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||
GstPineSrcBin *sink = GST_PINESRCBIN (element);
|
||||
g_print ("gst_pinesrcbin_change_state()\n");
|
||||
|
||||
GST_DEBUG_OBJECT (sink, "gst_pinesrcbin_change_state: state change");
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
if (!gst_pinesrcbin_detect (sink))
|
||||
@@ -333,6 +414,7 @@ gst_pinesrcbin_class_init (GstPineSrcBinClass * klass)
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *eklass;
|
||||
|
||||
g_print ("Class init\n");
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
eklass = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
@@ -349,7 +431,23 @@ gst_pinesrcbin_class_init (GstPineSrcBinClass * klass)
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
|
||||
g_param_spec_int ("num-buffers", "Num-buffers",
|
||||
"Number of buffers until EOS, -1 = unlimited", -1, INT_MAX, 1000,
|
||||
"Number of buffers until EOS, -1 = unlimited", -1, INT_MAX, -1,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_TEST_PATTERN,
|
||||
g_param_spec_int ("test-pattern", "Test-pattern",
|
||||
"Test pattern for camera to display", 0, INT_MAX, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_HUE,
|
||||
g_param_spec_int ("hue", "Hue",
|
||||
"Set image hue", 0, 65535, 128,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_DEVICE,
|
||||
g_param_spec_string ("device", "Device",
|
||||
"Device", "",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_MODE,
|
||||
g_param_spec_int ("mode", "Mode",
|
||||
"Set image hue", 1, 2, 1,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
@@ -358,10 +456,18 @@ GST_DEBUG_CATEGORY (pinesrcbin_debug);
|
||||
static void
|
||||
gst_pinesrcbin_init (GstPineSrcBin * self)
|
||||
{
|
||||
GST_DEBUG_OBJECT (self, "Starting device configuration");
|
||||
gst_pinesrcbin_configure_device(self, "rear");
|
||||
GST_DEBUG_CATEGORY_INIT (pinesrcbin_debug, "pinesrcbin", 0,
|
||||
"pinephone v4lsrc camera wrapper");
|
||||
g_print ("Plugin init\n");
|
||||
self->sync = DEFAULT_SYNC;
|
||||
self->num_buffers = 1000;
|
||||
self->num_buffers = -1;
|
||||
self->test_pattern = 0;
|
||||
self->hue = 128;
|
||||
self->mode = 1;
|
||||
self->device = g_strdup("primary");
|
||||
self->media_if = NULL;
|
||||
g_print("initial hue: %d\n", self->hue);
|
||||
GST_DEBUG_OBJECT (self, "Starting device configuration");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -369,8 +475,9 @@ plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
GST_DEBUG_CATEGORY_INIT (pinesrcbin_debug, "pinesrcbin", 0,
|
||||
"pinephone v4lsrc camera wrapper");
|
||||
return gst_element_register (plugin, "pinesrcbin",
|
||||
gst_element_register (plugin, "pinesrcbin",
|
||||
GST_RANK_NONE, GST_TYPE_PINESRCBIN);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR,
|
||||
|
||||
@@ -31,6 +31,10 @@ typedef struct _GstPineSrcBin
|
||||
gboolean autofocus;
|
||||
/* Buffers till EOS */
|
||||
int num_buffers;
|
||||
int test_pattern;
|
||||
int hue;
|
||||
int mode;
|
||||
const gchar *device;
|
||||
} GstPineSrcBin;
|
||||
|
||||
#endif
|
||||
|
||||
3
rpm/pinesrcbin.conf
Normal file
3
rpm/pinesrcbin.conf
Normal file
@@ -0,0 +1,3 @@
|
||||
QT_GSTREAMER_CAMERABIN_SRC="wrappercamerabinsrc"
|
||||
QT_GSTREAMER_CAMERABIN_VIDEOSRC="pinesrcbin"
|
||||
# QT_GSTREAMER_CAMERABIN_FLAGS=15
|
||||
45
rpm/pinesrcbin.spec
Normal file
45
rpm/pinesrcbin.spec
Normal file
@@ -0,0 +1,45 @@
|
||||
%define majorminor 1.0
|
||||
|
||||
Name: pinesrcbin
|
||||
Version: 0.0.1
|
||||
Release: 0
|
||||
Summary: GStreamer plug-in
|
||||
Group: Applications/Multimedia
|
||||
License: LGPLv2+
|
||||
URL: https://git.omprussia.ru/s.lapin/pinesrcbin
|
||||
Source0: %{name}-%{version}.tar.bz2
|
||||
Source1: pinesrcbin.conf
|
||||
|
||||
%define sonamever %(echo %{version} | cut -d '+' -f 1)
|
||||
|
||||
BuildRequires: pkgconfig(gstreamer-1.0) >= 1.16.1
|
||||
BuildRequires: pkgconfig(gstreamer-base-1.0) >= 1.16.1
|
||||
BuildRequires: pkgconfig(gstreamer-plugins-bad-1.0) >= 1.16.1
|
||||
|
||||
BuildRequires: meson
|
||||
|
||||
%description
|
||||
TBD
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%meson
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
mkdir -p %{builroot}%{_libdir}
|
||||
mkdir -p %{buildroot}/var/lib/environment/compositor/
|
||||
mkdir -p %{buildroot}/var/lib/environment/nemo
|
||||
|
||||
%meson_install
|
||||
|
||||
cp %{SOURCE1} %{buildroot}%{_sharedstatedir}/environment/compositor/pinesrcbin.conf
|
||||
cp %{SOURCE1} %{buildroot}%{_sharedstatedir}/environment/nemo/70-pinesrcbin.conf
|
||||
|
||||
%files
|
||||
%{_libdir}/gstreamer-1.0/libgstpinesrcbin.so
|
||||
%{_sharedstatedir}/environment/compositor/pinesrcbin.conf
|
||||
%{_sharedstatedir}/environment/nemo/70-pinesrcbin.conf
|
||||
|
||||
107
utility.c
107
utility.c
@@ -1,3 +1,7 @@
|
||||
/* insert copyright here *
|
||||
* THE manual: https://www.kernel.org/doc/html/v5.7/media/uapi/mediactl/media-ioc-g-topology.html
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -82,13 +86,14 @@ struct camera_data {
|
||||
int subdev_fd;
|
||||
const struct media_v2_entity *entity;
|
||||
const struct media_v2_interface *interface;
|
||||
const struct media_v2_pad *pad;
|
||||
int gain_ctrl;
|
||||
int gain_max;
|
||||
char devnode_path[261];
|
||||
};
|
||||
struct camera_config configurations[] = {
|
||||
{"front", "gc2145", 320, 240, MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_SBGGR8_1X8, {1, 15}},
|
||||
{"rear", "ov5640", 320, 240, MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_SBGGR8_1X8, {1, 15}},
|
||||
{"secondary", "gc2145", 1280, 720, MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_SBGGR8_1X8, {1, 15}},
|
||||
{"primary", "ov5640", 1280, 720, MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_SBGGR8_1X8, {1, 30}},
|
||||
};
|
||||
struct camera_data cam_store[] = {
|
||||
{},
|
||||
@@ -156,10 +161,8 @@ gst_pinesrcbin_get_entity_interface(struct device_data *dev, uint32_t id)
|
||||
{
|
||||
const struct media_v2_link *link =
|
||||
gst_pinesrcbin_get_link_from_entity(dev, id);
|
||||
g_print("entity id: %d\n", id);
|
||||
if (!link)
|
||||
return NULL;
|
||||
g_print("link id: %d %d\n", link->sink_id, link->source_id);
|
||||
return gst_pinesrcbin_get_interface_by_id(dev, link->source_id);
|
||||
}
|
||||
|
||||
@@ -181,9 +184,6 @@ gst_pinesrcbin_find_media_entity(struct device_data *dev,
|
||||
{
|
||||
int length = strlen(driver_name);
|
||||
int i;
|
||||
for (i = 0; i < dev->num_entities; i++)
|
||||
g_print("%s: entity: %s:%d:%s\n", dev->path, dev->entities[i].name,
|
||||
dev->entities[i].id, driver_name);
|
||||
for (i = 0; i < dev->num_entities; i++) {
|
||||
if (!strncmp(dev->entities[i].name, driver_name, length))
|
||||
return &dev->entities[i];
|
||||
@@ -201,7 +201,6 @@ static void disable_all_links(struct device_data *dev)
|
||||
continue;
|
||||
if (!(sink_pad->flags & MEDIA_PAD_FL_SINK))
|
||||
continue;
|
||||
g_print("sink pad: %d\n", sink_pad->id);
|
||||
for (j = 0; j < dev->num_entities; j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
@@ -209,55 +208,11 @@ static void disable_all_links(struct device_data *dev)
|
||||
gst_pinesrcbin_get_pad_from_entity (dev, dev->entities[j].id);
|
||||
if (!source_pad)
|
||||
continue;
|
||||
g_print("source pad: %d\n", source_pad->id);
|
||||
if (!(source_pad->flags & MEDIA_PAD_FL_SOURCE))
|
||||
continue;
|
||||
g_print("disabling link %d %d\n", source_pad->entity_id, sink_pad->entity_id);
|
||||
setup_link(dev, source_pad->id, sink_pad->id, FALSE);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
const struct media_v2_link *plink =
|
||||
gst_pinesrcbin_get_link_from_entity(dev,
|
||||
dev->entities[i].id);
|
||||
if (plink) {
|
||||
g_print("link %d %08x %08x: %08x\n", plink->id, plink->source_id, plink->sink_id, plink->flags);
|
||||
if (plink->flags & MEDIA_LNK_FL_ENABLED) {
|
||||
uint32_t link_type = plink->flags & MEDIA_LNK_FL_LINK_TYPE;
|
||||
if (link_type == MEDIA_LNK_FL_DATA_LINK) {
|
||||
g_print("data link %d\n", plink->id);
|
||||
setup_link(dev, plink->source_id, plink->sink_id, FALSE);
|
||||
} else if (link_type == MEDIA_LNK_FL_INTERFACE_LINK) {
|
||||
struct media_v2_interface *iface = st_pinesrcbin_get_interface_by_id(dev, plink->source_id);
|
||||
g_print("interface link %d entity: %d\n", plink->id, iface->);
|
||||
continue;
|
||||
}
|
||||
const struct media_v2_pad *source_pad, *sink_pad;
|
||||
g_print("link %d is active\n", plink->id);
|
||||
source_pad = gst_pinesrcbin_get_pad_from_entity(dev, plink->source_id);
|
||||
sink_pad = gst_pinesrcbin_get_pad_from_entity(dev, plink->sink_id);
|
||||
g_assert(source_pad);
|
||||
g_assert(sink_pad);
|
||||
setup_link(dev, source_pad->id, sink_pad->id, FALSE);
|
||||
#if 0
|
||||
struct media_link_desc link = {};
|
||||
link.flags = 0;
|
||||
link.source.entity = plink->source_id;
|
||||
link.source.index = 0;
|
||||
link.sink.entity = plink->sink_id;
|
||||
link.sink.index = 0;
|
||||
if (xioctl(dev->fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
|
||||
g_printerr("MEDIA_IOC_SETUP_LINK: %d %s", errno, strerror(errno));
|
||||
#endif
|
||||
#if 0
|
||||
/* TODO: maintain own links structure */
|
||||
else
|
||||
plink->flags = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct device_data *
|
||||
@@ -342,6 +297,7 @@ setup_gain(int fd, int *gain_ctrl, int *gain_max)
|
||||
*gain_max = ctrl.maximum;
|
||||
return;
|
||||
}
|
||||
camera_control(fd, *gain_ctrl, VIDIOC_S_EXT_CTRLS, gain_max);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -413,7 +369,7 @@ static int alloc_device(struct device_data *dev)
|
||||
rc = xioctl(dev->fd, MEDIA_IOC_G_TOPOLOGY, &dev->topology);
|
||||
if (rc < 0)
|
||||
{
|
||||
g_printerr("topology x1 error %d %d %s\n", rc,
|
||||
g_error("topology x1 error %d %d %s\n", rc,
|
||||
errno, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
@@ -435,12 +391,10 @@ static int alloc_device(struct device_data *dev)
|
||||
dev->topology.ptr_interfaces = (uint64_t)dev->interfaces;
|
||||
dev->topology.ptr_pads = (uint64_t)dev->pads;
|
||||
dev->topology.ptr_links = (uint64_t)dev->links;
|
||||
g_print("topology x2\n");
|
||||
rc = xioctl(dev->fd, MEDIA_IOC_G_TOPOLOGY, &dev->topology);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
g_print("device info\n");
|
||||
rc = xioctl(dev->fd, MEDIA_IOC_DEVICE_INFO, &dev->info);
|
||||
out:
|
||||
return rc;
|
||||
@@ -517,6 +471,24 @@ get_camera_data(const char *conf_name)
|
||||
return &cam_store[conf];
|
||||
}
|
||||
}
|
||||
void set_camera_control(const char * conf_name, int control, int value)
|
||||
{
|
||||
struct camera_data *cam_data = get_camera_data(conf_name);
|
||||
switch(control) {
|
||||
case CONTROL_HUE:
|
||||
g_print("configuring hue = %d\n", value);
|
||||
camera_control (cam_data->subdev_fd, V4L2_CID_HUE, VIDIOC_S_EXT_CTRLS, &value);
|
||||
break;
|
||||
case CONTROL_SATURATION:
|
||||
g_print("configuring saturation = %d\n", value);
|
||||
camera_control (cam_data->subdev_fd, V4L2_CID_SATURATION, VIDIOC_S_EXT_CTRLS, &value);
|
||||
break;
|
||||
case CONTROL_TEST_PATTERN:
|
||||
g_print("configuring test pattern = %d\n", value);
|
||||
camera_control (cam_data->subdev_fd, V4L2_CID_TEST_PATTERN, VIDIOC_S_EXT_CTRLS, &value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void gst_pinesrcbin_configure_device(GstPineSrcBin * self, const char *conf_name)
|
||||
{
|
||||
struct camera_config *conf;
|
||||
@@ -565,7 +537,7 @@ void gst_pinesrcbin_configure_device(GstPineSrcBin * self, const char *conf_name
|
||||
if (!self->v4l2entity)
|
||||
g_error ("can't find entity sun6i-csi\n");
|
||||
GST_DEBUG_OBJECT (self, "sink entity: %d %s\n", self->v4l2entity->id, self->v4l2entity->name);
|
||||
/* This is sink pad (for host controller) */
|
||||
/* This is sink pad (for media controller) */
|
||||
self->v4l2pad =
|
||||
gst_pinesrcbin_get_pad_from_entity (self->media_if, self->v4l2entity->id);
|
||||
GST_DEBUG_OBJECT (self, "sink pad: %d\n", self->v4l2pad->id);
|
||||
@@ -591,6 +563,8 @@ void gst_pinesrcbin_configure_device(GstPineSrcBin * self, const char *conf_name
|
||||
disable_all_links(self->media_if);
|
||||
cam_data->entity = gst_pinesrcbin_find_media_entity(self->media_if, conf->camera_name);
|
||||
GST_DEBUG_OBJECT (self, "camera: %s: source interface entity %d\n", conf->camera_name, cam_data->entity->id);
|
||||
cam_data->pad =
|
||||
gst_pinesrcbin_get_pad_from_entity (self->media_if, cam_data->entity->id);
|
||||
|
||||
cam_data->interface =
|
||||
gst_pinesrcbin_get_entity_interface (self->media_if,
|
||||
@@ -612,10 +586,31 @@ void gst_pinesrcbin_configure_device(GstPineSrcBin * self, const char *conf_name
|
||||
camera_control (cam_data->subdev_fd, V4L2_CID_FOCUS_AUTO, VIDIOC_S_EXT_CTRLS, &enable);
|
||||
}
|
||||
setup_gain (cam_data->subdev_fd, &cam_data->gain_ctrl, &cam_data->gain_max);
|
||||
/* self->test_pattern = 1; */
|
||||
camera_control (cam_data->subdev_fd, V4L2_CID_TEST_PATTERN, VIDIOC_S_EXT_CTRLS, &self->test_pattern);
|
||||
{
|
||||
int auto_gain = 1;
|
||||
camera_control (cam_data->subdev_fd, V4L2_CID_AUTOGAIN, VIDIOC_S_EXT_CTRLS, &auto_gain);
|
||||
}
|
||||
set_camera_control(conf_name, CONTROL_HUE, self->hue);
|
||||
/* now configuring camera modes */
|
||||
GST_DEBUG_OBJECT (self, "configuring camera modes\n");
|
||||
subdev_set_mode(cam_data->subdev_fd, conf->width,
|
||||
conf->height, conf->bus_code_video,
|
||||
conf->frame_interval);
|
||||
GST_DEBUG_OBJECT (self, "enabling link for %s\n", conf->camera_name);
|
||||
setup_link(self->media_if, cam_data->pad->id, self->v4l2pad->id, TRUE);
|
||||
}
|
||||
|
||||
|
||||
void gst_pinesrcbin_free_device(GstPineSrcBin * self)
|
||||
{
|
||||
struct camera_data *cam_data = get_camera_data(self->device);
|
||||
if (!self->media_if)
|
||||
return;
|
||||
close(cam_data->subdev_fd);
|
||||
close(self->fd);
|
||||
disable_all_links(self->media_if);
|
||||
close(self->media_if);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,18 @@ struct device_data
|
||||
struct media_v2_link *links;
|
||||
size_t num_links;
|
||||
};
|
||||
|
||||
enum {
|
||||
CONTROL_HUE,
|
||||
CONTROL_SATURATION,
|
||||
CONTROL_TEST_PATTERN,
|
||||
};
|
||||
|
||||
void gst_pinesrcbin_configure_device(GstPineSrcBin * self, const char *conf_name);
|
||||
void gst_pinesrcbin_free_device(GstPineSrcBin * self);
|
||||
void gst_pinesrcbin_get_gst_caps_data(const char * conf_name,
|
||||
int *width, int * height, const char **format,
|
||||
struct v4l2_fract *interval);
|
||||
void set_camera_control(const char * conf_name, int control, int value);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user