[libcamera-devel,v3,2/9] libcamera: Add MediaDeviceBase
diff mbox series

Message ID 20230105043726.679968-3-chenghaoyang@google.com
State Superseded
Headers show
Series
  • Virtual pipeline handler
Related show

Commit Message

Harvey Yang Jan. 5, 2023, 4:37 a.m. UTC
To introduce a virtual MediaDevice class in the following patches, adds
a base class of MediaDevice, to be used in other base classes.

Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
---
 include/libcamera/internal/media_device.h     |  35 +----
 .../libcamera/internal/media_device_base.h    |  68 +++++++++
 include/libcamera/internal/meson.build        |   1 +
 src/libcamera/media_device.cpp                |  97 +-----------
 src/libcamera/media_device_base.cpp           | 140 ++++++++++++++++++
 src/libcamera/meson.build                     |   1 +
 6 files changed, 221 insertions(+), 121 deletions(-)
 create mode 100644 include/libcamera/internal/media_device_base.h
 create mode 100644 src/libcamera/media_device_base.cpp

Patch
diff mbox series

diff --git a/include/libcamera/internal/media_device.h b/include/libcamera/internal/media_device.h
index eb8cfde4..0edf6b98 100644
--- a/include/libcamera/internal/media_device.h
+++ b/include/libcamera/internal/media_device.h
@@ -18,35 +18,26 @@ 
 #include <libcamera/base/signal.h>
 #include <libcamera/base/unique_fd.h>
 
