diff --git a/commitFile.txt b/commitFile.txt
new file mode 100644
index 0000000..380c68e
--- /dev/null
+++ b/commitFile.txt
@@ -0,0 +1,10 @@
+Updating prebuilts and/or headers
+
+da5475c4506f0f70011e5723f4f3e1e7368a0554 - gst-nvarguscamera/nvbufsurface.h
+1be6fc0d7406e0633b7e2cba49166a2f0a085cdd - gst-nvarguscamera/Makefile
+f2949ff626879be5aaeabf40e9ad8eab11238b6e - gst-nvarguscamera/gstnvarguscamera_utils.h
+5b71a3ab30d24949dcf3770e509d17dd1af64256 - gst-nvarguscamera/gstnvarguscamera_utils.cpp
+704bc9c630378dd0ab3da09d386464aaca369d05 - gst-nvarguscamera/gstnvarguscamerasrc.hpp
+31603afe2ae89fa3fc94e382a28df8f163194659 - gst-nvarguscamera/gstnvarguscamerasrc.cpp
+08b7522e02574bb6b1d0142a847a8f972d185671 - gst-nvarguscamera/3rdpartyheaders.tbz2
+fa14f1cb043a26a6465ce793ac78479d8f6afa02 - gst-nvarguscamera/gstnvdsbufferpool.h
diff --git a/gst-nvarguscamera/3rdpartyheaders.tbz2 b/gst-nvarguscamera/3rdpartyheaders.tbz2
new file mode 100644
index 0000000..b1868c8
Binary files /dev/null and b/gst-nvarguscamera/3rdpartyheaders.tbz2 differ
diff --git a/gst-nvarguscamera/Makefile b/gst-nvarguscamera/Makefile
new file mode 100644
index 0000000..b5a4940
--- /dev/null
+++ b/gst-nvarguscamera/Makefile
@@ -0,0 +1,74 @@
+# Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of NVIDIA CORPORATION nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SO_NAME := libgstnvarguscamerasrc.so
+
+CC := g++
+
+GST_INSTALL_DIR?=/usr/lib/aarch64-linux-gnu/gstreamer-1.0/
+LIB_INSTALL_DIR?=/usr/lib/aarch64-linux-gnu/tegra/
+CFLAGS:=
+LIBS:= -lnvbufsurface -lnvbufsurftransform -lnvdsbufferpool -lnvargus_socketclient -lpthread
+
+SRCS := $(wildcard *.cpp)
+
+INCLUDES += -I./ -I../
+
+# Include jetson_mm_api include path
+INCLUDES += -I/usr/src/jetson_multimedia_api/include/
+INCLUDES += -I/usr/src/jetson_multimedia_api/argus/samples/utils/
+
+PKGS := gstreamer-1.0 \
+ gstreamer-base-1.0 \
+ gstreamer-video-1.0 \
+ gstreamer-allocators-1.0 \
+ glib-2.0
+
+OBJS := $(SRCS:.cpp=.o)
+
+CFLAGS += -fPIC
+
+CFLAGS += `pkg-config --cflags $(PKGS)`
+
+LDFLAGS = -Wl,--no-undefined -L$(LIB_INSTALL_DIR) -Wl,-rpath,$(LIB_INSTALL_DIR)
+
+LIBS += `pkg-config --libs $(PKGS)`
+
+all: $(SO_NAME)
+
+%.o: %.cpp
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -o $@
+
+$(SO_NAME): $(OBJS)
+ $(CC) -shared -o $(SO_NAME) $(OBJS) $(LIBS) $(LDFLAGS)
+
+.PHONY: install
+install: $(SO_NAME)
+ cp -vp $(SO_NAME) $(GST_INSTALL_DIR)
+
+.PHONY: clean
+clean:
+ rm -rf $(OBJS) $(SO_NAME)
diff --git a/gst-nvarguscamera/README.txt b/gst-nvarguscamera/README.txt
new file mode 100644
index 0000000..f04de1c
--- /dev/null
+++ b/gst-nvarguscamera/README.txt
@@ -0,0 +1,51 @@
+# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of NVIDIA CORPORATION nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Steps to compile the "gst-nvarguscamera" sources natively:
+
+1) Install gstreamer related packages on target using the command:
+
+ sudo apt-get install libgstreamer1.0-dev \
+ gstreamer1.0-plugins-base \
+ gstreamer1.0-plugins-good \
+ libgstreamer-plugins-base1.0-dev \
+ libegl1-mesa-dev
+
+2) Install "jetson_multimedia_api" package from latest Jetpack release.
+
+3) Download and extract the package "gst-nvarguscamera_src.tbz2" as follow:
+
+ tar -I lbzip2 -xvf gst-nvarguscamera_src.tbz2
+
+3) Run the following commands to build and install "libgstnvarguscamerasrc.so":
+ cd "gst-nvarguscamera"
+ make
+ make install
+ or
+ DEST_DIR=
make install
+
+ Note: "make install" will copy library "libgstnvarguscamerasrc.so"
+ into "/usr/lib/aarch64-linux-gnu/gstreamer-1.0" directory.
diff --git a/gst-nvarguscamera/gstnvarguscamera_utils.cpp b/gst-nvarguscamera/gstnvarguscamera_utils.cpp
new file mode 100644
index 0000000..c21e9c4
--- /dev/null
+++ b/gst-nvarguscamera/gstnvarguscamera_utils.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of NVIDIA CORPORATION nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gstnvarguscamera_utils.h"
+#include
+
+GType
+gst_nvarguscam_white_balance_mode_get_type (void)
+{
+ static gsize white_balance_type = 0;
+ static const GEnumValue white_balance_mode[] = {
+ {NvArgusCamAwbMode_Off, "GST_NVCAM_WB_MODE_OFF", "off"},
+ {NvArgusCamAwbMode_Auto, "GST_NVCAM_WB_MODE_AUTO", "auto"},
+ {NvArgusCamAwbMode_Incandescent, "GST_NVCAM_WB_MODE_INCANDESCENT",
+ "incandescent"},
+ {NvArgusCamAwbMode_Fluorescent, "GST_NVCAM_WB_MODE_FLUORESCENT", "fluorescent"},
+ {NvArgusCamAwbMode_WarmFluorescent, "GST_NVCAM_WB_MODE_WARM_FLUORESCENT",
+ "warm-fluorescent"},
+ {NvArgusCamAwbMode_Daylight, "GST_NVCAM_WB_MODE_DAYLIGHT", "daylight"},
+ {NvArgusCamAwbMode_CloudyDaylight, "GST_NVCAM_WB_MODE_CLOUDY_DAYLIGHT",
+ "cloudy-daylight"},
+ {NvArgusCamAwbMode_Twilight, "GST_NVCAM_WB_MODE_TWILIGHT", "twilight"},
+ {NvArgusCamAwbMode_Shade, "GST_NVCAM_WB_MODE_SHADE", "shade"},
+ {NvArgusCamAwbMode_Manual, "GST_NVCAM_WB_MODE_MANUAL", "manual"},
+ {0, NULL, NULL}
+ };
+
+ if (g_once_init_enter (&white_balance_type)) {
+ GType tmp = g_enum_register_static ("GstNvArgusCamWBMode", white_balance_mode);
+ g_once_init_leave (&white_balance_type, tmp);
+ }
+
+ return (GType) white_balance_type;
+}
+
+GType
+gst_nvarguscam_tnr_mode_get_type (void)
+{
+ static gsize tnr_type = 0;
+ static const GEnumValue tnr_mode[] = {
+ {NvArgusCamNoiseReductionMode_Off, "GST_NVCAM_NR_OFF", "NoiseReduction_Off"},
+ {NvArgusCamNoiseReductionMode_Fast, "GST_NVCAM_NR_FAST", "NoiseReduction_Fast"},
+ {NvArgusCamNoiseReductionMode_HighQuality, "GST_NVCAM_NR_HIGHQUALITY", "NoiseReduction_HighQuality"},
+ {0, NULL, NULL}
+ };
+
+ if (g_once_init_enter (&tnr_type)) {
+ GType tmp = g_enum_register_static ("GstNvArgusCamTNRMode", tnr_mode);
+ g_once_init_leave (&tnr_type, tmp);
+ }
+ return (GType) tnr_type;
+}
+
+GType
+gst_nvarguscam_edge_enhancement_mode_get_type (void)
+{
+ static gsize edge_enhancement_type = 0;
+ static const GEnumValue edge_enhancement_mode[] = {
+ {NvArgusCamEdgeEnhancementMode_Off, "GST_NVCAM_EE_OFF", "EdgeEnhancement_Off"},
+ {NvArgusCamEdgeEnhancementMode_Fast, "GST_NVCAM_EE_FAST", "EdgeEnhancement_Fast"},
+ {NvArgusCamEdgeEnhancementMode_HighQuality, "GST_NVCAM_EE_HIGHQUALITY", "EdgeEnhancement_HighQuality"},
+ {0, NULL, NULL}
+ };
+
+ if (g_once_init_enter (&edge_enhancement_type)) {
+ GType tmp = g_enum_register_static ("GstNvArgusCamEEMode", edge_enhancement_mode);
+ g_once_init_leave (&edge_enhancement_type, tmp);
+ }
+ return (GType) edge_enhancement_type;
+}
+
+GType
+gst_nvarguscam_aeantibanding_mode_get_type (void)
+{
+ static gsize aeantibanding_type = 0;
+ static const GEnumValue aeantibanding_mode[] = {
+ {NvArgusCamAeAntibandingMode_Off, "GST_NVCAM_AEANTIBANDING_OFF", "AeAntibandingMode_Off"},
+ {NvArgusCamAeAntibandingMode_Auto, "GST_NVCAM_AEANTIBANDING_AUTO", "AeAntibandingMode_Auto"},
+ {NvArgusCamAeAntibandingMode_50HZ, "GST_NVCAM_AEANTIBANDING_50HZ", "AeAntibandingMode_50HZ"},
+ {NvArgusCamAeAntibandingMode_60HZ, "GST_NVCAM_AEANTIBANDING_60HZ", "AeAntibandingMode_60HZ"},
+ {0, NULL, NULL}
+ };
+
+ if (g_once_init_enter (&aeantibanding_type)) {
+ GType tmp = g_enum_register_static ("GstNvArgusCamAeAntiBandingMode", aeantibanding_mode);
+ g_once_init_leave (&aeantibanding_type, tmp);
+ }
+ return (GType) aeantibanding_type;
+}
\ No newline at end of file
diff --git a/gst-nvarguscamera/gstnvarguscamera_utils.h b/gst-nvarguscamera/gstnvarguscamera_utils.h
new file mode 100644
index 0000000..3bfea40
--- /dev/null
+++ b/gst-nvarguscamera/gstnvarguscamera_utils.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of NVIDIA CORPORATION nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GSTNVARGUSCAMERA_UTILS_H_
+#define GSTNVARGUSCAMERA_UTILS_H_
+
+#include
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum
+{
+ NvArgusCamAwbMode_Off = 0,
+ NvArgusCamAwbMode_Auto,
+ NvArgusCamAwbMode_Incandescent,
+ NvArgusCamAwbMode_Fluorescent,
+ NvArgusCamAwbMode_WarmFluorescent,
+ NvArgusCamAwbMode_Daylight,
+ NvArgusCamAwbMode_CloudyDaylight,
+ NvArgusCamAwbMode_Twilight,
+ NvArgusCamAwbMode_Shade,
+ NvArgusCamAwbMode_Manual,
+
+} NvArgusCamAwbMode;
+
+typedef enum
+{
+ NvArgusCamNoiseReductionMode_Off = 0,
+ NvArgusCamNoiseReductionMode_Fast,
+ NvArgusCamNoiseReductionMode_HighQuality
+
+} NvArgusCamNoiseReductionMode;
+
+typedef enum
+{
+ NvArgusCamEdgeEnhancementMode_Off = 0,
+ NvArgusCamEdgeEnhancementMode_Fast,
+ NvArgusCamEdgeEnhancementMode_HighQuality
+
+} NvArgusCamEdgeEnhancementMode;
+
+typedef enum
+{
+ NvArgusCamAeAntibandingMode_Off = 0,
+ NvArgusCamAeAntibandingMode_Auto,
+ NvArgusCamAeAntibandingMode_50HZ,
+ NvArgusCamAeAntibandingMode_60HZ
+
+} NvArgusCamAeAntibandingMode;
+
+GType gst_nvarguscam_white_balance_mode_get_type (void);
+#define GST_TYPE_NVARGUSCAM_WB_MODE (gst_nvarguscam_white_balance_mode_get_type())
+
+GType gst_nvarguscam_tnr_mode_get_type (void);
+#define GST_TYPE_NVARGUSCAM_TNR_MODE (gst_nvarguscam_tnr_mode_get_type())
+
+GType gst_nvarguscam_edge_enhancement_mode_get_type (void);
+#define GST_TYPE_NVARGUSCAM_EDGE_ENHANCEMENT_MODE (gst_nvarguscam_edge_enhancement_mode_get_type())
+
+GType gst_nvarguscam_aeantibanding_mode_get_type (void);
+#define GST_TYPE_NVARGUSCAM_AEANTIBANDING_MODE (gst_nvarguscam_aeantibanding_mode_get_type())
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GSTNVARGUSCAMERA_UTILS_H_ */
diff --git a/gst-nvarguscamera/gstnvarguscamerasrc.cpp b/gst-nvarguscamera/gstnvarguscamerasrc.cpp
new file mode 100644
index 0000000..97d9ef0
--- /dev/null
+++ b/gst-nvarguscamera/gstnvarguscamerasrc.cpp
@@ -0,0 +1,2434 @@
+/*
+ * Copyright (c) 2017-2023, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of NVIDIA CORPORATION nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Sample pipeline
+ *
+ * gst-launch-1.0
+ * nvarguscamerasrc !
+ * "video/x-raw(memory:NVMM), width=640, height=480, format=NV12, framerate=30/1" !
+ * nvoverlaysink -e -v
+ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include // for useconds_t
+
+#include "Ordered.h"
+
+#include "gstnvarguscamerasrc.hpp"
+#include "Error.h"
+
+#define CAPTURE_CAPS \
+ "video/x-raw(memory:NVMM), " \
+ "width = (int) [ 1, MAX ], " \
+ "height = (int) [ 1, MAX ], " \
+ "format = (string) { NV12 }, " \
+ "framerate = (fraction) [ 0, MAX ];"
+
+#define MIN_BUFFERS 6
+#define MAX_BUFFERS 8
+
+#define MIN_GAIN 1
+#define MAX_GAIN 16
+
+#define MIN_EXPOSURE_TIME 34000
+#define MAX_EXPOSURE_TIME 358733000
+
+#define MIN_DIGITAL_GAIN 1
+#define MAX_DIGITAL_GAIN 256
+
+#define GST_NVARGUS_MEMORY_TYPE "nvarguscam"
+static const int DEFAULT_FPS = 30;
+static const uint64_t DEFAULT_WAIT_FOR_EVENT_TIMEOUT = 3000000000;
+static const uint64_t DEFAULT_ACQUIRE_FRAME_TIMEOUT = 5000000000;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+using namespace std;
+using namespace Argus;
+using namespace EGLStream;
+
+std::mutex g_mtx;
+class CameraProviderContainer
+{
+public:
+ CameraProviderContainer()
+ {
+ m_cameraProvider = CameraProvider::create();
+ if (!m_cameraProvider)
+ return;
+
+ m_iCameraProvider = interface_cast(m_cameraProvider);
+ m_iCameraProvider->getCameraDevices(&m_cameraDevices);
+ }
+
+ ~CameraProviderContainer()
+ {
+ if (m_cameraProvider)
+ m_cameraProvider->destroy();
+ }
+
+ ICameraProvider* getICameraProvider();
+ std::vector getCameraDevices();
+private:
+ CameraProvider *m_cameraProvider = NULL;
+ ICameraProvider *m_iCameraProvider = NULL;
+ std::vector m_cameraDevices;
+};
+
+ICameraProvider* CameraProviderContainer::getICameraProvider()
+{
+ if (!m_cameraProvider)
+ return NULL;
+
+ return m_iCameraProvider;
+}
+
+vector CameraProviderContainer::getCameraDevices()
+{
+ return m_cameraDevices;
+}
+
+shared_ptr g_cameraProvider = make_shared();
+
+namespace ArgusSamples
+{
+
+ThreadArgus::ThreadArgus()
+ : m_doShutdown(false)
+ , m_threadID(0)
+ , m_threadState(THREAD_INACTIVE)
+
+{
+}
+
+ThreadArgus::~ThreadArgus()
+{
+ (void)shutdown();
+}
+
+bool ThreadArgus::initialize(GstNvArgusCameraSrc *src)
+{
+ if (m_threadID)
+ return true;
+
+ this->src = src;
+
+ if (pthread_create(&m_threadID, NULL, threadFunctionStub, this) != 0)
+ ORIGINATE_ERROR("Failed to create thread.");
+
+ // wait for the thread to start up
+ while (m_threadState == THREAD_INACTIVE)
+ {
+ usleep(100);
+ if (m_threadState == THREAD_FAILED)
+ return false;
+ }
+
+ return true;
+}
+
+bool ThreadArgus::shutdown()
+{
+ if (m_threadID)
+ {
+ m_doShutdown = true;
+ if (pthread_join(m_threadID, NULL) != 0)
+ ORIGINATE_ERROR("Failed to join thread");
+ m_threadID = 0;
+ m_doShutdown = false;
+ m_threadState = THREAD_INACTIVE;
+ }
+
+ return true;
+}
+
+bool ThreadArgus::waitRunning(useconds_t timeoutUs)
+{
+ // Can only wait for a thread which is initializing or already running
+ if ((m_threadState != THREAD_INITIALIZING) && (m_threadState != THREAD_RUNNING))
+ ORIGINATE_ERROR("Invalid thread state %d", m_threadState.get());
+
+ // wait for the thread to run
+ const useconds_t sleepTimeUs = 100;
+ while (m_threadState != THREAD_RUNNING)
+ {
+ usleep(sleepTimeUs);
+ if (m_threadState == THREAD_FAILED)
+ {
+ ORIGINATE_ERROR("Invalid thread state %d", m_threadState.get());
+ }
+#ifdef DEBUG
+ // in debug mode wait indefinitely
+#else
+ if (timeoutUs < sleepTimeUs)
+ return false;
+ timeoutUs -= sleepTimeUs;
+#endif
+ }
+
+ return true;
+}
+
+/**
+ * Thread function stub, calls the real thread function.
+ *
+ * @param [in] dataPtr Pointer to user data
+ */
+/* static */ void *ThreadArgus::threadFunctionStub(void *dataPtr)
+{
+ ThreadArgus *thread = static_cast(dataPtr);
+
+ if (!thread->threadFunction(thread->src))
+ thread->m_threadState = ThreadArgus::THREAD_FAILED;
+ else
+ thread->m_threadState = ThreadArgus::THREAD_DONE;
+
+ return NULL;
+}
+
+/**
+ * Thread function
+ */
+bool ThreadArgus::threadFunction(GstNvArgusCameraSrc *src)
+{
+ m_threadState = THREAD_INITIALIZING;
+
+ PROPAGATE_ERROR(threadInitialize(src));
+
+ m_threadState = THREAD_RUNNING;
+
+ while (!m_doShutdown)
+ {
+ PROPAGATE_ERROR(threadExecute(src));
+ }
+
+ PROPAGATE_ERROR(threadShutdown(src));
+
+ return true;
+}
+
+}; // namespace ArgusSamples
+
+namespace ArgusCamera
+{
+
+// Constants
+
+#define GST_ARGUS_PRINT(...) printf("GST_ARGUS: " __VA_ARGS__)
+#define CONSUMER_PRINT(...) printf("CONSUMER: " __VA_ARGS__)
+#define GST_ARGUS_ERROR(...) printf("ARGUS_ERROR: Error generated. %s, %s: %d %s", __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+const char* getStatusString(Argus::Status status);
+
+/*******************************************************************************
+ * StreamConsumer thread:
+ * Creates a StreamConsumer object to read frames from the OutputStream just tests
+ * for sanity.
+ ******************************************************************************/
+class StreamConsumer : public ArgusSamples::ThreadArgus
+{
+public:
+ explicit StreamConsumer(OutputStream* stream) :
+ m_stream(stream)
+ {
+ }
+ ~StreamConsumer()
+ {
+ }
+
+private:
+ /** @name Thread methods */
+ /**@{*/
+ virtual bool threadInitialize(GstNvArgusCameraSrc *);
+ virtual bool threadExecute(GstNvArgusCameraSrc *);
+ virtual bool threadShutdown(GstNvArgusCameraSrc *);
+ /**@}*/
+
+ OutputStream* m_stream;
+ //GstNvArgusCameraSrc *argus_src;
+ UniqueObj m_consumer;
+};
+
+const char* getStatusString(Argus::Status status)
+{
+ switch (status)
+ {
+ case Argus::STATUS_OK: return "OK";
+ case Argus::STATUS_INVALID_PARAMS: return "INVALID_PARAMS";
+ case Argus::STATUS_INVALID_SETTINGS: return "INVALID_SETTINGS";
+ case Argus::STATUS_UNAVAILABLE: return "UNAVAILABLE";
+ case Argus::STATUS_OUT_OF_MEMORY: return "OUT_OF_MEMORY";
+ case Argus::STATUS_UNIMPLEMENTED: return "UNIMPLEMENTED";
+ case Argus::STATUS_TIMEOUT: return "TIMEOUT";
+ case Argus::STATUS_CANCELLED: return "CANCELLED";
+ case Argus::STATUS_DISCONNECTED: return "DISCONNECTED";
+ case Argus::STATUS_END_OF_STREAM: return "END_OF_STREAM";
+ default: return "BAD STATUS";
+ }
+}
+
+bool StreamConsumer::threadInitialize(GstNvArgusCameraSrc *src)
+{
+ // Create the FrameConsumer.
+ m_consumer = UniqueObj(FrameConsumer::create(m_stream));
+ if (!m_consumer)
+ ORIGINATE_ERROR("Failed to create FrameConsumer");
+
+ return true;
+}
+
+bool StreamConsumer::threadExecute(GstNvArgusCameraSrc *src)
+{
+ IEGLOutputStream *iStream = interface_cast(m_stream);
+ Size2D streamSize (src->width, src->height);
+ IFrameConsumer *iFrameConsumer = interface_cast(m_consumer);
+
+ // Wait until the producer has connected to the stream.
+ CONSUMER_PRINT("Waiting until producer is connected...\n");
+ if (iStream->waitUntilConnected() != STATUS_OK)
+ {
+ src->argus_in_error = TRUE;
+ ORIGINATE_ERROR("Stream failed to connect.");
+ }
+ CONSUMER_PRINT("Producer has connected; continuing.\n");
+ IAutoControlSettings* l_iAutoControlSettings_ptr = (IAutoControlSettings *)src->iAutoControlSettings_ptr;
+ ICaptureSession* l_iCaptureSession = (ICaptureSession *)src->iCaptureSession_ptr;
+ IDenoiseSettings* l_iDenoiseSettings_ptr = (IDenoiseSettings *)src->iDenoiseSettings_ptr;
+ IEdgeEnhanceSettings* l_iEeSettings_ptr = (IEdgeEnhanceSettings *)src->iEeSettings_ptr;
+ ISourceSettings* l_iRequestSourceSettings_ptr = (ISourceSettings *)src->iRequestSourceSettings_ptr;
+ Request* l_captureRequest = (Request*)src->request_ptr;
+ IEventProvider *iEventProvider_ptr = (IEventProvider*)src->iEventProvider_ptr;
+ IEventQueue *iEventQueue_ptr = (IEventQueue*)src->iEventQueue_ptr;
+ Range sensorModeAnalogGainRange;
+ Range ispDigitalGainRange;
+ Range limitExposureTimeRange;
+ l_iCaptureSession->repeat(l_captureRequest);
+
+ src->frameInfo = g_slice_new(NvArgusFrameInfo);
+ src->frameInfo->fd = -1;
+ while (true)
+ {
+ Argus::Status frame_status;
+ GError *error = NULL;
+ Event* event = NULL;
+ IEvent* iEvent = NULL;
+ static GQuark domain = g_quark_from_static_string ("NvArgusCameraSrc");
+
+ g_mutex_lock(&src->queue_lock);
+ if (src->queue.get() == NULL)
+ {
+ g_mutex_unlock(&src->queue_lock);
+ break;
+ }
+
+ iEventProvider_ptr->waitForEvents(src->queue.get(), src->event_timeout);
+ g_mutex_unlock(&src->queue_lock);
+
+ if (iEventQueue_ptr->getSize() == 0)
+ {
+ g_mutex_lock (&src->argus_buffers_queue_lock);
+ src->stop_requested = TRUE;
+ g_mutex_unlock (&src->argus_buffers_queue_lock);
+ break;
+ }
+
+ event = (Event* )iEventQueue_ptr->getEvent(iEventQueue_ptr->getSize() - 1);
+ iEvent = (IEvent*)interface_cast(event);
+ if (!iEvent)
+ {
+ src->argus_in_error = TRUE;
+ ORIGINATE_ERROR("Failed to get IEvent interface");
+ }
+
+ if (iEvent->getEventType() == EVENT_TYPE_ERROR)
+ {
+ if (src->stop_requested == TRUE || src->timeout_complete == TRUE)
+ break;
+
+ src->argus_in_error = TRUE;
+ const IEventError* iEventError = interface_cast(event);
+ Argus::Status argusStatus = iEventError->getStatus();
+ error = g_error_new_literal (domain, argusStatus, getStatusString(argusStatus));
+ GstMessage *message = gst_message_new_error (GST_OBJECT(src), error, "Argus Error Status");
+ gst_element_post_message (GST_ELEMENT_CAST(src), message);
+ g_mutex_lock (&src->argus_buffers_queue_lock);
+ src->stop_requested = TRUE;
+ g_mutex_unlock (&src->argus_buffers_queue_lock);
+ break;
+ }
+
+ {
+ UniqueObj frame(iFrameConsumer->acquireFrame(src->acquire_timeout, &frame_status));
+
+ if (src->stop_requested == TRUE || src->timeout_complete == TRUE)
+ {
+ break;
+ }
+
+ if (frame_status != STATUS_OK)
+ {
+ src->argus_in_error = TRUE;
+ error = g_error_new_literal (domain, frame_status, getStatusString(frame_status));
+ GstMessage *message = gst_message_new_error (GST_OBJECT(src), error, "Argus Error Status");
+ gst_element_post_message (GST_ELEMENT_CAST(src), message);
+ g_mutex_lock (&src->argus_buffers_queue_lock);
+ src->stop_requested = TRUE;
+ g_mutex_unlock (&src->argus_buffers_queue_lock);
+ break;
+ }
+ if (!frame)
+ {
+ g_mutex_lock (&src->argus_buffers_queue_lock);
+ src->stop_requested = TRUE;
+ g_mutex_unlock (&src->argus_buffers_queue_lock);
+ break;
+ }
+
+ if (src->wbPropSet)
+ {
+ switch (src->controls.wbmode)
+ {
+ case NvArgusCamAwbMode_Off:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_OFF);
+ break;
+ case NvArgusCamAwbMode_Auto:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_AUTO);
+ break;
+ case NvArgusCamAwbMode_Incandescent:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_INCANDESCENT);
+ break;
+ case NvArgusCamAwbMode_Fluorescent:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_FLUORESCENT);
+ break;
+ case NvArgusCamAwbMode_WarmFluorescent:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_WARM_FLUORESCENT);
+ break;
+ case NvArgusCamAwbMode_Daylight:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_DAYLIGHT);
+ break;
+ case NvArgusCamAwbMode_CloudyDaylight:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_CLOUDY_DAYLIGHT);
+ break;
+ case NvArgusCamAwbMode_Twilight:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_TWILIGHT);
+ break;
+ case NvArgusCamAwbMode_Shade:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_SHADE);
+ break;
+ case NvArgusCamAwbMode_Manual:
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_MANUAL);
+ break;
+ default :
+ l_iAutoControlSettings_ptr->setAwbMode(AWB_MODE_OFF);
+ break;
+ }
+ src->wbPropSet = FALSE;
+ l_iCaptureSession->repeat(l_captureRequest);
+ }
+
+ if (src->saturationPropSet)
+ {
+ l_iAutoControlSettings_ptr->setColorSaturationEnable(TRUE);
+ l_iAutoControlSettings_ptr->setColorSaturation(src->controls.saturation);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->saturationPropSet = FALSE;
+ }
+
+ if (src->exposureCompensationPropSet)
+ {
+ l_iAutoControlSettings_ptr->setExposureCompensation(src->controls.ExposureCompensation);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->exposureCompensationPropSet = FALSE;
+ }
+
+ if(src->aeLockPropSet)
+ {
+ if(src->controls.AeLock)
+ l_iAutoControlSettings_ptr->setAeLock(true);
+ else
+ l_iAutoControlSettings_ptr->setAeLock(false);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->aeLockPropSet = FALSE;
+ }
+
+ if(src->awbLockPropSet)
+ {
+ if(src->controls.AwbLock)
+ l_iAutoControlSettings_ptr->setAwbLock(true);
+ else
+ l_iAutoControlSettings_ptr->setAwbLock(false);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->awbLockPropSet = FALSE;
+ }
+
+ if(src->tnrModePropSet)
+ {
+ switch (src->controls.NoiseReductionMode)
+ {
+ case NvArgusCamNoiseReductionMode_Off:
+ l_iDenoiseSettings_ptr->setDenoiseMode(DENOISE_MODE_OFF);
+ break;
+ case NvArgusCamNoiseReductionMode_Fast:
+ l_iDenoiseSettings_ptr->setDenoiseMode(DENOISE_MODE_FAST);
+ break;
+ case NvArgusCamNoiseReductionMode_HighQuality:
+ l_iDenoiseSettings_ptr->setDenoiseMode(DENOISE_MODE_HIGH_QUALITY);
+ break;
+ default :
+ l_iDenoiseSettings_ptr->setDenoiseMode(DENOISE_MODE_OFF);
+ break;
+ }
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->tnrModePropSet = FALSE;
+ }
+
+ if(src->tnrStrengthPropSet)
+ {
+ l_iDenoiseSettings_ptr->setDenoiseStrength(src->controls.NoiseReductionStrength);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->tnrStrengthPropSet = FALSE;
+ }
+
+ if(src->edgeEnhancementModePropSet)
+ {
+ switch (src->controls.EdgeEnhancementMode)
+ {
+ case NvArgusCamEdgeEnhancementMode_Off:
+ l_iEeSettings_ptr->setEdgeEnhanceMode(EDGE_ENHANCE_MODE_OFF);
+ break;
+ case NvArgusCamEdgeEnhancementMode_Fast:
+ l_iEeSettings_ptr->setEdgeEnhanceMode(EDGE_ENHANCE_MODE_FAST);
+ break;
+ case NvArgusCamEdgeEnhancementMode_HighQuality:
+ l_iEeSettings_ptr->setEdgeEnhanceMode(EDGE_ENHANCE_MODE_HIGH_QUALITY);
+ break;
+ default :
+ l_iEeSettings_ptr->setEdgeEnhanceMode(EDGE_ENHANCE_MODE_OFF);
+ break;
+ }
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->edgeEnhancementModePropSet = FALSE;
+ }
+
+ if(src->edgeEnhancementStrengthPropSet)
+ {
+ l_iEeSettings_ptr->setEdgeEnhanceStrength(src->controls.EdgeEnhancementStrength);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->edgeEnhancementStrengthPropSet = FALSE;
+ }
+
+ if(src->aeAntibandingPropSet)
+ {
+ switch (src->controls.AeAntibandingMode)
+ {
+ case NvArgusCamAeAntibandingMode_Off:
+ l_iAutoControlSettings_ptr->setAeAntibandingMode(AE_ANTIBANDING_MODE_OFF);
+ break;
+ case NvArgusCamAeAntibandingMode_Auto:
+ l_iAutoControlSettings_ptr->setAeAntibandingMode(AE_ANTIBANDING_MODE_AUTO);
+ break;
+ case NvArgusCamAeAntibandingMode_50HZ:
+ l_iAutoControlSettings_ptr->setAeAntibandingMode(AE_ANTIBANDING_MODE_50HZ);
+ break;
+ case NvArgusCamAeAntibandingMode_60HZ:
+ l_iAutoControlSettings_ptr->setAeAntibandingMode(AE_ANTIBANDING_MODE_60HZ);
+ break;
+ default :
+ l_iAutoControlSettings_ptr->setAeAntibandingMode(AE_ANTIBANDING_MODE_OFF);
+ break;
+ }
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->aeAntibandingPropSet = FALSE;
+ }
+
+ if(src->gainRangePropSet == TRUE)
+ {
+ sensorModeAnalogGainRange.min() = src->controls.gainRange.low;
+ sensorModeAnalogGainRange.max() = src->controls.gainRange.high;
+ l_iRequestSourceSettings_ptr->setGainRange(sensorModeAnalogGainRange);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->gainRangePropSet = FALSE;
+ }
+
+ if(src->ispDigitalGainRangePropSet == TRUE)
+ {
+ ispDigitalGainRange.min() = src->controls.ispDigitalGainRange.low;
+ ispDigitalGainRange.max() = src->controls.ispDigitalGainRange.high;
+ l_iAutoControlSettings_ptr->setIspDigitalGainRange(ispDigitalGainRange);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->ispDigitalGainRangePropSet = FALSE;
+ }
+
+ if(src->exposureTimePropSet == TRUE)
+ {
+ limitExposureTimeRange.min() = src->controls.exposureTimeRange.low;
+ limitExposureTimeRange.max() = src->controls.exposureTimeRange.high;
+ l_iRequestSourceSettings_ptr->setExposureTimeRange(limitExposureTimeRange);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->exposureTimePropSet = FALSE;
+ }
+
+ if(src->aeRegionPropSet == TRUE)
+ {
+ std::vector < AcRegion > AeRegion;
+ AcRegion ae(src->controls.AeRegion.left(), src->controls.AeRegion.top(),
+ src->controls.AeRegion.right(), src->controls.AeRegion.bottom(),
+ src->controls.AeRegion.weight());
+ AeRegion.push_back(ae);
+ GST_ARGUS_PRINT("Setting AeRegion on the fly: %d %d %d %d %f \n",
+ AeRegion[0].left(), AeRegion[0].top(), AeRegion[0].right(),
+ AeRegion[0].bottom(), AeRegion[0].weight());
+ l_iAutoControlSettings_ptr->setAeRegions(AeRegion);
+ l_iCaptureSession->repeat(l_captureRequest);
+ src->aeRegionPropSet = FALSE;
+ }
+
+ // Use the IFrame interface to print out the frame number/timestamp, and
+ // to provide access to the Image in the Frame.
+ IFrame *iFrame = interface_cast