diff --git a/0001-multiple-cam-demo-Changes-on-top-of-working-PW-and-W.patch b/0001-multiple-cam-demo-Changes-on-top-of-working-PW-and-W.patch
deleted file mode 100644
index f316b7aae67aca1223fbf2de949e58d0442d6223..0000000000000000000000000000000000000000
--- a/0001-multiple-cam-demo-Changes-on-top-of-working-PW-and-W.patch
+++ /dev/null
@@ -1,542 +0,0 @@
-From e71c2cef383ccafa40ef5fd88a3bca9bda128118 Mon Sep 17 00:00:00 2001
-From: Ashok Sidipotu <ashok.sidipotu@collabora.com>
-Date: Fri, 29 Oct 2021 13:55:07 +0530
-Subject: [PATCH] multiple cam demo: Changes on top of working PW and WP
-
-- PW version: 0.3.36
-- WP version: 0.4.3
----
- src/config/wireplumber.conf   |  18 ++++-
- src/scripts/alsa-minimal.lua  |  48 ++++++++++++
- src/scripts/policy-access.lua |  34 ++++++++
- src/scripts/policy-item.lua   |  97 +++++++++++++++++++++++
- src/scripts/policy-link.lua   | 142 ++++++++++++++++++++++++++++++++++
- src/scripts/v4l2.lua          | 139 +++++++++++++++++++++++++++++++++
- 6 files changed, 475 insertions(+), 3 deletions(-)
- create mode 100644 src/scripts/alsa-minimal.lua
- create mode 100644 src/scripts/policy-access.lua
- create mode 100644 src/scripts/policy-item.lua
- create mode 100644 src/scripts/policy-link.lua
- create mode 100644 src/scripts/v4l2.lua
-
-diff --git a/src/config/wireplumber.conf b/src/config/wireplumber.conf
-index 0ac65c7..e411a08 100644
---- a/src/config/wireplumber.conf
-+++ b/src/config/wireplumber.conf
-@@ -73,7 +73,19 @@ wireplumber.components = [
- 
-   # The lua configuration file(s)
-   # Other components are loaded from there
--  { name = main.lua, type = config/lua }
--  { name = policy.lua, type = config/lua }
--  { name = bluetooth.lua, type = config/lua }
-+  # { name = main.lua, type = config/lua }
-+  # { name = policy.lua, type = config/lua }
-+  # { name = bluetooth.lua, type = config/lua }
-+  # { name = policy-access.lua, type = script/lua }
-+
-+  # demo
-+  { name = policy-access.lua, type = script/lua }
-+  { name = libwireplumber-module-si-audio-adapter, type = module }
-+  { name = libwireplumber-module-si-node, type = module }
-+  { name = policy-item.lua, type = script/lua }
-+  { name = libwireplumber-module-si-standard-link, type = module }
-+  { name = policy-link.lua, type = script/lua }
-+  { name = alsa-minimal.lua, type = script/lua }
-+  { name = v4l2.lua, type = script/lua }
- ]
-+
-diff --git a/src/scripts/alsa-minimal.lua b/src/scripts/alsa-minimal.lua
-new file mode 100644
-index 0000000..93f0574
---- /dev/null
-+++ b/src/scripts/alsa-minimal.lua
-@@ -0,0 +1,48 @@
-+function createDevice(parent, id, type, factory, properties)
-+  -- set device name
-+  properties["device.name"] = "alsa_card." .. properties["device.bus-path"]
-+
-+  -- set device description (user-friendly name)
-+  properties["device.description"] = properties["device.product.name"]
-+
-+  Log.info("dev name="..properties["device.name"].."dev descp"..properties["device.description"].."factory is"..factory)
-+  local device = SpaDevice(factory, properties)
-+  device:connect("create-object", createNode)
-+  device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND)
-+  parent:store_managed_object(id, device)
-+end
-+
-+function createNode(parent, id, type, factory, properties)
-+  -- setup node properties
-+  properties["device.id"] = parent["bound-id"]
-+  properties["factory.name"] = factory
-+
-+  local device_properties = parent.properties
-+
-+  local dev = properties["api.alsa.pcm.device"]
-+  local subdev = properties["api.alsa.pcm.subdevice"]
-+  local stream = properties["api.alsa.pcm.stream"]
-+
-+  -- set node name
-+  properties["node.name"] =
-+      (stream == "capture" and "alsa_input" or "alsa_output")
-+      .. "." ..
-+      (device_properties["device.name"]:gsub("^alsa_card%.(.+)", "%1") or
-+       device_properties["device.name"] or
-+       "unnamed-device")
-+      .. "." ..
-+      (properties["device.profile.name"] or
-+       (stream .. "." .. dev .. "." .. subdev))
-+
-+  -- set node description
-+  properties["node.description"] = device_properties["device.description"]
-+
-+  -- create the node
-+  local node = Node("adapter", properties)
-+  node:activate(Feature.Proxy.BOUND)
-+  parent:store_managed_object(id, node)
-+end
-+
-+monitor = SpaDevice("api.alsa.enum.udev", {})
-+monitor:connect("create-object", createDevice)
-+monitor:activate(Feature.SpaDevice.ENABLED)
-diff --git a/src/scripts/policy-access.lua b/src/scripts/policy-access.lua
-new file mode 100644
-index 0000000..ec8bcba
---- /dev/null
-+++ b/src/scripts/policy-access.lua
-@@ -0,0 +1,34 @@
-+clients_om = ObjectManager {
-+  Interest { type = "client" }
-+}
-+
-+fact_om = ObjectManager {
-+  Interest { type = "factory"}
-+}
-+
-+clients_om:connect("object-added", function(om, client)
-+    local id = client["bound-id"]
-+    local properties = client["properties"]
-+
-+    if properties["application.process.host"] == Core.get_info()["host_name"] then
-+        -- Local client added grant full access
-+        client:update_permissions { ["any"] = "rwxm" }
-+      else
-+        Log.info(client, "remote client added"..tostring(client))
-+        -- first grant access to pw core
-+        client:update_permissions { [0] = "rwxm" }
-+
-+        -- second grant access to client node factory, so that a stream node can be created.
-+        local cnf = fact_om:lookup { Constraint { "factory.name", "matches", "client-node", type = "pw-global" }, }
-+        if not cnf then
-+          Log.warning("access cannot be granted: unable to locate client node factory object");
-+          return
-+        end
-+
-+        Log.info(cnf, "client node factory id ".. cnf["bound-id"])
-+        client:update_permissions { [cnf["bound-id"]] = "rwxm" }
-+      end
-+end)
-+
-+fact_om:activate()
-+clients_om:activate()
-diff --git a/src/scripts/policy-item.lua b/src/scripts/policy-item.lua
-new file mode 100644
-index 0000000..d3e6a7b
---- /dev/null
-+++ b/src/scripts/policy-item.lua
-@@ -0,0 +1,97 @@
-+items = {}
-+
-+remote_client_media_role = "Stream/Input/Video"
-+
-+clients_om = ObjectManager {
-+  Interest { type = "client" }
-+}
-+
-+function isNodeFromRemoteClient(node)
-+  local np = node.properties
-+  local media_class = np["media.class"]
-+  Log.info(node, "id is "..node["bound-id"].." and its media.class is "..media_class);
-+
-+  if(string.find(media_class,"Stream")) then
-+    local client_id = np["client.id"]
-+    local client = clients_om:lookup { Constraint { "bound-id", "=", client_id, type = "gobject" }, }
-+    Log.info("client id is "..client_id.. tostring(client));
-+    local cp = client["properties"]
-+    if cp["application.process.host"] ~= Core.get_info()["host_name"] then
-+      return true
-+    end
-+  end    
-+end
-+
-+function addItem (node, item_type)
-+  local id = node["bound-id"]
-+  local media_class = node.properties["media.class"]
-+  
-+  if isNodeFromRemoteClient(node) then
-+    if media_class ~= remote_client_media_role then
-+      Log.warning("remote client doesnt have priviledge to create session item");
-+      return
-+    end
-+  end
-+
-+  -- create item
-+  items[id] = SessionItem ( item_type )
-+
-+  if not items[id] then
-+    Log.warning("failed to create session item for node " .. tostring(id))
-+    return
-+  end
-+
-+  -- configure item
-+  if not items[id]:configure {
-+      ["item.node"] = node,
-+      ["media.class"] = node.properties["media.class"],
-+  } then
-+    Log.warning(items[id], "failed to configure item for node " .. tostring(id))
-+    return
-+  end
-+
-+  -- activate item
-+  items[id]:activate (Features.ALL, function(item)
-+    Log.info(item, "activated item for node " .. tostring(id))
-+    item:register()
-+  end)
-+end
-+
-+nodes_om = ObjectManager {
-+  Interest {
-+    type = "node",
-+    Constraint { "media.class", "#", "Stream/*", type = "pw-global" },
-+  },
-+  Interest {
-+    type = "node",
-+    Constraint { "media.class", "#", "Video/*", type = "pw-global" },
-+  },
-+  Interest {
-+    type = "node",
-+    Constraint { "media.class", "#", "Audio/*", type = "pw-global" },
-+    -- Constraint { "wireplumber.is-endpoint", "-", type = "pw" },
-+  },
-+}
-+
-+nodes_om:connect("object-added", function(om, node)
-+  local media_class = node.properties['media.class']
-+  Log.info(node,"object-added " .. media_class)
-+  if string.find (media_class, "Audio") then
-+    addItem(node, "si-audio-adapter")
-+  else
-+    addItem(node, "si-node")
-+  end
-+end)
-+
-+nodes_om:connect("object-removed", function(om, node)
-+  local id = node["bound-id"]
-+  if items[id] then
-+    -- remove item from the global registry
-+    items[id]:remove()
-+    -- remove item from the local table
-+    items[id] = nil
-+  end
-+end)
-+
-+nodes_om:activate()
-+clients_om:activate()
-\ No newline at end of file
-diff --git a/src/scripts/policy-link.lua b/src/scripts/policy-link.lua
-new file mode 100644
-index 0000000..ac46d7f
---- /dev/null
-+++ b/src/scripts/policy-link.lua
-@@ -0,0 +1,142 @@
-+linkables_om = ObjectManager {
-+  Interest {
-+    type = "SiLinkable",
-+    Constraint { "item.factory.name", "c", "si-audio-adapter", "si-node", type = "pw-global" },
-+  },
-+}
-+
-+links_om = ObjectManager {
-+  Interest {
-+    type = "SiLink",
-+  }
-+}
-+
-+function findTarget(node)
-+  local target_class_assoc = {
-+    ["Stream/Input/Audio"] = "Audio/Source",
-+    ["Stream/Output/Audio"] = "Audio/Sink",
-+    ["Stream/Input/Video"] = "Video/Source",
-+  }
-+
-+  local target_media_class = target_class_assoc[node.properties["media.class"]]
-+
-+-- check if node.target(camera preference) is set
-+  local node_target = node.properties["node.target"]
-+  if node_target then
-+    Log.info(node,"node.target is set to "..node_target)
-+    local node_target_found;
-+    
-+    for si in linkables_om:iterate() do
-+      local node = si:get_associated_proxy("node")
-+      Log.info(si,"node="..tostring(node).."node bound.id="..node["bound-id"])  
-+
-+      if tostring(node["bound-id"]) == tostring(node_target) then
-+        node_target_found = true;
-+        Log.info(node,"node.target found")
-+        return si
-+      end
-+
-+    end
-+    if not node_target_found then
-+      Log.info(node, "node.target="..node_target.." seems to be invalid"..
-+        "are you sure it points to right cam source node?")
-+    end
-+  end
-+
-+-- pick any available cam source as no explicit preferece is set.
-+  for si in linkables_om:iterate() do
-+    local node = si:get_associated_proxy("node")
-+    if node.properties["media.class"] == target_media_class then
-+      return si
-+    end
-+  end
-+  return nil
-+end
-+
-+function createLink(item, target)
-+  local node = item:get_associated_proxy ("node")
-+  local target_node = target:get_associated_proxy ("node")
-+  local media_class = node.properties["media.class"]
-+  local target_media_class = target_node.properties["media.class"]
-+  local out_item = nil
-+  local in_item = nil
-+
-+  if string.find (media_class, "Input") or
-+     string.find (media_class, "Sink") then
-+    -- capture
-+    out_item = target
-+    in_item = item
-+  else
-+    -- playback
-+    out_item = item
-+    in_item = target
-+  end
-+
-+  Log.info (string.format("link %s(%d) <-> %s(%d)",
-+      tostring(node.properties["node.name"]),
-+      node["bound-id"],
-+      tostring(target_node.properties["node.name"]),
-+      target_node["bound-id"]))
-+
-+  -- create and configure link
-+  local link = SessionItem("si-standard-link")
-+  if not link:configure {
-+    ["out.item"] = out_item,
-+    ["in.item"] = in_item,
-+    ["out.item.port.context"] = "output",
-+    ["in.item.port.context"] = "input",
-+  } then
-+    Log.warning(link, "failed to configure si-standard-link")
-+    return
-+  end
-+
-+  -- register & activate
-+  link:register()
-+  link:activate(Feature.SessionItem.ACTIVE, function (l, e)
-+    if e ~= nil then
-+      Log.warning (l, "failed to activate si-standard-link")
-+      link:remove ()
-+    else
-+      Log.info (l, "activated si-standard-link")
-+    end
-+  end)
-+end
-+
-+linkables_om:connect("object-added", function(om, item)
-+  -- only handle session items that has a node associated proxy
-+  local node = item:get_associated_proxy("node")
-+  local media_class = node.properties["media.class"]
-+  Log.info (node, "handling linkable item " .. tostring(node.properties["node.name"]))
-+
-+  -- check all the links to see if the item is already linked
-+  for link in links_om:iterate() do
-+    local out_id = tonumber(link.properties["out.item.id"])
-+    local in_id = tonumber(link.properties["in.item.id"])
-+    if out_id == item.id or in_id == item.id then
-+      -- already linked, nothing to do
-+      return
-+    end
-+  end
-+
-+  local target = findTarget(node)
-+  if target then
-+    createLink(item, target)
-+  else
-+    Log.info("unable to findTarget for "..tostring(node));
-+  end
-+end)
-+
-+linkables_om:connect("object-removed", function(om, item)
-+  -- remove any links associated with this item
-+  for link in links_om:iterate() do
-+    local out_id = tonumber (link.properties["out.item.id"])
-+    local in_id = tonumber (link.properties["in.item.id"])
-+    if out_id == item.id or in_id == item.id then
-+      link:remove ()
-+      Log.info(link, "link removed")
-+    end
-+  end
-+end)
-+
-+links_om:activate()
-+linkables_om:activate()
-diff --git a/src/scripts/v4l2.lua b/src/scripts/v4l2.lua
-new file mode 100644
-index 0000000..fd9a20d
---- /dev/null
-+++ b/src/scripts/v4l2.lua
-@@ -0,0 +1,139 @@
-+-- WirePlumber
-+--
-+-- Copyright © 2021 Collabora Ltd.
-+--    @author George Kiagiadakis <george.kiagiadakis@collabora.com>
-+--
-+-- SPDX-License-Identifier: MIT
-+
-+local config = ... or {}
-+
-+-- preprocess rules and create Interest objects
-+for _, r in ipairs(config.rules or {}) do
-+  r.interests = {}
-+  for _, i in ipairs(r.matches) do
-+    local interest_desc = { type = "properties" }
-+    for _, c in ipairs(i) do
-+      c.type = "pw"
-+      table.insert(interest_desc, Constraint(c))
-+    end
-+    local interest = Interest(interest_desc)
-+    table.insert(r.interests, interest)
-+  end
-+  r.matches = nil
-+end
-+
-+-- applies properties from config.rules when asked to
-+function rulesApplyProperties(properties)
-+  for _, r in ipairs(config.rules or {}) do
-+    if r.apply_properties then
-+      for _, interest in ipairs(r.interests) do
-+        if interest:matches(properties) then
-+          for k, v in pairs(r.apply_properties) do
-+            properties[k] = v
-+          end
-+        end
-+      end
-+    end
-+  end
-+end
-+
-+function findDuplicate(parent, id, property, value)
-+  for i = 0, id - 1, 1 do
-+    local obj = parent:get_managed_object(i)
-+    if obj and obj.properties[property] == value then
-+      return true
-+    end
-+  end
-+  return false
-+end
-+
-+function createNode(parent, id, type, factory, properties)
-+  local dev_props = parent.properties
-+
-+  -- set the device id and spa factory name; REQUIRED, do not change
-+  properties["device.id"] = parent["bound-id"]
-+  properties["factory.name"] = factory
-+
-+  -- set the default pause-on-idle setting
-+  properties["node.pause-on-idle"] = false
-+
-+  -- set the node name
-+  local name =
-+      (factory:find("sink") and "v4l2_output") or
-+       (factory:find("source") and "v4l2_input" or factory)
-+      .. "." ..
-+      (dev_props["device.name"]:gsub("^v4l2_device%.(.+)", "%1") or
-+       dev_props["device.name"] or
-+       dev_props["device.nick"] or
-+       dev_props["device.alias"] or
-+       "v4l2-device")
-+  -- sanitize name
-+  name = name:gsub("([^%w_%-%.])", "_")
-+
-+  properties["node.name"] = name
-+
-+  -- deduplicate nodes with the same name
-+  for counter = 2, 99, 1 do
-+    if findDuplicate(parent, id, "node.name", properties["node.name"]) then
-+      properties["node.name"] = name .. "." .. counter
-+    else
-+      break
-+    end
-+  end
-+
-+  -- set the node description
-+  local desc = dev_props["device.description"] or "v4l2-device"
-+  -- sanitize description, replace ':' with ' '
-+  properties["node.description"] = desc:gsub("(:)", " ")
-+
-+  -- apply properties from config.rules
-+  rulesApplyProperties(properties)
-+
-+  -- create the node
-+  local node = Node("spa-node-factory", properties)
-+  node:activate(Feature.Proxy.BOUND)
-+  parent:store_managed_object(id, node)
-+end
-+
-+function createDevice(parent, id, type, factory, properties)
-+  -- ensure the device has an appropriate name
-+  local name = "v4l2_device." ..
-+      (properties["device.name"] or
-+       properties["device.bus-id"] or
-+       properties["device.bus-path"] or
-+       tostring(id)):gsub("([^%w_%-%.])", "_")
-+
-+  properties["device.name"] = name
-+
-+  -- deduplicate devices with the same name
-+  for counter = 2, 99, 1 do
-+    if findDuplicate(parent, id, "device.name", properties["device.name"]) then
-+      properties["device.name"] = name .. "." .. counter
-+    else
-+      break
-+    end
-+  end
-+
-+  -- ensure the device has a description
-+  properties["device.description"] =
-+      properties["device.description"]
-+      or properties["device.product.name"]
-+      or "Unknown device"
-+
-+  -- apply properties from config.rules
-+  rulesApplyProperties(properties)
-+
-+  -- create the device
-+  local device = SpaDevice(factory, properties)
-+  device:connect("create-object", createNode)
-+  device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND)
-+  parent:store_managed_object(id, device)
-+end
-+
-+monitor = SpaDevice("api.v4l2.enum.udev", config.properties or {})
-+if monitor then
-+  monitor:connect("create-object", createDevice)
-+  monitor:activate(Feature.SpaDevice.ENABLED)
-+else
-+  Log.message("PipeWire's V4L SPA missing or broken. Video4Linux not supported.")
-+end
--- 
-2.30.2
-
diff --git a/Dockerfile b/Dockerfile
index 208aa4215c198d5c18c29abf82c041c5dc1ff3a2..04a2a78299725bb13e76dfd6f85f581892228850 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,40 +1,15 @@
-FROM debian:stable
+FROM debian:unstable
 
 ENV LANG C.UTF-8
 
 RUN apt-get update && apt-get install -y \
