mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
libcamera: Implement SPA_META_VideoTransform support
libcamera can detect camera transforms/rotation, e.g. from the device tree, and makes that information usable for clients via `CameraConfiguration::transform`. Advertise this information via the VideoTransform meta so Pipewire clients can adjust their output accordingly. Rotated cameras are common in mobile devices such as the Pinephone Pro, which was used to test this feature.
This commit is contained in:
parent
9f2abea480
commit
fa799aac86
2 changed files with 41 additions and 0 deletions
|
|
@ -78,6 +78,7 @@ struct buffer {
|
|||
struct spa_list link;
|
||||
struct spa_buffer *outbuf;
|
||||
struct spa_meta_header *h;
|
||||
struct spa_meta_videotransform *videotransform;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
|
|
@ -589,6 +590,12 @@ next:
|
|||
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
|
||||
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
|
||||
break;
|
||||
case 1:
|
||||
param = (struct spa_pod*)spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamMeta, id,
|
||||
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoTransform),
|
||||
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_videotransform)));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -698,6 +698,31 @@ static int spa_libcamera_use_buffers(struct impl *impl, struct port *port,
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
Transform libcamera_transform;
|
||||
uint32_t spa_transform_value;
|
||||
} transform_map[] = {
|
||||
{ Transform::Identity, SPA_META_TRANSFORMATION_None },
|
||||
{ Transform::Rot0, SPA_META_TRANSFORMATION_None },
|
||||
{ Transform::HFlip, SPA_META_TRANSFORMATION_Flipped },
|
||||
{ Transform::VFlip, SPA_META_TRANSFORMATION_Flipped180 },
|
||||
{ Transform::HVFlip, SPA_META_TRANSFORMATION_180 },
|
||||
{ Transform::Rot180, SPA_META_TRANSFORMATION_180 },
|
||||
{ Transform::Transpose, SPA_META_TRANSFORMATION_Flipped90 },
|
||||
{ Transform::Rot90, SPA_META_TRANSFORMATION_270 },
|
||||
{ Transform::Rot270, SPA_META_TRANSFORMATION_90 },
|
||||
{ Transform::Rot180Transpose, SPA_META_TRANSFORMATION_Flipped270 },
|
||||
};
|
||||
|
||||
static uint32_t libcamera_transform_to_spa_transform_value(Transform transform)
|
||||
{
|
||||
for (const auto& t : transform_map) {
|
||||
if (t.libcamera_transform == transform)
|
||||
return t.spa_transform_value;
|
||||
}
|
||||
return SPA_META_TRANSFORMATION_None;
|
||||
}
|
||||
|
||||
static int
|
||||
mmap_init(struct impl *impl, struct port *port,
|
||||
struct spa_buffer **buffers, uint32_t n_buffers)
|
||||
|
|
@ -742,6 +767,15 @@ mmap_init(struct impl *impl, struct port *port,
|
|||
b->flags = BUFFER_FLAG_OUTSTANDING;
|
||||
b->h = (struct spa_meta_header*)spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
b->videotransform = (struct spa_meta_videotransform*)spa_buffer_find_meta_data(
|
||||
buffers[i], SPA_META_VideoTransform, sizeof(*b->videotransform));
|
||||
if (b->videotransform) {
|
||||
b->videotransform->transform =
|
||||
libcamera_transform_to_spa_transform_value(impl->config->transform);
|
||||
spa_log_debug(impl->log, "Setting videotransform for buffer %d to %u",
|
||||
i, b->videotransform->transform);
|
||||
}
|
||||
|
||||
d = buffers[i]->datas;
|
||||
for(j = 0; j < buffers[i]->n_datas; ++j) {
|
||||
d[j].type = port->memtype;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue