Show a patch.

GET /api/1.1/patches/2701/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2701,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/2701/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/2701/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20200120002437.6633-15-laurent.pinchart@ideasonboard.com>",
    "date": "2020-01-20T00:24:32",
    "name": "[libcamera-devel,14/19] libcamera: camera: Move private data members to private implementation",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "81682f183d519f12d91e09d9f54179fa2dee7d32",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/2701/mbox/",
    "series": [
        {
            "id": 641,
            "url": "https://patchwork.libcamera.org/api/1.1/series/641/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=641",
            "date": "2020-01-20T00:24:19",
            "name": "Initial libcamera threading model",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/641/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/2701/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/2701/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<laurent.pinchart@ideasonboard.com>",
        "Received": [
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D5158607EC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 20 Jan 2020 01:24:47 +0100 (CET)",
            "from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3A4DA504\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 20 Jan 2020 01:24:47 +0100 (CET)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1579479887;\n\tbh=biG6RcQKVHJgIhFHeFwbZz0F4ULtzgUJp36cqcQg95s=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=QZ5IxpYr9xg8Zgpz7WEhpisvgqaKCTsdHf38m7VDBPkRW4HzuLtX5UArZLNFmGvap\n\tHpYTwUaUZYWAQOuFUKfULRVmk0o20g7u0kskqf5jPvPZEPyMnZO/vHscyb90XH/CEl\n\tJUe/dN2+29RD4Jjind1LhgRtGwrUJ4PClTBaX/MQ=",
        "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon, 20 Jan 2020 02:24:32 +0200",
        "Message-Id": "<20200120002437.6633-15-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.24.1",
        "In-Reply-To": "<20200120002437.6633-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20200120002437.6633-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH 14/19] libcamera: camera: Move private\n\tdata members to private implementation",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "X-List-Received-Date": "Mon, 20 Jan 2020 00:24:48 -0000"
    },
    "content": "Use the pimpl paradigm ([1]) to hide the private data members from the\nCamera class interface. This will ease maintaining ABI compatibility,\nand prepares for the implementation of the Camera class threading model.\n\nThe FrameBufferAllocator class accesses the Camera private data members\ndirectly. In order to hide them, this pattern is replaced with new\nprivate member functions in the Camera class, and the\nFrameBufferAllocator is updated accordingly.\n\n[1] https://en.cppreference.com/w/cpp/language/pimpl\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n include/libcamera/camera.h              |  28 +--\n src/libcamera/camera.cpp                | 224 +++++++++++++++---------\n src/libcamera/framebuffer_allocator.cpp |  47 ++---\n 3 files changed, 161 insertions(+), 138 deletions(-)",
    "diff": "diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\nindex 6597ade83288..c37319eda2dc 100644\n--- a/include/libcamera/camera.h\n+++ b/include/libcamera/camera.h\n@@ -98,34 +98,22 @@ public:\n \tint stop();\n \n private:\n-\tenum State {\n-\t\tCameraAvailable,\n-\t\tCameraAcquired,\n-\t\tCameraConfigured,\n-\t\tCameraRunning,\n-\t};\n-\n-\tCamera(PipelineHandler *pipe, const std::string &name);\n+\tCamera(PipelineHandler *pipe, const std::string &name,\n+\t       const std::set<Stream *> &streams);\n \t~Camera();\n \n-\tbool stateBetween(State low, State high) const;\n-\tbool stateIs(State state) const;\n+\tclass Private;\n+\tstd::unique_ptr<Private> p_;\n \n \tfriend class PipelineHandler;\n \tvoid disconnect();\n-\n \tvoid requestComplete(Request *request);\n \n-\tstd::shared_ptr<PipelineHandler> pipe_;\n-\tstd::string name_;\n-\tstd::set<Stream *> streams_;\n-\tstd::set<Stream *> activeStreams_;\n-\n-\tbool disconnected_;\n-\tState state_;\n-\n-\t/* Needed to update allocator_ and to read state_ and activeStreams_. */\n \tfriend class FrameBufferAllocator;\n+\tint exportFrameBuffers(Stream *stream,\n+\t\t\t       std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n+\tint freeFrameBuffers(Stream *stream);\n+\t/* \\todo Remove allocator_ from the exposed API */\n \tFrameBufferAllocator *allocator_;\n };\n \ndiff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\nindex 3385c08778b8..6fe802f375a3 100644\n--- a/src/libcamera/camera.cpp\n+++ b/src/libcamera/camera.cpp\n@@ -254,6 +254,75 @@ std::size_t CameraConfiguration::size() const\n  * \\brief The vector of stream configurations\n  */\n \n+class Camera::Private\n+{\n+public:\n+\tenum State {\n+\t\tCameraAvailable,\n+\t\tCameraAcquired,\n+\t\tCameraConfigured,\n+\t\tCameraRunning,\n+\t};\n+\n+\tPrivate(PipelineHandler *pipe, const std::string &name,\n+\t\tconst std::set<Stream *> &streams);\n+\n+\tbool stateBetween(State low, State high) const;\n+\tbool stateIs(State state) const;\n+\n+\tstd::shared_ptr<PipelineHandler> pipe_;\n+\tstd::string name_;\n+\tstd::set<Stream *> streams_;\n+\tstd::set<Stream *> activeStreams_;\n+\n+\tbool disconnected_;\n+\tState state_;\n+};\n+\n+Camera::Private::Private(PipelineHandler *pipe, const std::string &name,\n+\t\t\t const std::set<Stream *> &streams)\n+\t: pipe_(pipe->shared_from_this()), name_(name), streams_(streams),\n+\t  disconnected_(false), state_(CameraAvailable)\n+{\n+}\n+\n+static constexpr std::array<const char *, 4> camera_state_names = {\n+\t\"Available\",\n+\t\"Acquired\",\n+\t\"Configured\",\n+\t\"Running\",\n+};\n+\n+bool Camera::Private::stateBetween(State low, State high) const\n+{\n+\tif (state_ >= low && state_ <= high)\n+\t\treturn true;\n+\n+\tASSERT(static_cast<unsigned int>(low) < camera_state_names.size() &&\n+\t       static_cast<unsigned int>(high) < camera_state_names.size());\n+\n+\tLOG(Camera, Debug) << \"Camera in \" << camera_state_names[state_]\n+\t\t\t   << \" state trying operation requiring state between \"\n+\t\t\t   << camera_state_names[low] << \" and \"\n+\t\t\t   << camera_state_names[high];\n+\n+\treturn false;\n+}\n+\n+bool Camera::Private::stateIs(State state) const\n+{\n+\tif (state_ == state)\n+\t\treturn true;\n+\n+\tASSERT(static_cast<unsigned int>(state) < camera_state_names.size());\n+\n+\tLOG(Camera, Debug) << \"Camera in \" << camera_state_names[state_]\n+\t\t\t   << \" state trying operation requiring state \"\n+\t\t\t   << camera_state_names[state];\n+\n+\treturn false;\n+}\n+\n /**\n  * \\class Camera\n  * \\brief Camera device\n@@ -354,8 +423,7 @@ std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,\n \t\t}\n \t};\n \n-\tCamera *camera = new Camera(pipe, name);\n-\tcamera->streams_ = streams;\n+\tCamera *camera = new Camera(pipe, name, streams);\n \n \treturn std::shared_ptr<Camera>(camera, Deleter());\n }\n@@ -366,7 +434,7 @@ std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,\n  */\n const std::string &Camera::name() const\n {\n-\treturn name_;\n+\treturn p_->name_;\n }\n \n /**\n@@ -392,55 +460,18 @@ const std::string &Camera::name() const\n  * application API calls by returning errors immediately.\n  */\n \n-Camera::Camera(PipelineHandler *pipe, const std::string &name)\n-\t: pipe_(pipe->shared_from_this()), name_(name), disconnected_(false),\n-\t  state_(CameraAvailable), allocator_(nullptr)\n+Camera::Camera(PipelineHandler *pipe, const std::string &name,\n+\t       const std::set<Stream *> &streams)\n+\t: p_(new Private(pipe, name, streams)), allocator_(nullptr)\n {\n }\n \n Camera::~Camera()\n {\n-\tif (!stateIs(CameraAvailable))\n+\tif (!p_->stateIs(Private::CameraAvailable))\n \t\tLOG(Camera, Error) << \"Removing camera while still in use\";\n }\n \n-static constexpr std::array<const char *, 4> camera_state_names = {\n-\t\"Available\",\n-\t\"Acquired\",\n-\t\"Configured\",\n-\t\"Running\",\n-};\n-\n-bool Camera::stateBetween(State low, State high) const\n-{\n-\tif (state_ >= low && state_ <= high)\n-\t\treturn true;\n-\n-\tASSERT(static_cast<unsigned int>(low) < camera_state_names.size() &&\n-\t       static_cast<unsigned int>(high) < camera_state_names.size());\n-\n-\tLOG(Camera, Debug) << \"Camera in \" << camera_state_names[state_]\n-\t\t\t   << \" state trying operation requiring state between \"\n-\t\t\t   << camera_state_names[low] << \" and \"\n-\t\t\t   << camera_state_names[high];\n-\n-\treturn false;\n-}\n-\n-bool Camera::stateIs(State state) const\n-{\n-\tif (state_ == state)\n-\t\treturn true;\n-\n-\tASSERT(static_cast<unsigned int>(state) < camera_state_names.size());\n-\n-\tLOG(Camera, Debug) << \"Camera in \" << camera_state_names[state_]\n-\t\t\t   << \" state trying operation requiring state \"\n-\t\t\t   << camera_state_names[state];\n-\n-\treturn false;\n-}\n-\n /**\n  * \\brief Notify camera disconnection\n  *\n@@ -455,20 +486,45 @@ bool Camera::stateIs(State state) const\n  */\n void Camera::disconnect()\n {\n-\tLOG(Camera, Debug) << \"Disconnecting camera \" << name_;\n+\tLOG(Camera, Debug) << \"Disconnecting camera \" << name();\n \n \t/*\n \t * If the camera was running when the hardware was removed force the\n \t * state to Configured state to allow applications to free resources\n \t * and call release() before deleting the camera.\n \t */\n-\tif (state_ == CameraRunning)\n-\t\tstate_ = CameraConfigured;\n+\tif (p_->state_ == Private::CameraRunning)\n+\t\tp_->state_ = Private::CameraConfigured;\n \n-\tdisconnected_ = true;\n+\tp_->disconnected_ = true;\n \tdisconnected.emit(this);\n }\n \n+int Camera::exportFrameBuffers(Stream *stream,\n+\t\t\t       std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n+{\n+\tif (!p_->stateIs(Private::CameraConfigured))\n+\t\treturn -EACCES;\n+\n+\tif (streams().find(stream) == streams().end())\n+\t\treturn -EINVAL;\n+\n+\tif (p_->activeStreams_.find(stream) == p_->activeStreams_.end())\n+\t\treturn -EINVAL;\n+\n+\treturn p_->pipe_->exportFrameBuffers(this, stream, buffers);\n+}\n+\n+int Camera::freeFrameBuffers(Stream *stream)\n+{\n+\tif (!p_->stateIs(Private::CameraConfigured))\n+\t\treturn -EACCES;\n+\n+\tp_->pipe_->freeFrameBuffers(this, stream);\n+\n+\treturn 0;\n+}\n+\n /**\n  * \\brief Acquire the camera device for exclusive access\n  *\n@@ -494,19 +550,19 @@ void Camera::disconnect()\n  */\n int Camera::acquire()\n {\n-\tif (disconnected_)\n+\tif (p_->disconnected_)\n \t\treturn -ENODEV;\n \n-\tif (!stateIs(CameraAvailable))\n+\tif (!p_->stateIs(Private::CameraAvailable))\n \t\treturn -EBUSY;\n \n-\tif (!pipe_->lock()) {\n+\tif (!p_->pipe_->lock()) {\n \t\tLOG(Camera, Info)\n \t\t\t<< \"Pipeline handler in use by another process\";\n \t\treturn -EBUSY;\n \t}\n \n-\tstate_ = CameraAcquired;\n+\tp_->state_ = Private::CameraAcquired;\n \n \treturn 0;\n }\n@@ -524,7 +580,8 @@ int Camera::acquire()\n  */\n int Camera::release()\n {\n-\tif (!stateBetween(CameraAvailable, CameraConfigured))\n+\tif (!p_->stateBetween(Private::CameraAvailable,\n+\t\t\t      Private::CameraConfigured))\n \t\treturn -EBUSY;\n \n \tif (allocator_) {\n@@ -537,9 +594,9 @@ int Camera::release()\n \t\treturn -EBUSY;\n \t}\n \n-\tpipe_->unlock();\n+\tp_->pipe_->unlock();\n \n-\tstate_ = CameraAvailable;\n+\tp_->state_ = Private::CameraAvailable;\n \n \treturn 0;\n }\n@@ -553,7 +610,7 @@ int Camera::release()\n  */\n const ControlInfoMap &Camera::controls()\n {\n-\treturn pipe_->controls(this);\n+\treturn p_->pipe_->controls(this);\n }\n \n /**\n@@ -567,7 +624,7 @@ const ControlInfoMap &Camera::controls()\n  */\n const std::set<Stream *> &Camera::streams() const\n {\n-\treturn streams_;\n+\treturn p_->streams_;\n }\n \n /**\n@@ -586,10 +643,10 @@ const std::set<Stream *> &Camera::streams() const\n  */\n std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamRoles &roles)\n {\n-\tif (disconnected_ || roles.size() > streams_.size())\n+\tif (p_->disconnected_ || roles.size() > streams().size())\n \t\treturn nullptr;\n \n-\tCameraConfiguration *config = pipe_->generateConfiguration(this, roles);\n+\tCameraConfiguration *config = p_->pipe_->generateConfiguration(this, roles);\n \tif (!config) {\n \t\tLOG(Camera, Debug)\n \t\t\t<< \"Pipeline handler failed to generate configuration\";\n@@ -639,10 +696,11 @@ int Camera::configure(CameraConfiguration *config)\n {\n \tint ret;\n \n-\tif (disconnected_)\n+\tif (p_->disconnected_)\n \t\treturn -ENODEV;\n \n-\tif (!stateBetween(CameraAcquired, CameraConfigured))\n+\tif (!p_->stateBetween(Private::CameraAcquired,\n+\t\t\t      Private::CameraConfigured))\n \t\treturn -EACCES;\n \n \tif (allocator_ && allocator_->allocated()) {\n@@ -667,11 +725,11 @@ int Camera::configure(CameraConfiguration *config)\n \n \tLOG(Camera, Info) << msg.str();\n \n-\tret = pipe_->configure(this, config);\n+\tret = p_->pipe_->configure(this, config);\n \tif (ret)\n \t\treturn ret;\n \n-\tactiveStreams_.clear();\n+\tp_->activeStreams_.clear();\n \tfor (const StreamConfiguration &cfg : *config) {\n \t\tStream *stream = cfg.stream();\n \t\tif (!stream)\n@@ -679,10 +737,10 @@ int Camera::configure(CameraConfiguration *config)\n \t\t\t\t<< \"Pipeline handler failed to update stream configuration\";\n \n \t\tstream->configuration_ = cfg;\n-\t\tactiveStreams_.insert(stream);\n+\t\tp_->activeStreams_.insert(stream);\n \t}\n \n-\tstate_ = CameraConfigured;\n+\tp_->state_ = Private::CameraConfigured;\n \n \treturn 0;\n }\n@@ -709,7 +767,9 @@ int Camera::configure(CameraConfiguration *config)\n  */\n Request *Camera::createRequest(uint64_t cookie)\n {\n-\tif (disconnected_ || !stateBetween(CameraConfigured, CameraRunning))\n+\tif (p_->disconnected_ ||\n+\t    !p_->stateBetween(Private::CameraConfigured,\n+\t\t\t      Private::CameraRunning))\n \t\treturn nullptr;\n \n \treturn new Request(this, cookie);\n@@ -739,10 +799,10 @@ Request *Camera::createRequest(uint64_t cookie)\n  */\n int Camera::queueRequest(Request *request)\n {\n-\tif (disconnected_)\n+\tif (p_->disconnected_)\n \t\treturn -ENODEV;\n \n-\tif (!stateIs(CameraRunning))\n+\tif (!p_->stateIs(Private::CameraRunning))\n \t\treturn -EACCES;\n \n \tif (request->buffers().empty()) {\n@@ -753,13 +813,13 @@ int Camera::queueRequest(Request *request)\n \tfor (auto const &it : request->buffers()) {\n \t\tStream *stream = it.first;\n \n-\t\tif (activeStreams_.find(stream) == activeStreams_.end()) {\n+\t\tif (p_->activeStreams_.find(stream) == p_->activeStreams_.end()) {\n \t\t\tLOG(Camera, Error) << \"Invalid request\";\n \t\t\treturn -EINVAL;\n \t\t}\n \t}\n \n-\treturn pipe_->queueRequest(this, request);\n+\treturn p_->pipe_->queueRequest(this, request);\n }\n \n /**\n@@ -777,26 +837,26 @@ int Camera::queueRequest(Request *request)\n  */\n int Camera::start()\n {\n-\tif (disconnected_)\n+\tif (p_->disconnected_)\n \t\treturn -ENODEV;\n \n-\tif (!stateIs(CameraConfigured))\n+\tif (!p_->stateIs(Private::CameraConfigured))\n \t\treturn -EACCES;\n \n \tLOG(Camera, Debug) << \"Starting capture\";\n \n-\tfor (Stream *stream : activeStreams_) {\n+\tfor (Stream *stream : p_->activeStreams_) {\n \t\tif (allocator_ && !allocator_->buffers(stream).empty())\n \t\t\tcontinue;\n \n-\t\tpipe_->importFrameBuffers(this, stream);\n+\t\tp_->pipe_->importFrameBuffers(this, stream);\n \t}\n \n-\tint ret = pipe_->start(this);\n+\tint ret = p_->pipe_->start(this);\n \tif (ret)\n \t\treturn ret;\n \n-\tstate_ = CameraRunning;\n+\tp_->state_ = Private::CameraRunning;\n \n \treturn 0;\n }\n@@ -815,23 +875,23 @@ int Camera::start()\n  */\n int Camera::stop()\n {\n-\tif (disconnected_)\n+\tif (p_->disconnected_)\n \t\treturn -ENODEV;\n \n-\tif (!stateIs(CameraRunning))\n+\tif (!p_->stateIs(Private::CameraRunning))\n \t\treturn -EACCES;\n \n \tLOG(Camera, Debug) << \"Stopping capture\";\n \n-\tstate_ = CameraConfigured;\n+\tp_->state_ = Private::CameraConfigured;\n \n-\tpipe_->stop(this);\n+\tp_->pipe_->stop(this);\n \n-\tfor (Stream *stream : activeStreams_) {\n+\tfor (Stream *stream : p_->activeStreams_) {\n \t\tif (allocator_ && !allocator_->buffers(stream).empty())\n \t\t\tcontinue;\n \n-\t\tpipe_->freeFrameBuffers(this, stream);\n+\t\tp_->pipe_->freeFrameBuffers(this, stream);\n \t}\n \n \treturn 0;\ndiff --git a/src/libcamera/framebuffer_allocator.cpp b/src/libcamera/framebuffer_allocator.cpp\nindex a7588c7fe4c2..4f442d0d92e7 100644\n--- a/src/libcamera/framebuffer_allocator.cpp\n+++ b/src/libcamera/framebuffer_allocator.cpp\n@@ -89,7 +89,7 @@ FrameBufferAllocator::~FrameBufferAllocator()\n {\n \tfor (auto &value : buffers_) {\n \t\tStream *stream = value.first;\n-\t\tcamera_->pipe_->freeFrameBuffers(camera_.get(), stream);\n+\t\tcamera_->freeFrameBuffers(stream);\n \t}\n \n \tbuffers_.clear();\n@@ -116,36 +116,17 @@ FrameBufferAllocator::~FrameBufferAllocator()\n  */\n int FrameBufferAllocator::allocate(Stream *stream)\n {\n-\tif (camera_->state_ != Camera::CameraConfigured) {\n-\t\tLOG(Allocator, Error)\n-\t\t\t<< \"Camera must be in the configured state to allocate buffers\";\n-\t\treturn -EACCES;\n-\t}\n-\n-\tif (camera_->streams().find(stream) == camera_->streams().end()) {\n-\t\tLOG(Allocator, Error)\n-\t\t\t<< \"Stream does not belong to \" << camera_->name();\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tif (camera_->activeStreams_.find(stream) == camera_->activeStreams_.end()) {\n-\t\tLOG(Allocator, Error)\n-\t\t\t<< \"Stream is not part of \" << camera_->name()\n-\t\t\t<< \" active configuration\";\n-\t\treturn -EINVAL;\n-\t}\n-\n \tif (buffers_.count(stream)) {\n \t\tLOG(Allocator, Error) << \"Buffers already allocated for stream\";\n \t\treturn -EBUSY;\n \t}\n \n-\tint ret = camera_->pipe_->exportFrameBuffers(camera_.get(), stream,\n-\t\t\t\t\t\t     &buffers_[stream]);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\treturn 0;\n+\tint ret = camera_->exportFrameBuffers(stream, &buffers_[stream]);\n+\tif (ret == -EINVAL)\n+\t\tLOG(Allocator, Error)\n+\t\t\t<< \"Stream is not part of \" << camera_->name()\n+\t\t\t<< \" active configuration\";\n+\treturn ret;\n }\n \n /**\n@@ -162,22 +143,16 @@ int FrameBufferAllocator::allocate(Stream *stream)\n  */\n int FrameBufferAllocator::free(Stream *stream)\n {\n-\tif (camera_->state_ != Camera::CameraConfigured) {\n-\t\tLOG(Allocator, Error)\n-\t\t\t<< \"Camera must be in the configured state to free buffers\";\n-\t\treturn -EACCES;\n-\t}\n-\n \tauto iter = buffers_.find(stream);\n \tif (iter == buffers_.end())\n \t\treturn -EINVAL;\n \n-\tstd::vector<std::unique_ptr<FrameBuffer>> &buffers = iter->second;\n+\tint ret = camera_->freeFrameBuffers(stream);\n+\tif (ret < 0)\n+\t\treturn ret;\n \n+\tstd::vector<std::unique_ptr<FrameBuffer>> &buffers = iter->second;\n \tbuffers.clear();\n-\n-\tcamera_->pipe_->freeFrameBuffers(camera_.get(), stream);\n-\n \tbuffers_.erase(iter);\n \n \treturn 0;\n",
    "prefixes": [
        "libcamera-devel",
        "14/19"
    ]
}