+#include "libcamera/internal/media_device_base.h"
 #include "libcamera/internal/media_object.h"
 
 namespace libcamera {
 
-class MediaDevice : protected Loggable
+class MediaDevice : public MediaDeviceBase
 {
 public:
 	MediaDevice(const std::string &deviceNode);
 	~MediaDevice();
 
-	bool acquire();
-	void release();
-	bool busy() const { return acquired_; }
+	bool lock() override;
+	void unlock() override;
 
-	bool lock();
-	void unlock();
+	int populate() override;
 
-	int populate();
-	bool isValid() const { return valid_; }
-
-	const std::string &driver() const { return driver_; }
-	const std::string &deviceNode() const { return deviceNode_; }
 	const std::string &model() const { return model_; }
 	unsigned int version() const { return version_; }
 	unsigned int hwRevision() const { return hwRevision_; }
 
-	const std::vector<MediaEntity *> &entities() const { return entities_; }
-	MediaEntity *getEntityByName(const std::string &name) const;
-
 	MediaLink *link(const std::string &sourceName, unsigned int sourceIdx,
 			const std::string &sinkName, unsigned int sinkIdx);
 	MediaLink *link(const MediaEntity *source, unsigned int sourceIdx,
@@ -54,18 +45,13 @@  public:
 	MediaLink *link(const MediaPad *source, const MediaPad *sink);
 	int disableLinks();
 
-	Signal<> disconnected;
-
-protected:
-	std::string logPrefix() const override;
-
 private:
-	int open();
-	void close();
+	int open() override;
+	void close() override;
 
 	MediaObject *object(unsigned int id);
 	bool addObject(MediaObject *object);
-	void clear();
+	void clear() override;
 
 	struct media_v2_interface *findInterface(const struct media_v2_topology &topology,
 						 unsigned int entityId);
@@ -77,18 +63,13 @@  private:
 	friend int MediaLink::setEnabled(bool enable);
 	int setupLink(const MediaLink *link, unsigned int flags);
 
-	std::string driver_;
-	std::string deviceNode_;
 	std::string model_;
 	unsigned int version_;
 	unsigned int hwRevision_;
 
 	UniqueFD fd_;
-	bool valid_;
-	bool acquired_;
 
 	std::map<unsigned int, MediaObject *> objects_;
-	std::vector<MediaEntity *> entities_;
 };
 
 } /* namespace libcamera */
diff --git a/include/libcamera/internal/media_device_base.h b/include/libcamera/internal/media_device_base.h
new file mode 100644
index 00000000..4f2d1fb7
--- /dev/null
+++ b/include/libcamera/internal/media_device_base.h
@@ -0,0 +1,68 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * media_device.h - The base class of media device handler
+ */
+
+#pragma once
+
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <linux/media.h>
+
+#include <libcamera/base/log.h>
+#include <libcamera/base/signal.h>
+#include <libcamera/base/unique_fd.h>
+
+#include "libcamera/internal/media_object.h"
+
+namespace libcamera {
+
+class MediaDeviceBase : protected Loggable
+{
+public:
+	MediaDeviceBase(const std::string &deviceNode);
+	~MediaDeviceBase();
+
+	bool acquire();
+	void release();
+	bool busy() const { return acquired_; }
+
+	virtual bool lock();
+	virtual void unlock();
+
+	virtual int populate();
+	bool isValid() const { return valid_; }
+
+	const std::string &driver() const { return driver_; }
+	const std::string &deviceNode() const { return deviceNode_; }
+
+	const std::vector<MediaEntity *> &entities() const { return entities_; }
+	MediaEntity *getEntityByName(const std::string &name) const;
+
+	Signal<> disconnected;
+
+protected:
+	std::string logPrefix() const override;
+
+	virtual int open() { return 0; }
+	virtual void close() {}
+	virtual void clear();
+
+	std::string driver_;
+	std::string deviceNode_;
+
+	bool valid_;
+	bool acquired_;
+
+	std::vector<MediaEntity *> entities_;
+
+private:
+	bool lock_;
+};
+
+} /* namespace libcamera */
diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build
index f8be86e0..826a241c 100644
--- a/include/libcamera/internal/meson.build
+++ b/include/libcamera/internal/meson.build
@@ -31,6 +31,7 @@  libcamera_internal_headers = files([
     'ipc_unixsocket.h',
     'mapped_framebuffer.h',
     'media_device.h',
+    'media_device_base.h',
     'media_object.h',
     'pipeline_handler.h',
     'process.h',
diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
index 52c8e66e..ea0525d5 100644
--- a/src/libcamera/media_device.cpp
+++ b/src/libcamera/media_device.cpp
@@ -63,63 +63,13 @@  LOG_DEFINE_CATEGORY(MediaDevice)
  * populate() before the media graph can be queried.
  */
 MediaDevice::MediaDevice(const std::string &deviceNode)
-	: deviceNode_(deviceNode), valid_(false), acquired_(false)
+	: MediaDeviceBase(deviceNode)
 {
 }
 
 MediaDevice::~MediaDevice()
 {
 	fd_.reset();
-	clear();
-}
-
-std::string MediaDevice::logPrefix() const
-{
-	return deviceNode() + "[" + driver() + "]";
-}
-
-/**
- * \brief Claim a device for exclusive use
- *
- * The device claiming mechanism offers simple media device access arbitration
- * between multiple users. When the media device is created, it is available to
- * all users. Users can query the media graph to determine whether they can
- * support the device and, if they do, claim the device for exclusive use. Other
- * users are then expected to skip over media devices in use as reported by the
- * busy() function.
- *
- * Once claimed the device shall be released by its user when not needed anymore
- * by calling the release() function. Acquiring the media device opens a file
- * descriptor to the device which is kept open until release() is called.
- *
- * Exclusive access is only guaranteed if all users of the media device abide by
- * the device claiming mechanism, as it isn't enforced by the media device
- * itself.
- *
- * \return true if the device was successfully claimed, or false if it was
- * already in use
- * \sa release(), busy()
- */
-bool MediaDevice::acquire()
-{
-	if (acquired_)
-		return false;
-
-	if (open())
-		return false;
-
-	acquired_ = true;
-	return true;
-}
-
-/**
- * \brief Release a device previously claimed for exclusive use
- * \sa acquire(), busy()
- */
-void MediaDevice::release()
-{
-	close();
-	acquired_ = false;
 }
 
 /**
@@ -290,12 +240,6 @@  done:
  * \return The name of the kernel driver that handles the MediaDevice
  */
 
-/**
- * \fn MediaDevice::deviceNode()
- * \brief Retrieve the media device node path
- * \return The MediaDevice deviceNode path
- */
-
 /**
  * \fn MediaDevice::model()
  * \brief Retrieve the media device model name
@@ -320,26 +264,6 @@  done:
  * \return The MediaDevice hardware revision
  */
 
-/**
- * \fn MediaDevice::entities()
- * \brief Retrieve the list of entities in the media graph
- * \return The list of MediaEntities registered in the MediaDevice
- */
-
-/**
- * \brief Return the MediaEntity with name \a name
- * \param[in] name The entity name
- * \return The entity with \a name, or nullptr if no such entity is found
- */
-MediaEntity *MediaDevice::getEntityByName(const std::string &name) const
-{
-	for (MediaEntity *e : entities_)
-		if (e->name() == name)
-			return e;
-
-	return nullptr;
-}
-
 /**
  * \brief Retrieve the MediaLink connecting two pads, identified by entity
  * names and pad indexes
@@ -453,16 +377,6 @@  int MediaDevice::disableLinks()
 	return 0;
 }
 
-/**
- * \var MediaDevice::disconnected
- * \brief Signal emitted when the media device is disconnected from the system
- *
- * This signal is emitted when the device enumerator detects that the media
- * device has been removed from the system. For hot-pluggable devices this is
- * usually caused by physical device disconnection, but can also result from
- * driver unloading for most devices. The media device is passed as a parameter.
- */
-
 /**
  * \brief Open the media device
  *
@@ -565,14 +479,9 @@  void MediaDevice::clear()
 		delete o.second;
 
 	objects_.clear();
-	entities_.clear();
-	valid_ = false;
-}
 
-/**
- * \var MediaDevice::entities_
- * \brief Global list of media entities in the media graph
- */
+	MediaDeviceBase::clear();
+}
 
 /**
  * \brief Find the interface associated with an entity
diff --git a/src/libcamera/media_device_base.cpp b/src/libcamera/media_device_base.cpp
new file mode 100644
index 00000000..12161d1a
--- /dev/null
+++ b/src/libcamera/media_device_base.cpp
@@ -0,0 +1,140 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * media_device_base.cpp - The base class of media device handler
+ */
+
+#include "libcamera/internal/media_device_base.h"
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(MediaDeviceBase)
+
+MediaDeviceBase::MediaDeviceBase(const std::string &deviceNode)
+	: deviceNode_(deviceNode), valid_(false), acquired_(false), lock_(false)
+{
+}
+
+MediaDeviceBase::~MediaDeviceBase()
+{
+	clear();
+}
+
+/**
+ * \brief Claim a device for exclusive use
+ *
+ * The device claiming mechanism offers simple media device access arbitration
+ * between multiple users. When the media device is created, it is available to
+ * all users. Users can query the media graph to determine whether they can
+ * support the device and, if they do, claim the device for exclusive use. Other
+ * users are then expected to skip over media devices in use as reported by the
+ * busy() function.
+ *
+ * Once claimed the device shall be released by its user when not needed anymore
+ * by calling the release() function. Acquiring the media device opens a file
+ * descriptor to the device which is kept open until release() is called.
+ *
+ * Exclusive access is only guaranteed if all users of the media device abide by
+ * the device claiming mechanism, as it isn't enforced by the media device
+ * itself.
+ *
+ * \return true if the device was successfully claimed, or false if it was
+ * already in use
+ * \sa release(), busy()
+ */
+bool MediaDeviceBase::acquire()
+{
+	if (acquired_)
+		return false;
+
+	if (open())
+		return false;
+
+	acquired_ = true;
+	return true;
+}
+
+/**
+ * \brief Release a device previously claimed for exclusive use
+ * \sa acquire(), busy()
+ */
+void MediaDeviceBase::release()
+{
+	close();
+	acquired_ = false;
+}
+
+bool MediaDeviceBase::lock()
+{
+	if (lock_)
+		return false;
+
+	lock_ = true;
+	return true;
+}
+
+void MediaDeviceBase::unlock()
+{
+	lock_ = false;
+}
+
+int MediaDeviceBase::populate()
+{
+	valid_ = true;
+	return 0;
+}
+
+/**
+ * \fn MediaDeviceBase::deviceNode()
+ * \brief Retrieve the media device node path
+ * \return The MediaDeviceBase deviceNode path
+ */
+
+/**
+ * \fn MediaDeviceBase::entities()
+ * \brief Retrieve the list of entities in the media graph
+ * \return The list of MediaEntities registered in the MediaDeviceBase
+ */
+
+/**
+ * \brief Return the MediaEntity with name \a name
+ * \param[in] name The entity name
+ * \return The entity with \a name, or nullptr if no such entity is found
+ */
+MediaEntity *MediaDeviceBase::getEntityByName(const std::string &name) const
+{
+	for (MediaEntity *e : entities_)
+		if (e->name() == name)
+			return e;
+
+	return nullptr;
+}
+
+/**
+ * \var MediaDeviceBase::disconnected
+ * \brief Signal emitted when the media device is disconnected from the system
+ *
+ * This signal is emitted when the device enumerator detects that the media
+ * device has been removed from the system. For hot-pluggable devices this is
+ * usually caused by physical device disconnection, but can also result from
+ * driver unloading for most devices. The media device is passed as a parameter.
+ */
+
+std::string MediaDeviceBase::logPrefix() const
+{
+	return deviceNode() + "[" + driver() + "]";
+}
+
+void MediaDeviceBase::clear()
+{
+	entities_.clear();
+	valid_ = false;
+}
+
+/**
+ * \var MediaDeviceBase::entities_
+ * \brief Global list of media entities in the media graph
+ */
+
+} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 0494e808..ce4c1a29 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -32,6 +32,7 @@  libcamera_sources = files([
     'ipc_unixsocket.cpp',
     'mapped_framebuffer.cpp',
     'media_device.cpp',
+    'media_device_base.cpp',
     'media_object.cpp',
     'pipeline_handler.cpp',
     'pixel_format.cpp',