gjdwebserver-overlay/media-video/megapixels/files/8721f29e27f21111c439ee45f4ea76b56017d016.patch

707 lines
30 KiB
Diff
Raw Normal View History

2022-12-15 13:54:39 +01:00
From 8721f29e27f21111c439ee45f4ea76b56017d016 Mon Sep 17 00:00:00 2001
From: kgmt0 <kritphong@teknik.io>
Date: Fri, 17 Jun 2022 02:08:44 +0700
Subject: [PATCH] WIP: Support Pinephone Pro
Both cameras work now but the quality is very poor.
The config file format is extended to include 2 new options
"media-formats" and "media-crops" that can be used to set formats and
crops on a per-pad basis. These are needed to initialize Pinephone Pro's
media controller.
Tested with Linux 6.0.8-1 from Arch Linux ARM (linux-megi).
---
config/motorola,osprey.ini | 1 +
config/pine64,pinephone-pro.ini | 51 ++++++++
config/xiaomi,scorpio.ini | 1 +
meson.build | 1 +
src/camera.c | 10 +-
src/camera_config.c | 61 ++++++++++
src/camera_config.h | 23 ++++
src/device.c | 82 +++++++++++++
src/device.h | 9 ++
src/io_pipeline.c | 201 +++++++++++++++++++++++++-------
10 files changed, 392 insertions(+), 48 deletions(-)
create mode 100644 config/pine64,pinephone-pro.ini
diff --git a/config/motorola,osprey.ini b/config/motorola,osprey.ini
index ab8990d..5809a8e 100644
--- a/config/motorola,osprey.ini
+++ b/config/motorola,osprey.ini
@@ -15,3 +15,4 @@ preview-rate=30
preview-fmt=RGGB10P
rotate=270
media-links=msm_csiphy0:1->msm_csid0:0,msm_csid0:1->msm_ispif0:0,msm_ispif0:1->msm_vfe0_rdi0:0
+media-formats=msm_csiphy0:1:RGGB10P:4096:2304,msm_csid0:0:RGGB10P:4096:2304,msm_csid0:1:RGGB10P:4096:2304,msm_ispif0:0:RGGB10P:4096:2304,msm_ispif0:1:RGGB10P:4096:2304,msm_vfe0_rdi0:0:RGGB10P:4096:2304
diff --git a/config/pine64,pinephone-pro.ini b/config/pine64,pinephone-pro.ini
new file mode 100644
index 0000000..3416ca0
--- /dev/null
+++ b/config/pine64,pinephone-pro.ini
@@ -0,0 +1,51 @@
+[device]
+make=PINE64
+model=PinePhone
+
+[rear]
+driver=imx258 1-001a
+media-driver=rkisp1
+capture-width=1048
+capture-height=780
+capture-rate=30
+capture-fmt=RGGB8
+preview-width=1048
+preview-height=780
+preview-rate=30
+preview-fmt=RGGB8
+rotate=270
+mirrored=false
+blacklevel=3
+whitelevel=255
+focallength=2.35
+cropfactor=10.81
+fnumber=2.2
+iso-min=100
+iso-max=64000
+flash-path=/sys/class/leds/white:flash
+media-links=imx258 1-001a:0->rkisp1_csi:0,rkisp1_csi:1->rkisp1_isp:0,rkisp1_isp:2->rkisp1_resizer_mainpath:0
+media-formats=imx258 1-001a:0:RGGB10P:1048:780,rkisp1_csi:0:RGGB10P:1048:780,rkisp1_isp:0:RGGB10P:1048:780,rkisp1_isp:2:RGGB8:1048:780,rkisp1_resizer_mainpath:0:RGGB8:1048:780,rkisp1_resizer_mainpath:1:RGGB8:1048:780
+media-crops=rkisp1_isp:0:0:0:1048:780,rkisp1_isp:2:0:0:1048:780,rkisp1_resizer_mainpath:0:0:0:1048:768
+
+[front]
+driver=m00_f_ov8858 1-0036
+media-driver=rkisp1
+capture-width=3264
+capture-height=2448
+capture-rate=30
+;capture-fmt=BGGR10P
+capture-fmt=BGGR8
+preview-width=3264
+preview-height=2448
+preview-rate=30
+;preview-fmt=BGGR10P
+preview-fmt=BGGR8
+rotate=90
+mirrored=true
+focallength=2.94
+cropfactor=12.7
+fnumber=2.4
+flash-display=true
+media-links=m00_f_ov8858 1-0036:0->rkisp1_csi:0,rkisp1_csi:1->rkisp1_isp:0,rkisp1_isp:2->rkisp1_resizer_mainpath:0,rkisp1_resizer_mainpath:1->rkisp1_mainpath:0
+media-formats=m00_f_ov8858 1-0036:0:BGGR10P:3264:2448,rkisp1_csi:0:BGGR10P:3264:2448,rkisp1_isp:0:BGGR10P:3264:2448,rkisp1_isp:2:BGGR8:3264:2448,rkisp1_resizer_mainpath:0:BGGR8:3264:2448,rkisp1_resizer_mainpath:1:BGGR8:3264:2448
+media-crops=rkisp1_isp:0:0:0:3264:2448,rkisp1_isp:2:0:0:3264:2448,rkisp1_resizer_mainpath:0:0:0:3264:768
diff --git a/config/xiaomi,scorpio.ini b/config/xiaomi,scorpio.ini
index cce6d49..14b7f29 100644
--- a/config/xiaomi,scorpio.ini
+++ b/config/xiaomi,scorpio.ini
@@ -15,3 +15,4 @@ preview-rate=30
preview-fmt=RGGB10P
rotate=90
media-links=imx318 3-001a:0->msm_csiphy0:0,msm_csiphy0:1->msm_csid0:0,msm_csid0:1->msm_ispif0:0,msm_ispif0:1->msm_vfe0_rdi0:0
+media-formats=imx318 3-001a:0:RGGB10P:3840:2160,msm_csiphy0:0:RGGB10P:3840:2160,msm_csiphy0:1:RGGB10P:3840:2160,msm_csid0:0:RGGB10P:3840:2160,msm_csid0:1:RGGB10P:3840:2160,msm_ispif0:0:RGGB10P:3840:2160,msm_ispif0:1:RGGB10P:3840:2160,msm_vfe0_rdi0:0:RGGB10P:3840:2160
diff --git a/meson.build b/meson.build
index 3b98f19..d53dec9 100644
--- a/meson.build
+++ b/meson.build
@@ -72,6 +72,7 @@ install_data(
'config/pine64,pinephone-1.0.ini',
'config/pine64,pinephone-1.1.ini',
'config/pine64,pinephone-1.2.ini',
+ 'config/pine64,pinephone-pro.ini',
'config/pine64,pinetab.ini',
'config/xiaomi,scorpio.ini',
],
diff --git a/src/camera.c b/src/camera.c
index 9a08f56..7368189 100644
--- a/src/camera.c
+++ b/src/camera.c
@@ -305,11 +305,11 @@ mp_camera_set_mode(MPCamera *camera, MPMode *mode)
}
// Update the mode
- mode->pixel_format =
- mp_pixel_format_from_v4l_bus_code(fmt.format.code);
- mode->frame_interval = interval.interval;
- mode->width = fmt.format.width;
- mode->height = fmt.format.height;
+ //mode->pixel_format =
+ // mp_pixel_format_from_v4l_bus_code(fmt.format.code);
+ //mode->frame_interval = interval.interval;
+ //mode->width = fmt.format.width;
+ //mode->height = fmt.format.height;
}
// Set the mode for the video device
diff --git a/src/camera_config.c b/src/camera_config.c
index 6ff74d1..1102354 100644
--- a/src/camera_config.c
+++ b/src/camera_config.c
@@ -184,6 +184,67 @@ config_ini_handler(void *user,
++cc->num_media_links;
}
g_strfreev(linkdefs);
+ } else if (strcmp(name, "media-formats") == 0) {
+ struct mp_camera_config *cc = &cameras[index];
+ char **formatdefs = g_strsplit(value, ",", 0);
+
+ for (int i = 0; i < MP_MAX_FORMATS && formatdefs[i] != NULL;
+ ++i) {
+ char **entry = g_strsplit(formatdefs[i], ":", 5);
+ char *name = entry[0];
+ int pad = strtoint(entry[1], NULL, 10);
+ char *format = entry[2];
+ char *width = entry[3];
+ char *height = entry[4];
+
+ const size_t name_size =
+ sizeof(cc->media_formats[i].name);
+ strncpy(cc->media_formats[i].name,
+ name,
+ name_size );
+
+ cc->media_formats[i].pad = pad;
+
+ cc->media_formats[i].mode.pixel_format =
+ mp_pixel_format_from_str(format);
+ cc->media_formats[i].mode.width =
+ strtoint(width, NULL, 10);
+ cc->media_formats[i].mode.height =
+ strtoint(height, NULL, 10);
+
+ cc->num_media_formats++;
+
+ g_strfreev(entry);
+ }
+ } else if (strcmp(name, "media-crops") == 0) {
+ char **formatdefs = g_strsplit(value, ",", 0);
+
+ for (int i = 0; i < MP_MAX_CROPS && formatdefs[i] != NULL;
+ ++i) {
+ char **entry = g_strsplit(formatdefs[i], ":", 6);
+ char *name = entry[0];
+ int pad = strtoint(entry[1], NULL, 10);
+ int top = strtoint(entry[2], NULL, 10);
+ int left = strtoint(entry[3], NULL, 10);
+ int width = strtoint(entry[4], NULL, 10);
+ int height = strtoint(entry[5], NULL, 10);
+
+ const size_t name_size =
+ sizeof(cc->media_crops[i].name);
+ strncpy(cc->media_crops[i].name,
+ name,
+ name_size );
+
+ cc->media_crops[i].pad = pad;
+ cc->media_crops[i].top = top;
+ cc->media_crops[i].left = left;
+ cc->media_crops[i].width = width;
+ cc->media_crops[i].height = height;
+
+ cc->num_media_crops++;
+
+ g_strfreev(entry);
+ }
} else if (strcmp(name, "colormatrix") == 0) {
sscanf(value,
"%f,%f,%f,%f,%f,%f,%f,%f,%f",
diff --git a/src/camera_config.h b/src/camera_config.h
index d53d36f..b1bd5a5 100644
--- a/src/camera_config.h
+++ b/src/camera_config.h
@@ -7,6 +7,8 @@
#define MP_MAX_CAMERAS 5
#define MP_MAX_LINKS 10
+#define MP_MAX_FORMATS 10
+#define MP_MAX_CROPS 10
struct mp_media_link_config {
char source_name[100];
@@ -15,6 +17,21 @@ struct mp_media_link_config {
int target_port;
};
+struct mp_media_format_config {
+ char name[100];
+ int pad;
+ MPMode mode;
+};
+
+struct mp_media_crop_config {
+ char name[100];
+ int pad;
+ int left;
+ int top;
+ int width;
+ int height;
+};
+
struct mp_camera_config {
size_t index;
@@ -30,6 +47,12 @@ struct mp_camera_config {
struct mp_media_link_config media_links[MP_MAX_LINKS];
int num_media_links;
+ struct mp_media_format_config media_formats[MP_MAX_FORMATS];
+ int num_media_formats;
+
+ struct mp_media_crop_config media_crops[MP_MAX_CROPS];
+ int num_media_crops;
+
float colormatrix[9];
float forwardmatrix[9];
float previewmatrix[9];
diff --git a/src/device.c b/src/device.c
index 9e2db00..0defccb 100644
--- a/src/device.c
+++ b/src/device.c
@@ -8,6 +8,8 @@
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
+#include <linux/v4l2-subdev.h>
+#include <linux/media.h>
bool
mp_find_device_path(struct media_v2_intf_devnode devnode, char *path, int length)
@@ -237,6 +239,73 @@ mp_entity_pad_set_format(MPDevice *device,
return true;
}
+const struct media_v2_pad *
+mp_device_get_pad_at_index_from_entity(const MPDevice *device, uint32_t entity_id, uint32_t index)
+{
+ for (int i = 0; i < device->num_pads; ++i) {
+ if (device->pads[i].entity_id == entity_id && index-- == 0) {
+ return &device->pads[i];
+ }
+ }
+ return NULL;
+}
+
+bool
+mp_device_setup_link_by_name(MPDevice *device,
+ const char *source_entity_name,
+ uint32_t source_pad_index,
+ const char *sink_entity_name,
+ uint32_t sink_pad_index,
+ bool enabled)
+{
+ const struct media_v2_entity *source_entity =
+ mp_device_find_entity
+ (device, source_entity_name);
+ const struct media_v2_entity *sink_entity =
+ mp_device_find_entity
+ (device, sink_entity_name);
+
+ struct media_link_desc link = {};
+ link.flags = enabled ? MEDIA_LNK_FL_ENABLED : 0;
+ link.source.entity = source_entity->id;
+ link.source.index = source_pad_index;
+ link.sink.entity = sink_entity->id;
+ link.sink.index = sink_pad_index;
+ if (xioctl(device->fd, MEDIA_IOC_SETUP_LINK, &link) == -1) {
+ errno_printerr("MEDIA_IOC_SETUP_LINK");
+ return false;
+ }
+
+ return true;
+}
+
+int
+mp_device_get_fd_by_name(const MPDevice *device, const char *driver_name)
+{
+ struct media_entity_desc desc = {};
+
+ desc.id |= MEDIA_ENT_ID_FLAG_NEXT;
+
+ while(true) {
+ desc.id |= MEDIA_ENT_ID_FLAG_NEXT;
+ if(xioctl(device->fd, MEDIA_IOC_ENUM_ENTITIES, &desc) == -1) {
+ errno_printerr("MEDIA_IOC_ENUM_ENTITIES");
+ return -1;
+ }
+
+ if(strncmp(desc.name, driver_name, 32) == 0) {
+ const uint32_t major = desc.dev.major;
+ const uint32_t minor = desc.dev.minor;
+ char path[256];
+ int rc = snprintf(path, 256, "/dev/char/%u:%u", major, minor);
+
+ return rc > 0 ? open(path, O_RDWR) : -1;
+ }
+ }
+
+ return -1;
+}
+
const struct media_v2_entity *
mp_device_find_entity(const MPDevice *device, const char *driver_name)
{
@@ -263,6 +332,19 @@ mp_device_find_entity_type(const MPDevice *device, const uint32_t type)
return NULL;
}
+bool
+mp_xioctl(const MPDevice *device, const char *driver_name, unsigned long request, void *argp)
+{
+ int fd = mp_device_get_fd_by_name(device, driver_name);
+
+ if(fd < 0)
+ {
+ printf("ERROR: device with driver name %s not found\n", driver_name);
+ }
+
+ return fd >= 0 && xioctl(fd, request, argp) != -1;
+}
+
const struct media_device_info *
mp_device_get_info(const MPDevice *device)
{
diff --git a/src/device.h b/src/device.h
index 1894c67..a9e1b59 100644
--- a/src/device.h
+++ b/src/device.h
@@ -36,6 +36,15 @@ bool mp_entity_pad_set_format(MPDevice *device,
uint32_t pad,
MPMode *mode);
+bool mp_xioctl(const MPDevice *device, const char *driver_name, unsigned long request, void *argp);
+
+bool mp_device_setup_link_by_name(MPDevice *device,
+ const char *source_entity_name,
+ uint32_t source_pad_index,
+ const char *sink_entity_name,
+ uint32_t sink_pad_index,
+ bool enabled);
+
const struct media_device_info *mp_device_get_info(const MPDevice *device);
const struct media_v2_entity *mp_device_find_entity(const MPDevice *device,
const char *driver_name);
diff --git a/src/io_pipeline.c b/src/io_pipeline.c
index 8434420..da95678 100644
--- a/src/io_pipeline.c
+++ b/src/io_pipeline.c
@@ -47,7 +47,8 @@ struct camera_info {
// int media_fd;
// struct mp_media_link media_links[MP_MAX_LINKS];
- // int num_media_links;
+ struct mp_media_link_config media_links[MP_MAX_LINKS];
+ int num_media_links;
// int gain_ctrl;
};
@@ -100,36 +101,68 @@ static bool want_focus = false;
static MPPipeline *pipeline;
static GSource *capture_source;
+// TODO: move to device.c
+static void
+mp_setup_media_link_pad_crops(struct device_info *dev_info,
+ const struct mp_media_crop_config media_crops[],
+ int num_media_crops)
+{
+ for(int i = 0; i < num_media_crops; i++) {
+ const struct mp_media_crop_config *crop = media_crops + i;
+ struct v4l2_subdev_crop v4l2_crop = {};
+ v4l2_crop.pad = crop->pad;
+ v4l2_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ v4l2_crop.rect.top = crop->top;
+ v4l2_crop.rect.left = crop->left;
+ v4l2_crop.rect.width = crop->width;
+ v4l2_crop.rect.height = crop->height;
+
+ if(!mp_xioctl(dev_info->device, crop->name, VIDIOC_SUBDEV_S_CROP, &v4l2_crop)) {
+ //errno_printerr("VIDIOC_SUBDEV_S_CROP");
+ }
+ }
+}
+
static void
mp_setup_media_link_pad_formats(struct device_info *dev_info,
- const struct mp_media_link_config media_links[],
- int num_media_links,
- MPMode *mode)
+ const struct mp_media_format_config media_formats[],
+ int num_media_formats)
{
- const struct media_v2_entity *entities[2];
- int ports[2];
- for (int i = 0; i < num_media_links; i++) {
- entities[0] = mp_device_find_entity(
- dev_info->device, (const char *)media_links[i].source_name);
- entities[1] = mp_device_find_entity(
- dev_info->device, (const char *)media_links[i].target_name);
- ports[0] = media_links[i].source_port;
- ports[1] = media_links[i].target_port;
-
- for (int j = 0; j < 2; j++)
- if (!mp_entity_pad_set_format(
- dev_info->device, entities[j], ports[j], mode)) {
- g_printerr("Failed to set %s:%d format\n",
- entities[j]->name,
- ports[j]);
- exit(EXIT_FAILURE);
- }
+ for(int i = 0; i < num_media_formats; i++) {
+ const struct mp_media_format_config *format =
+ media_formats + i;
+ const struct media_v2_entity *entity =
+ mp_device_find_entity
+ (dev_info->device, format->name);
+ MPMode *mode =
+ (MPMode *)
+ &format->mode;
+ bool successful =
+ mp_entity_pad_set_format
+ (dev_info->device, entity, format->pad, mode);
+
+ if(!successful) {
+ g_printerr( "Failed to set %s:%d format\n",
+ entity->name,
+ format->pad );
+ exit(EXIT_FAILURE);
+ }
}
}
static void
setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
{
+ char compat[512];
+ FILE *fp = fopen("/proc/device-tree/compatible", "r");
+ fgets(compat, 512, fp);
+ fclose(fp);
+
+ printf("setup_camera()\n");
+ printf("compatible: %s\n", compat);
+ printf("media_dev: %s\n", config->media_dev_name);
+ printf("dev: %s\n", config->dev_name);
+
// Find device info
size_t device_index = 0;
for (; device_index < num_devices; ++device_index) {
@@ -144,6 +177,7 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
if (device_index == num_devices) {
device_index = num_devices;
+ printf("initializing new device\n");
// Initialize new device
struct device_info *info = &devices[device_index];
info->media_dev_name = config->media_dev_name;
@@ -175,6 +209,8 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
exit(EXIT_FAILURE);
}
+ printf("video path: %s\n", dev_name);
+
info->video_fd = open(dev_name, O_RDWR);
if (info->video_fd == -1) {
g_printerr("Could not open %s: %s\n",
@@ -191,6 +227,9 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
struct device_info *dev_info = &devices[device_index];
info->device_index = device_index;
+ info->num_media_links = config->num_media_links;
+
+ memcpy(info->media_links, config->media_links, MP_MAX_LINKS * sizeof(struct mp_media_link_config));
const struct media_v2_entity *entity =
mp_device_find_entity(dev_info->device, config->dev_name);
@@ -205,11 +244,48 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
info->pad_id = pad->id;
+ // Disable all links
+ const size_t num_links =
+ mp_device_get_num_links(dev_info->device);
+ const struct media_v2_link *links =
+ mp_device_get_links(dev_info->device);
+
+ for(int i = 0; i < num_links; i++) {
+ const struct media_v2_link *link = links + i;
+
+ if(!(link->flags & MEDIA_LNK_FL_IMMUTABLE)) {
+ mp_device_setup_link(dev_info->device,
+ link->source_id,
+ link->sink_id,
+ false);
+ }
+ }
+
// Make sure the camera starts out as disabled
- mp_device_setup_link(dev_info->device,
- info->pad_id,
- dev_info->interface_pad_id,
- false);
+ printf("making sure camera starts out disabled\n");
+ if(config->num_media_links > 0)
+ {
+ const struct media_v2_entity *entity =
+ mp_device_find_entity(dev_info->device, config->media_links[0].source_name);
+
+ // This gets the first pad for this entity, which is
+ // fine for Pinephone Pro, but does it really work for
+ // all devices?
+ const struct media_v2_pad* pad =
+ mp_device_get_pad_from_entity(dev_info->device, entity->id);
+
+ mp_device_setup_link(dev_info->device,
+ info->pad_id,
+ pad->id,
+ false);
+ }
+ else
+ {
+ mp_device_setup_link(dev_info->device,
+ info->pad_id,
+ dev_info->interface_pad_id,
+ false);
+ }
const struct media_v2_interface *interface =
mp_device_find_entity_interface(dev_info->device,
@@ -220,6 +296,7 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
exit(EXIT_FAILURE);
}
+ printf("camera device path: %s\n", info->dev_fname);
info->fd = open(info->dev_fname, O_RDWR);
if (info->fd == -1) {
g_printerr("Could not open %s: %s\n",
@@ -234,11 +311,14 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
// the ov5640 driver where it won't allow setting the preview
// format initially.
MPMode mode = config->capture_mode;
- if (config->num_media_links)
+ if (config->num_media_formats)
mp_setup_media_link_pad_formats(dev_info,
- config->media_links,
- config->num_media_links,
- &mode);
+ config->media_formats,
+ config->num_media_formats);
+ if (config->num_media_crops)
+ mp_setup_media_link_pad_crops(dev_info,
+ config->media_crops,
+ config->num_media_crops);
mp_camera_set_mode(info->camera, &mode);
// Trigger continuous auto focus if the sensor supports it
@@ -400,9 +480,12 @@ capture(MPPipeline *pipeline, const void *data)
mode = camera->capture_mode;
if (camera->num_media_links)
mp_setup_media_link_pad_formats(dev_info,
- camera->media_links,
- camera->num_media_links,
- &mode);
+ camera->media_formats,
+ camera->num_media_formats);
+ if (camera->num_media_crops)
+ mp_setup_media_link_pad_crops(dev_info,
+ camera->media_crops,
+ camera->num_media_crops);
mp_camera_set_mode(info->camera, &mode);
just_switched_mode = true;
@@ -569,9 +652,13 @@ on_frame(MPBuffer buffer, void *_data)
if (camera->num_media_links)
mp_setup_media_link_pad_formats(
dev_info,
- camera->media_links,
- camera->num_media_links,
- &mode);
+ camera->media_formats,
+ camera->num_media_formats);
+ if (camera->num_media_crops)
+ mp_setup_media_link_pad_crops(
+ dev_info,
+ camera->media_crops,
+ camera->num_media_crops);
mp_camera_set_mode(info->camera, &mode);
just_switched_mode = true;
@@ -609,6 +696,8 @@ mp_setup_media_link(struct device_info *dev_info,
static void
update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
{
+ printf("update_state()\n");
+
// Make sure the state isn't updated more than it needs to be by checking
// whether this state change actually changes anything.
bool has_changed = false;
@@ -617,6 +706,7 @@ update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
has_changed = true;
if (camera) {
+ printf("uninitializing current camera\n");
struct camera_info *info = &cameras[camera->index];
struct device_info *dev_info = &devices[info->device_index];
@@ -634,6 +724,7 @@ update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
}
if (capture_source) {
+ printf("uninitializing current capture source\n");
g_source_destroy(capture_source);
capture_source = NULL;
}
@@ -641,13 +732,33 @@ update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
camera = state->camera;
if (camera) {
+ printf("initializing camera\n");
struct camera_info *info = &cameras[camera->index];
struct device_info *dev_info = &devices[info->device_index];
- mp_device_setup_link(dev_info->device,
- info->pad_id,
- dev_info->interface_pad_id,
- true);
+ if(info->num_media_links > 0)
+ {
+ const struct media_v2_entity *entity =
+ mp_device_find_entity(dev_info->device, info->media_links[0].source_name);
+
+ // This gets the first pad for this entity, which is
+ // fine for Pinephone Pro, but does it really work for
+ // all devices?
+ const struct media_v2_pad* pad =
+ mp_device_get_pad_from_entity(dev_info->device, entity->id);
+
+ mp_device_setup_link(dev_info->device,
+ info->pad_id,
+ pad->id,
+ true);
+ }
+ else
+ {
+ mp_device_setup_link(dev_info->device,
+ info->pad_id,
+ dev_info->interface_pad_id,
+ true);
+ }
// Enable media links
for (int i = 0; i < camera->num_media_links; i++)
@@ -658,9 +769,13 @@ update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
if (camera->num_media_links)
mp_setup_media_link_pad_formats(
dev_info,
- camera->media_links,
- camera->num_media_links,
- &mode);
+ camera->media_formats,
+ camera->num_media_formats);
+ if (camera->num_media_crops)
+ mp_setup_media_link_pad_crops(
+ dev_info,
+ camera->media_crops,
+ camera->num_media_crops);
mp_camera_set_mode(info->camera, &mode);
mp_camera_start_capture(info->camera);