-	debhelper-compat \
-	findutils \
-	git \
-	ninja-build meson \
-	pkg-config \
-	libdbus-1-dev \
-	libglib2.0-dev \
-	libgirepository1.0-dev \
-	doxygen \
-	python3-lxml \
-	libsndfile1-dev \
-	libgstreamer1.0-dev \
-	libgstreamer-plugins-base1.0-dev \
-	gstreamer1.0-tools \
-	systemd \
-	libgl1-mesa-glx \
-	libgl1-mesa-dri \
-	mesa-utils \
-	&& apt-get clean \
-	&& rm -rf /var/lib/apt/lists/*
-
-RUN git clone --depth=1 --branch=master https://gitlab.freedesktop.org/pipewire/pipewire.git \
-	&& meson build-pw pipewire --prefix=/usr \
-	   -Dsession-managers="['wireplumber']" -Ddefault-session-manager=wireplumber \
-	&& ninja -C build-pw install \
-	&& rm -rf build-pw pipewire
-
-# RUN rm /bin/sh && ln -s /bin/bash /bin/sh
-# SHELL ["/bin/bash", "-c"]
-# RUN echo 'alias hi="echo hello"' >> ~/.bashrc
-
-# RUN echo 'alias s="echo hello"' >> ~/.bashrc
-# RUN echo 'export PIPEWIRE_RUNTIME_DIR=/run/user/1000' >> ~/.bashrc
-# RUN echo 'export XDG_RUNTIME_DIR=/run/user/$UID' >> ~/.bashrc
-# # RUN /usr/bin/source ~/.bashrc
+        gstreamer1.0-tools \
+        gstreamer1.0-pipewire \
+        gstreamer1.0-plugins-good \
+        gstreamer1.0-plugins-base \
+        gstreamer1.0-gl \
+        pipewire-audio-client-libraries \
+        pipewire \
+        wireplumber \
+        && apt-get clean \
+        && rm -rf /var/lib/apt/lists/*
\ No newline at end of file
diff --git a/README.md b/README.md
index 1e2d85a5671f3a02975660c4e1f560f24b3f6d2a..1e82f1cf91b8363d96babdd6ad17d3efc342b152 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,16 @@
+
 # pipewire-multiple-camera-feed-access-demo
 
 A demo to showcase the capabilities of pipewire in letting multiple clients running in containers, access multiple cameras available in the system.
 
+- [pipewire-multiple-camera-feed-access-demo](#pipewire-multiple-camera-feed-access-demo)
+- [**Creating Container:**](#creating-container)
+- [**Setting up pipewire:**](#setting-up-pipewire)
+- [**Setting up wireplumber:**](#setting-up-wireplumber)
+  - [Method 1](#method-1)
+  - [Method 2](#method-2)
 
-**Steps:**
-
-Below are the instructions to re-create the demo.
-
-**Creating Container:**
+# **Creating Container:**
 
 Podman is chosen as the container for this demo. First step is to install podman and then.
 
@@ -15,31 +18,60 @@ Podman is chosen as the container for this demo. First step is to install podman
     
 ```
 cd multiple-camera-feed-access-demo
-podman build --tag debian-pipewire .
+podman build --tag debian-unstable-pipewire .
 ```
 The Above build command places takes the dockerfile(included in the repositiory).
 
 - Run Podman: 
 
 ```
-podman run -it --rm -e DISPLAY=$DISPLAY -e PIPEWIRE_RUNTIME_DIR=/run/user/1000 -e XDG_RUNTIME_DIR=/run/user/$UID -v /run/user/1000/pipewire-0:/run/user/1000/pipewire-0 -v /tmp/.X11-unix:/tmp/.X11-unix:rw -v ./aliases:/tmp/.bash_aliases pipewire-podman /bin/bash --init-file /tmp/.bash_aliases
+podman run -it --rm -e WAYLAND_DISPLAY=wayland-0 \
+                    -e XDG_RUNTIME_DIR=/run/user/0 \
+                    -v /run/user/1000/pipewire-0:/run/user/0/pipewire-0:Z \
+                    -v /run/user/1000/wayland-0:/run/user/0/wayland-0:Z \
+                    -v /dev/dri:/dev/dri \
+                    --security-opt label=disable \
+                    -v ./aliases:/tmp/.bash_aliases:Z \
+                    debian-unstable-pipewire /bin/bash --init-file /tmp/.bash_aliases
 ```
 
-**Setting up pipewire:**
+# **Setting up pipewire:**
 
-This config file contains changes to open pipewire in restricted moded.
+- configure pipewire in restricted acces mode.
+- stop pipewire deamon
+```
+systemctl --user stop pipewire.service  pipewire.socket  wireplumber.service  pipewire-pulse.service pipewire-pulse.socket
 ```
-sudo cp pipewire.conf /etc/pipewire/pipewire.conf
+- start pipewire with new config file 
+- restart the pipewire with custom conf file(the only diff is this conf file is the the pipewire access permissions).
 ```
+pipewire -c <path>/pipewire.conf 2>&1 | tee ~/pipewire.log
+```
+
+# **Setting up wireplumber:**
+
+## Method 1
 
-**Setting up wireplumber:**
-- Update the wireplumber.conf
+- stop wireplumber demon(when u kill pipewire wireplumber goes down as well) 
+
+> $ systemctl --user stop wireplumber.service
+
+- Update the wireplumber.conf and start it from the source
 
 ```
-cp wireplumber.conf <pipewire>/subprojects/wireplumber/src/config/
+cp wireplumber.conf <wireplumber src path>/wireplumber/src/config/
 ```
 
 - Update the Lua config files
 ```
-cp lua-policy-files/* <pipewire>/subprojects/wireplumber/src/scripts/
+cp lua-policy-files/* <wireplumber src path>/src/scripts/
+```
+- run wireplumber from **source**
 ```
+cd $HOME/code/pipewire/subprojects/wireplumber/
+make run 2>$2 &
+```
+
+## Method 2
+
+- apply wireplumber-0.4.5-22-gbe7b95c+cameras_demo.diff and then recompile and re-start the wireplumber. George has taken things in the Method 1 and then churned out Meathod 2
\ No newline at end of file
diff --git a/demo-secure-video-cam-access.mp4 b/demo-secure-video-cam-access.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..da41892f54a7cc61fb04da294d9a8df3d955965e
Binary files /dev/null and b/demo-secure-video-cam-access.mp4 differ
diff --git a/pipewire.conf b/pipewire.conf
index 28d0dc947b33014316199d6b22346d924a981d46..b2ae148b838cc63a1a4a36bdcce55bbc04116fe1 100644
--- a/pipewire.conf
+++ b/pipewire.conf
@@ -1,6 +1,6 @@
-# Daemon config file for PipeWire version "0.3.33" #
+# Daemon config file for PipeWire version "0.3.40" #
 #
-# Copy and edit this file in /etc/pipewire for systemwide changes
+# Copy and edit this file in /etc/pipewire for system-wide changes
 # or in ~/.config/pipewire for local changes.
 
 context.properties = {
@@ -15,9 +15,10 @@ context.properties = {
     #mem.mlock-all                         = false
     #clock.power-of-two-quantum            = true
     #log.level                             = 2
+    #cpu.zero.denormals                    = true
 
-    core.daemon                            = true                     # listening for socket connections
-    core.name                              = pipewire-0               # core name and socket name
+    core.daemon = true              # listening for socket connections
+    core.name   = pipewire-0        # core name and socket name
 
     ## Properties for the DSP configuration.
     #default.clock.rate          = 48000
@@ -32,7 +33,7 @@ context.properties = {
     #
     # These overrides are only applied when running in a vm.
     vm.overrides = {
-        default.clock.min-quantum     = 1024
+        default.clock.min-quantum = 1024
     }
 }
 
@@ -56,8 +57,8 @@ context.spa-libs = {
 }
 
 context.modules = [
-    #{   name = <module-name>
-    #    [ args = { <key> = <value> ... } ]
+    #{ name = <module-name>
+    #    [ args  = { <key> = <value> ... } ]
     #    [ flags = [ [ ifexists ] [ nofail ] ]
     #}
     #
@@ -67,7 +68,7 @@ context.modules = [
     #
 
     # Uses RTKit to boost the data thread priority.
-    {   name = libpipewire-module-rtkit
+    { name = libpipewire-module-rtkit
         args = {
             #nice.level   = -11
             #rt.prio      = 88
@@ -78,7 +79,7 @@ context.modules = [
     }
 
     # Set thread priorities without using RTKit.
-    #{   name = libpipewire-module-rt
+    #{ name = libpipewire-module-rt
     #    args = {
     #        nice.level   = -11
     #        rt.prio      = 88
@@ -89,52 +90,50 @@ context.modules = [
     #}
 
     # The native communication protocol.
-    {   name = libpipewire-module-protocol-native }
+    { name = libpipewire-module-protocol-native }
 
     # The profile module. Allows application to access profiler
     # and performance data. It provides an interface that is used
     # by pw-top and pw-profiler.
-    {   name = libpipewire-module-profiler }
+    { name = libpipewire-module-profiler }
 
     # Allows applications to create metadata objects. It creates
     # a factory for Metadata objects.
-    {   name = libpipewire-module-metadata }
+    { name = libpipewire-module-metadata }
 
     # Creates a factory for making devices that run in the
     # context of the PipeWire server.
-    {   name = libpipewire-module-spa-device-factory }
+    { name = libpipewire-module-spa-device-factory }
 
     # Creates a factory for making nodes that run in the
     # context of the PipeWire server.
-    {   name = libpipewire-module-spa-node-factory }
+    { name = libpipewire-module-spa-node-factory }
 
     # Allows creating nodes that run in the context of the
     # client. Is used by all clients that want to provide
     # data to PipeWire.
-    {   name = libpipewire-module-client-node }
+    { name = libpipewire-module-client-node }
 
     # Allows creating devices that run in the context of the
     # client. Is used by the session manager.
-    {   name = libpipewire-module-client-device }
+    { name = libpipewire-module-client-device }
 
     # The portal module monitors the PID of the portal process
     # and tags connections with the same PID as portal
     # connections.
-    {   name = libpipewire-module-portal
+    { name = libpipewire-module-portal
         flags = [ ifexists nofail ]
     }
 
     # The access module can perform access checks and block
     # new clients.
-    {   name = libpipewire-module-access
+    { name = libpipewire-module-access
         args = {
             # access.allowed to list an array of paths of allowed
             # apps.
             access.allowed = [
-               /home/ashok/Documents/code/pipewire/subprojects/wireplumber/build/src/wireplumber
+               wireplumber
                /usr/bin/gnome-shell
-               /usr/libexec/gsd-media-keys
-               /snap/vlc/2344/usr/bin/vlc
             ]
 
             # An array of rejected paths.
@@ -151,17 +150,17 @@ context.modules = [
 
     # Makes a factory for wrapping nodes in an adapter with a
     # converter and resampler.
-    {   name = libpipewire-module-adapter }
+    { name = libpipewire-module-adapter }
 
     # Makes a factory for creating links between ports.
-    {   name = libpipewire-module-link-factory }
+    { name = libpipewire-module-link-factory }
 
     # Provides factories to make session manager objects.
-    {   name = libpipewire-module-session-manager }
+    { name = libpipewire-module-session-manager }
 ]
 
 context.objects = [
-    #{   factory = <factory-name>
+    #{ factory = <factory-name>
     #    [ args  = { <key> = <value> ... } ]
     #    [ flags = [ [ nofail ] ]
     #}
@@ -169,7 +168,7 @@ context.objects = [
     # Creates an object from a PipeWire factory with the given parameters.
     # If nofail is given, errors are ignored (and no object is created).
     #
-    #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
+    #{ factory = spa-node-factory   args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
     #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
     #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
     #{ factory = spa-node-factory   args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
@@ -178,7 +177,7 @@ context.objects = [
 
     # A default dummy driver. This handles nodes marked with the "node.always-driver"
     # property when no other driver is currently active. JACK clients need this.
-    {   factory = spa-node-factory
+    { factory = spa-node-factory
         args = {
             factory.name    = support.node.driver
             node.name       = Dummy-Driver
@@ -186,7 +185,7 @@ context.objects = [
             priority.driver = 20000
         }
     }
-    {   factory = spa-node-factory
+    { factory = spa-node-factory
         args = {
             factory.name    = support.node.driver
             node.name       = Freewheel-Driver
@@ -197,7 +196,7 @@ context.objects = [
     }
     # This creates a new Source node. It will have input ports
     # that you can link, to provide audio for this source.
-    #{   factory = adapter
+    #{ factory = adapter
     #    args = {
     #        factory.name     = support.null-audio-sink
     #        node.name        = "my-mic"
@@ -210,21 +209,21 @@ context.objects = [
     # This creates a single PCM source device for the given
     # alsa device path hw:0. You can change source to sink
     # to make a sink in the same way.
-    #{   factory = adapter
+    #{ factory = adapter
     #    args = {
-    #        factory.name            = api.alsa.pcm.source
-    #        node.name               = "alsa-source"
-    #        node.description        = "PCM Source"
-    #        media.class             = "Audio/Source"
-    #        api.alsa.path           = "hw:0"
-    #        #api.alsa.period-size   = 1024
-    #        #api.alsa.headroom      = 0
-    #        #api.alsa.disable-mmap  = false
-    #        #api.alsa.disable-batch = false
-    #        #audio.format           = "S16LE"
-    #        #audio.rate             = 48000
-    #        #audio.channels         = 2
-    #        #audio.position         = "FL,FR"
+    #        factory.name           = api.alsa.pcm.source
+    #        node.name              = "alsa-source"
+    #        node.description       = "PCM Source"
+    #        media.class            = "Audio/Source"
+    #        api.alsa.path          = "hw:0"
+    #        api.alsa.period-size   = 1024
+    #        api.alsa.headroom      = 0
+    #        api.alsa.disable-mmap  = false
+    #        api.alsa.disable-batch = false
+    #        audio.format           = "S16LE"
+    #        audio.rate             = 48000
+    #        audio.channels         = 2
+    #        audio.position         = "FL,FR"
     #    }
     #}
 ]
@@ -238,7 +237,7 @@ context.exec = [
     # but it is better to start it as a systemd service.
     # Run the session manager with -h for options.
     #
-    #{ path = "/usr/bin/pipewire-media-session"  args = "" }
+    #{ path = "/usr/bin/pipewire-media-session" args = "" }
     #
     # You can optionally start the pulseaudio-server here as well
     # but it is better to start it as a systemd service.
diff --git a/secure-video-cam-access.odp b/secure-video-cam-access.odp
new file mode 100644
index 0000000000000000000000000000000000000000..194349021bcad6c37f8a2e1524ca63262e8d5290
Binary files /dev/null and b/secure-video-cam-access.odp differ
diff --git a/slides-secure-video-cam-access.mp4 b/slides-secure-video-cam-access.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..f0af065a2e4d7a38ba4d08f3bf9a61a69ae737cb
Binary files /dev/null and b/slides-secure-video-cam-access.mp4 differ
diff --git a/wireplumber-0.4.5-22-gbe7b95c+cameras_demo.diff b/wireplumber-0.4.5-22-gbe7b95c+cameras_demo.diff
new file mode 100644
index 0000000000000000000000000000000000000000..5dcd19c6fb57e0cdcf77ea3c9bdd2df79e370731
--- /dev/null
+++ b/wireplumber-0.4.5-22-gbe7b95c+cameras_demo.diff
@@ -0,0 +1,101 @@
+diff --git a/src/config/main.lua.d/50-default-access-config.lua b/src/config/main.lua.d/50-default-access-config.lua
+index 6cf18be..ed0ed92 100644
+--- a/src/config/main.lua.d/50-default-access-config.lua
++++ b/src/config/main.lua.d/50-default-access-config.lua
+@@ -26,6 +26,6 @@ default_access.rules = {
+         { "pipewire.access", "=", "restricted" },
+       },
+     },
+-    default_permissions = "rx",
++    default_permissions = "rwxm",
+   },
+ }
+diff --git a/src/scripts/access/access-default.lua b/src/scripts/access/access-default.lua
+index 3c27e90..a7688d2 100644
+--- a/src/scripts/access/access-default.lua
++++ b/src/scripts/access/access-default.lua
+@@ -37,17 +37,40 @@ end
+ clients_om = ObjectManager {
+   Interest { type = "client" }
+ }
++fact_om = ObjectManager {
++  Interest { type = "factory"}
++}
+ 
+ clients_om:connect("object-added", function (om, client)
+   local id = client["bound-id"]
+   local properties = client["properties"]
+ 
+-  local perms = rulesGetDefaultPermissions(properties)
++  if properties["application.process.host"] == Core.get_info()["host_name"] then
++    -- Local client added grant standard access
++    local perms = rulesGetDefaultPermissions(properties)
++
++    if perms then
++      Log.info(client, "Granting permissions to client " .. id .. ": " .. perms)
++      client:update_permissions { ["any"] = perms }
++    end
++  else
++    -- Container client, limited access
++    Log.info(client, "container client added"..tostring(client))
++
++    -- first grant access to pw core
++    client:update_permissions { [0] = "rwxm" }
++
++    -- second grant access to client node factory, so that a stream node can be created.
++    local cnf = fact_om:lookup { Constraint { "factory.name", "matches", "client-node", type = "pw-global" }, }
++    if not cnf then
++      Log.warning("access cannot be granted: unable to locate client node factory object");
++      return
++    end
+ 
+-  if perms then
+-    Log.info(client, "Granting permissions to client " .. id .. ": " .. perms)
+-    client:update_permissions { ["any"] = perms }
++    Log.info(cnf, "client node factory id ".. cnf["bound-id"])
++    client:update_permissions { [cnf["bound-id"]] = "rwxm" }
+   end
+ end)
+ 
++fact_om:activate()
+ clients_om:activate()
+diff --git a/src/scripts/create-item.lua b/src/scripts/create-item.lua
+index 5c22f60..2697328 100644
+--- a/src/scripts/create-item.lua
++++ b/src/scripts/create-item.lua
+@@ -56,7 +56,35 @@ function configProperties(node)
+   return properties
+ end
+ 
++clients_om = ObjectManager {
++  Interest { type = "client" }
++}
++clients_om:activate()
++
++function containerCheck(node)
++  local np = node.properties
++  local media_class = np["media.class"]
++  if string.find(media_class,"Stream") then
++    local client_id = np["client.id"]
++    local client = clients_om:lookup { Constraint { "bound-id", "=", client_id, type = "gobject" }, }
++    Log.info("client id is "..client_id.. tostring(client));
++    local cp = client["properties"]
++    if cp["application.process.host"] ~= Core.get_info()["host_name"] then
++      -- client is from container
++      if media_class ~= "Stream/Input/Video" then
++        client:send_error(node["bound-id"], -1, "not permitted")
++        return false
++      end
++    end
++  end
++  return true
++end
++
+ function addItem (node, item_type)
++  if not containerCheck(node) then
++    return
++  end
++
+   local id = node["bound-id"]
+ 
+   -- create item
diff --git a/wireplumber.conf b/wireplumber.conf
index e411a0859f959d2e9ab3929390dbba3ee799753a..50c703306b33a4812f65ee6cb3dc351bb4b8befe 100644
--- a/wireplumber.conf
+++ b/wireplumber.conf
@@ -78,7 +78,7 @@ wireplumber.components = [
   # { name = bluetooth.lua, type = config/lua }
   # { name = policy-access.lua, type = script/lua }
 
-  # demo
+  #pipewire-multiple-camera-feed-access-demo
   { name = policy-access.lua, type = script/lua }
   { name = libwireplumber-module-si-audio-adapter, type = module }
   { name = libwireplumber-module-si-node, type = module }