summaryrefslogtreecommitdiff
path: root/src/cam/main.cpp
AgeCommit message (Expand)Author
2020-05-01cam: Make use of StreamKeyValueParserNiklas Söderlund
2020-04-26cam: Add an option to list camera controlsLaurent Pinchart
2020-04-26cam: Rename OptProps to OptListPropertiesLaurent Pinchart
2020-03-27cam: Add option to capture StillCaptureRaw streamNiklas Söderlund
2020-03-24cam: main: Cache lookup of role propertyLaurent Pinchart
2020-03-20cam: Print one property per lineJacopo Mondi
2020-03-18libcamera: PixelFormat: Turn into a classNiklas Söderlund
2020-03-18libcamera: Use PixelFormat instead of unsigned int where appropriateNiklas Söderlund
2020-03-06cam: Add option to list camera propertiesJacopo Mondi
2019-11-20cam: Store camera as shared pointer everywhereNiklas Söderlund
2019-08-19libcamera: camera_manager: Construct CameraManager instances manuallyLaurent Pinchart
2019-06-19cam: Add --info option to print information about stream(s)Niklas Söderlund
2019-06-19cam: Validate camera configurationNiklas Söderlund
2019-06-19cam: Move camera configuration preparation to CamAppNiklas Söderlund
2019-06-18cam: Allow selecting cameras by indexLaurent Pinchart
2019-06-10cam: Fix cam --help crashNiklas Söderlund
2019-05-25cam: Add CamApp classNiklas Söderlund
2019-05-25cam: capture: Break out capture to a new classNiklas Söderlund
2019-05-23cam: Rename conf variable referring to command line option to optLaurent Pinchart
2019-05-23libcamera: camera: Add a validation API to the CameraConfiguration classLaurent Pinchart
2019-05-23libcamera: camera: Return a pointer from generateConfiguration()Laurent Pinchart
2019-05-23libcamera: Refactor the camera configuration storage and APILaurent Pinchart
2019-05-23libcamera: Use stream roles directly instead of StreamUsageLaurent Pinchart
2019-05-23libcamera: camera: Rename configureStreams() and streamConfiguration()Laurent Pinchart
2019-04-30libcamera: Use the Size class through libcameraLaurent Pinchart
2019-04-09cam: Allow cameras with more than one streamNiklas Söderlund
2019-04-09cam: Extend request completion handler to deal with multiple streamsNiklas Söderlund
2019-04-09cam: Add support to specify multiple stream configurations with rolesNiklas Söderlund
2019-04-09cam: Extend BufferWriter to include a stream name in file pathNiklas Söderlund
2019-04-09cam: Rename --format to --streamNiklas Söderlund
2019-04-09libcamera: Switch to CameraConfigurationNiklas Söderlund
2019-04-05libcamera: camera: Add support for stream usagesNiklas Söderlund
2019-04-04cam: Rework how streams configuration is preparedNiklas Söderlund
2019-03-27cam: Separate options valid() and empty()Laurent Pinchart
2019-03-01cam: Don't requeue requests when stopping streamLaurent Pinchart
2019-02-28libcamera: store stream pointers in sets instead of a vectorsNiklas Söderlund
2019-02-28cam: fix order camera is operated onNiklas Söderlund
2019-02-25cam: Improve when usage information is printedNiklas Söderlund
2019-02-25cam: fix printing of camera nameNiklas Söderlund
2019-02-25cam: improve error checking when capturingNiklas Söderlund
2019-02-25cam: free allocated buffers when done capturingNiklas Söderlund
2019-02-25cam: fix return type of configureStreams()Niklas Söderlund
2019-02-06cam: Add option to write raw frames to diskNiklas Söderlund
2019-02-06cam: Add capture operationNiklas Söderlund
2019-02-01cam: Add --format option to configure a streamNiklas Söderlund
2019-02-01cam: options: Add option type handling to options parserLaurent Pinchart
2019-02-01cam: options: Move enum OptionArgumentNiklas Söderlund
2019-01-25cam: Add event loopLaurent Pinchart
2019-01-22cam: options: Don't implement move semantics for OptionsParser::OptionsLaurent Pinchart
2019-01-22cam: Extract option parser to separate fileLaurent Pinchart
s="hl opt">(device)->name, nullptr); return TRUE; } static void gst_libcamera_device_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GstLibcameraDevice *device = GST_LIBCAMERA_DEVICE(object); switch (prop_id) { case PROP_DEVICE_NAME: device->name = g_value_dup_string(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void gst_libcamera_device_init([[maybe_unused]] GstLibcameraDevice *self) { } static void gst_libcamera_device_finalize(GObject *object) { GstLibcameraDevice *self = GST_LIBCAMERA_DEVICE(object); gpointer klass = gst_libcamera_device_parent_class; g_free(self->name); G_OBJECT_CLASS(klass)->finalize(object); } static void gst_libcamera_device_class_init(GstLibcameraDeviceClass *klass) { GstDeviceClass *device_class = GST_DEVICE_CLASS(klass); GObjectClass *object_class = G_OBJECT_CLASS(klass); device_class->create_element = gst_libcamera_device_create_element; device_class->reconfigure_element = gst_libcamera_device_reconfigure_element; object_class->set_property = gst_libcamera_device_set_property; object_class->finalize = gst_libcamera_device_finalize; GParamSpec *pspec = g_param_spec_string("name", "Name", "The name of the camera device", "", (GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property(object_class, PROP_DEVICE_NAME, pspec); } static GstDevice * gst_libcamera_device_new(const std::shared_ptr<Camera> &camera) { g_autoptr(GstCaps) caps = gst_caps_new_empty(); const gchar *name = camera->id().c_str(); StreamRoles roles; roles.push_back(StreamRole::VideoRecording); std::unique_ptr<CameraConfiguration> config = camera->generateConfiguration(roles); for (const StreamConfiguration &stream_cfg : *config) { GstCaps *sub_caps = gst_libcamera_stream_formats_to_caps(stream_cfg.formats()); if (sub_caps) gst_caps_append(caps, sub_caps); } return GST_DEVICE(g_object_new(GST_TYPE_LIBCAMERA_DEVICE, /* \todo Use a unique identifier instead of camera name. */ "name", name, "display-name", name, "caps", caps, "device-class", "Source/Video", nullptr)); } /** * \struct _GstLibcameraProvider * \brief libcamera GstDeviceProvider implementation * * This GstFeature is used by GstDeviceMonitor to probe the available * libcamera devices. The implementation is private to the plugin. */ struct _GstLibcameraProvider { GstDeviceProvider parent; }; G_DEFINE_TYPE_WITH_CODE(GstLibcameraProvider, gst_libcamera_provider, GST_TYPE_DEVICE_PROVIDER, GST_DEBUG_CATEGORY_INIT(provider_debug, "libcamera-provider", 0, "libcamera Device Provider")) static GList * gst_libcamera_provider_probe(GstDeviceProvider *provider) { GstLibcameraProvider *self = GST_LIBCAMERA_PROVIDER(provider); std::shared_ptr<CameraManager> cm; GList *devices = nullptr; gint ret; GST_INFO_OBJECT(self, "Probing cameras using libcamera"); /* \todo Move the CameraMananger start()/stop() calls into * GstDeviceProvider start()/stop() virtual function when CameraMananger * gains monitoring support. Meanwhile we need to cycle start()/stop() * to ensure every probe() calls return the latest list. */ cm = gst_libcamera_get_camera_mananger(ret); if (ret) { GST_ERROR_OBJECT(self, "Failed to retrieve device list: %s", g_strerror(-ret)); return nullptr; } for (const std::shared_ptr<Camera> &camera : cm->cameras()) { GST_INFO_OBJECT(self, "Found camera '%s'", camera->id().c_str()); devices = g_list_append(devices, g_object_ref_sink(gst_libcamera_device_new(camera))); } return devices; } static void gst_libcamera_provider_init(GstLibcameraProvider *self) { GstDeviceProvider *provider = GST_DEVICE_PROVIDER(self); /* Avoid devices being duplicated. */ gst_device_provider_hide_provider(provider, "v4l2deviceprovider"); } static void gst_libcamera_provider_class_init(GstLibcameraProviderClass *klass) { GstDeviceProviderClass *provider_class = GST_DEVICE_PROVIDER_CLASS(klass); provider_class->probe = gst_libcamera_provider_probe; gst_device_provider_class_set_metadata(provider_class, "libcamera Device Provider", "Source/Video", "List camera device using libcamera", "Nicolas Dufresne <nicolas.dufresne@collabora.com>"); }