Files
external_libcamera/src/gstreamer/gstlibcamerapad.cpp
T
Umang JainandKieran Bingham f6f5bd28dc gstreamer: Associate libcamera::Stream with GstPad
Instead of trying to figure out which libcamera::Stream, the GstPad
is configured with (from the libcamera pool), associate the Stream
with the GstPad directly. The association can be set using
gst_pad_set_element_private().

Add the gst_libcamera_pad_set_stream() helper to associate the stream
with the pad. Additionally, modify the gst_libcamera_pad_get_stream()
to use to the getter helper gst_pad_get_element_private().

Signed-off-by: Umang Jain <uajain@igalia.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-11-04 15:31:34 +00:00

211 lines
4.6 KiB
C++

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2019, Collabora Ltd.
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
*
* GStreamer Capture Pad
*/
#include "gstlibcamerapad.h"
#include <libcamera/stream.h>
#include "gstlibcamera-utils.h"
using namespace libcamera;
struct _GstLibcameraPad {
GstPad parent;
StreamRole role;
GstLibcameraPool *pool;
GstBufferPool *video_pool;
GstVideoInfo info;
GstClockTime latency;
};
enum {
PROP_0,
PROP_STREAM_ROLE
};
G_DEFINE_TYPE(GstLibcameraPad, gst_libcamera_pad, GST_TYPE_PAD)
static void
gst_libcamera_pad_set_property(GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
auto *self = GST_LIBCAMERA_PAD(object);
GLibLocker lock(GST_OBJECT(self));
switch (prop_id) {
case PROP_STREAM_ROLE:
self->role = (StreamRole)g_value_get_enum(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
gst_libcamera_pad_get_property(GObject *object, guint prop_id, GValue *value,
GParamSpec *pspec)
{
auto *self = GST_LIBCAMERA_PAD(object);
GLibLocker lock(GST_OBJECT(self));
switch (prop_id) {
case PROP_STREAM_ROLE:
g_value_set_enum(value, static_cast<gint>(self->role));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static gboolean
gst_libcamera_pad_query(GstPad *pad, GstObject *parent, GstQuery *query)
{
auto *self = GST_LIBCAMERA_PAD(pad);
if (query->type != GST_QUERY_LATENCY)
return gst_pad_query_default(pad, parent, query);
GLibLocker lock(GST_OBJECT(self));
if (self->latency == GST_CLOCK_TIME_NONE)
return FALSE;
/* TRUE here means live, we assumes that max latency is the same as min
* as we have no idea that duration of frames. */
gst_query_set_latency(query, TRUE, self->latency, self->latency);
return TRUE;
}
static void
gst_libcamera_pad_init(GstLibcameraPad *self)
{
self->latency = GST_CLOCK_TIME_NONE;
GST_PAD_QUERYFUNC(self) = gst_libcamera_pad_query;
}
static GType
gst_libcamera_stream_role_get_type()
{
static GType type = 0;
static const GEnumValue values[] = {
{
static_cast<gint>(StreamRole::StillCapture),
"libcamera::StillCapture",
"still-capture",
}, {
static_cast<gint>(StreamRole::VideoRecording),
"libcamera::VideoRecording",
"video-recording",
}, {
static_cast<gint>(StreamRole::Viewfinder),
"libcamera::Viewfinder",
"view-finder",
},
{ 0, nullptr, nullptr }
};
if (!type)
type = g_enum_register_static("GstLibcameraStreamRole", values);
return type;
}
static void
gst_libcamera_pad_class_init(GstLibcameraPadClass *klass)
{
auto *object_class = G_OBJECT_CLASS(klass);
object_class->set_property = gst_libcamera_pad_set_property;
object_class->get_property = gst_libcamera_pad_get_property;
auto *spec = g_param_spec_enum("stream-role", "Stream Role",
"The selected stream role",
gst_libcamera_stream_role_get_type(),
static_cast<gint>(StreamRole::VideoRecording),
(GParamFlags)(GST_PARAM_MUTABLE_READY
| G_PARAM_CONSTRUCT
| G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class, PROP_STREAM_ROLE, spec);
}
StreamRole
gst_libcamera_pad_get_role(GstPad *pad)
{
auto *self = GST_LIBCAMERA_PAD(pad);
GLibLocker lock(GST_OBJECT(self));
return self->role;
}
GstLibcameraPool *
gst_libcamera_pad_get_pool(GstPad *pad)
{
auto *self = GST_LIBCAMERA_PAD(pad);
return self->pool;
}
void
gst_libcamera_pad_set_pool(GstPad *pad, GstLibcameraPool *pool)
{
auto *self = GST_LIBCAMERA_PAD(pad);
if (self->pool)
g_object_unref(self->pool);
self->pool = pool;
}
GstBufferPool *
gst_libcamera_pad_get_video_pool(GstPad *pad)
{
auto *self = GST_LIBCAMERA_PAD(pad);
return self->video_pool;
}
void gst_libcamera_pad_set_video_pool(GstPad *pad, GstBufferPool *video_pool)
{
auto *self = GST_LIBCAMERA_PAD(pad);
if (self->video_pool)
g_object_unref(self->video_pool);
self->video_pool = video_pool;
}
GstVideoInfo gst_libcamera_pad_get_video_info(GstPad *pad)
{
auto *self = GST_LIBCAMERA_PAD(pad);
return self->info;
}
void gst_libcamera_pad_set_video_info(GstPad *pad, const GstVideoInfo *info)
{
auto *self = GST_LIBCAMERA_PAD(pad);
self->info = *info;
}
Stream *
gst_libcamera_pad_get_stream(GstPad *pad)
{
return static_cast<Stream *>(gst_pad_get_element_private(pad));
}
void
gst_libcamera_pad_set_stream(GstPad *pad, Stream *stream)
{
gst_pad_set_element_private(pad, stream);
}
void
gst_libcamera_pad_set_latency(GstPad *pad, GstClockTime latency)
{
auto *self = GST_LIBCAMERA_PAD(pad);
GLibLocker lock(GST_OBJECT(self));
self->latency = latency;
}