/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2019, Collabora Ltd. * Author: Nicolas Dufresne * * gstlibcamerapad.cpp - GStreamer Capture Pad */ #include "gstlibcamerapad.h" #include #include "gstlibcamera-utils.h" using namespace libcamera; struct _GstLibcameraPad { GstPad parent; StreamRole role; GstLibcameraPool *pool; 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(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); /* 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) { 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(StreamRole::StillCapture), "libcamera::StillCapture", "still-capture", }, { static_cast(StreamRole::VideoRecording), "libcamera::VideoRecording", "video-recording", }, { static_cast(StreamRole::Viewfinder), "libcamera::Viewfinder", "view-finder", }, { 0, NULL, NULL } }; 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(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; } Stream * gst_libcamera_pad_get_stream(GstPad *pad) { auto *self = GST_LIBCAMERA_PAD(pad); if (self->pool) return gst_libcamera_pool_get_stream(self->pool); return nullptr; } void gst_libcamera_pad_set_latency(GstPad *pad, GstClockTime latency) { auto *self = GST_LIBCAMERA_PAD(pad); GLibLocker lock(GST_OBJECT(self)); self->latency = latency; } 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * signal-threads.cpp - Cross-thread signal delivery test
 */

#include <chrono>
#include <iostream>
#include <thread>

#include <libcamera/base/message.h>
#include <libcamera/base/thread.h>
#include <libcamera/base/utils.h>

#include "test.h"

using namespace std;
using namespace libcamera;

class SignalReceiver : public Object
{
public:
	enum Status {
		NoSignal,
		InvalidThread,
		SignalReceived,
	};

	SignalReceiver()