Compare commits

..

1 Commits

Author SHA1 Message Date
svcmobrel-release
740ff74531 Updating prebuilts and/or headers
6bafa48f47ad43d33ee446cf86f2b1da134f7868 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_asound_common.h
c028fa403772288daf002520356e8e18cce5cb06 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgstplayer.h
33a285339d714d5546cddb92a710e418853470aa - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_asound_common.c
9b47978b5f3b6672dd4d6ad5ebe80c9b945a7eba - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_x11_common.c
599544266262509705c60ca9e8d2c8ade3bdfc30 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgstplayer.c
aaafd7fd4c0214a52bf73dd2a0ba0af08c675b85 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_x11_common.h
8531d3b2fb38ae84efeaadf6cc177e1e2b07a90b - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgstcapture.h
39d7bace9939d38f221edd9f87dc8e8dab2c2365 - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgstcapture.c
a5bdf6935960973677a005d9d28a04c023f5ec6f - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgst_x11_common.c
87556b6e7da0ec3865546f10b7a58959cd8c6bfc - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgst_x11_common.h

Change-Id: I7f51606e0777d688ea592cc5066a8a58f0c212a9
2024-09-06 00:00:49 -07:00
13 changed files with 76 additions and 943 deletions

View File

@@ -1,15 +1,12 @@
Updating prebuilts and/or headers
6bafa48f47ad43d33ee446cf86f2b1da134f7868 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_asound_common.h
d2d35088439d36583769e88ae1e00b60c476fd4d - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgstplayer.h
c028fa403772288daf002520356e8e18cce5cb06 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgstplayer.h
33a285339d714d5546cddb92a710e418853470aa - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_asound_common.c
582a142d1a3098aed3bb4c8f7329e8cdac7b0ed8 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_x11_common.c
8e85d7eb34d7f411e8269a9de58958ff84385d02 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgstplayer.c
9b47978b5f3b6672dd4d6ad5ebe80c9b945a7eba - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_x11_common.c
599544266262509705c60ca9e8d2c8ade3bdfc30 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgstplayer.c
aaafd7fd4c0214a52bf73dd2a0ba0af08c675b85 - nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgst_x11_common.h
7152d9928416f55c6879ec0170a495f71eabf80d - nvgstapps_src/nvgst_sample_apps/nvgstipctestapp-1.0/Makefile.public
6913ed4a984b2247d1373f0e1b395c582fefb2bd - nvgstapps_src/nvgst_sample_apps/nvgstipctestapp-1.0/LICENSE
f10c2dee4b1065e7c2dccbb6f32390dd6e3c1491 - nvgstapps_src/nvgst_sample_apps/nvgstipctestapp-1.0/nvgstipctestapp.c
4d1b5a02533b224281502e7197e7945faa2885f5 - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgstcapture.h
68e327a1f71ca2687f4aa9f223bb6be83bcf5e5c - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgstcapture.c
4b5054ba7e2715bddd948e4603445230ce1cf350 - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgst_x11_common.c
8531d3b2fb38ae84efeaadf6cc177e1e2b07a90b - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgstcapture.h
39d7bace9939d38f221edd9f87dc8e8dab2c2365 - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgstcapture.c
a5bdf6935960973677a005d9d28a04c023f5ec6f - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgst_x11_common.c
87556b6e7da0ec3865546f10b7a58959cd8c6bfc - nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgst_x11_common.h

View File

@@ -6,7 +6,7 @@ ARM architecture.
--------------------------------------------------------------------------------
Prerequisites for nvgst-1.0 applications
--------------------------------------------------------------------------------
For nvgstcapture-1.0, nvgstplayer-1.0 and nvgstipctestapp-1.0 applications:
For nvgstcapture-1.0 and nvgstplayer-1.0 applications:
* You must install GStreamer-1.0 on the target board using apt-get, as follows:
@@ -56,22 +56,9 @@ For nvgstcapture-1.0, nvgstplayer-1.0 and nvgstipctestapp-1.0 applications:
$(pkg-config --cflags --libs gstreamer-1.0 gstreamer-plugins-base-1.0 \
gstreamer-pbutils-1.0 gstreamer-video-1.0 x11 xext alsa)
--------------------------------------------------------------------------------
Procedure to compile nvgstipctestapp-1.0:
--------------------------------------------------------------------------------
On the target, execute the following commands:
cd nvgstapps_src/nvgst_sample_apps/nvgstipctestapp-1.0
gcc nvgstipctestapp.c -o nvgstipctestapp-1.0 \
$(pkg-config --cflags --libs gstreamer-1.0 gstreamer-plugins-base-1.0 \
gstreamer-pbutils-1.0 gstreamer-video-1.0 x11 gstreamer-video-1.0 gstreamer-app-1.0) -lm
* For nvgstcapture-1.0 usage, refer to
nvgstapps_src/nvgst_sample_apps/nvgstcapture-1.0/nvgstcapture-1.0_README.txt
* For nvgstplayer-1.0 usage, refer to
nvgstapps_src/nvgst_sample_apps/nvgstplayer-1.0/nvgstplayer-1.0_README.txt
* For nvgstipctestapp-1.0 usage, refer to
nvgstapps_src/nvgst_sample_apps/nvgstipctestapp-1.0/nvgstipctestapp-1.0_README.txt

View File

@@ -1,6 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -14,7 +13,7 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
@@ -22,7 +21,6 @@
*/
#include "nvgst_x11_common.h"
#include <stdbool.h>
void
nvgst_x11_init (displayCtx * dpyCtx)
@@ -54,7 +52,7 @@ saver_off (displayCtx * dpyCtx)
{
int nothing;
if (DPMSQueryExtension (dpyCtx->mDisplay, &nothing, &nothing)) {
BOOL enabled = false;
BOOL enabled;
CARD16 powerLevel;
DPMSInfo (dpyCtx->mDisplay, &powerLevel, &enabled);
@@ -77,7 +75,7 @@ saver_on (displayCtx * dpyCtx)
{
int nothing;
if (DPMSQueryExtension (dpyCtx->mDisplay, &nothing, &nothing)) {
BOOL enabled = false;
BOOL enabled;
CARD16 powerLevel;
DPMSInfo (dpyCtx->mDisplay, &powerLevel, &enabled);

View File

@@ -1,6 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2014-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
* Copyright (c) 2014-2023, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -14,7 +13,7 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
@@ -388,7 +387,7 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
case GST_MESSAGE_STATE_CHANGED:
{
GstState old = GST_STATE_NULL, new_state = GST_STATE_NULL, pending = GST_STATE_NULL;
GstState old, new_state, pending;
gst_message_parse_state_changed (msg, &old, &new_state, &pending);
@@ -519,7 +518,7 @@ static void
write_vsnap_buffer (GstElement * fsink,
GstBuffer * buffer, GstPad * pad, gpointer udata)
{
GstMapInfo info = GST_MAP_INFO_INIT;
GstMapInfo info;
if (gst_buffer_map (buffer, &info, GST_MAP_READ)) {
if (info.size) {
@@ -1405,12 +1404,14 @@ invalid_input:
void
set_capture_device_node (void)
{
gchar *fname = g_strdup_printf ("/dev/video%s", app->cap_dev_node);
gchar *fname = g_strndup ("/dev/video", 12);
fname = strcat (fname, app->cap_dev_node);
if (app->vidcap_device && access (fname, F_OK) != -1) {
g_free (app->vidcap_device);
app->vidcap_device = NULL;
app->vidcap_device = g_strdup_printf ("/dev/video%s", app->cap_dev_node);
app->vidcap_device = g_strndup ("/dev/video", 12);
app->vidcap_device = strcat (app->vidcap_device, app->cap_dev_node);
} else {
g_print ("%s does not exist\n",fname);
}
@@ -1788,9 +1789,6 @@ capture_init_params (void)
app->x_cond = malloc(sizeof(*(app->x_cond)));
g_cond_init (app->x_cond);
app->x_event_thread = NULL;
g_atomic_int_set(&app->x_thread_should_exit, FALSE);
app->native_record = GST_PAD_PROBE_DROP;
app->file_name = g_strdup (NVGST_DEFAULT_FILENAME);
app->vidcap_device = g_strdup (NVGST_DEFAULT_VIDCAP_DEVICE);
@@ -2042,7 +2040,7 @@ static void
cam_image_captured (GstElement * fsink,
GstBuffer * buffer, GstPad * pad, gpointer udata)
{
GstMapInfo info = GST_MAP_INFO_INIT;
GstMapInfo info;
if (app->capcount == 0) {
if (gst_buffer_map (buffer, &info, GST_MAP_READ)) {
@@ -3280,7 +3278,7 @@ create_vid_enc_bin (void)
}
else
{
sinkpad = gst_element_request_pad_simple (app->ele.muxer, "video_%u");
sinkpad = gst_element_get_request_pad (app->ele.muxer, "video_%u");
}
if (!sinkpad || !srcpad) {
@@ -4147,7 +4145,7 @@ exit_capture (gpointer data)
static void
nvgst_handle_xevents ()
{
XEvent e = {0};
XEvent e;
Atom wm_delete;
displayCtx *dpyCtx = &app->disp;
@@ -4169,17 +4167,13 @@ static gpointer
nvgst_x_event_thread (gpointer data)
{
g_mutex_lock (app->lock);
while (app->disp.window && !g_atomic_int_get(&app->x_thread_should_exit)) {
while (app->disp.window) {
nvgst_handle_xevents ();
/* Wait for 50ms or until signaled to exit */
gint64 end_time = g_get_monotonic_time() + 50000; /* 50ms timeout */
g_cond_wait_until(app->x_cond, app->lock, end_time);
}
/* Only unlock if we still have a valid lock */
if (app->lock)
g_mutex_unlock(app->lock);
g_usleep(G_USEC_PER_SEC / 20);
g_mutex_lock(app->lock);
}
g_mutex_unlock(app->lock);
return NULL;
}
#endif
@@ -4595,13 +4589,16 @@ main (int argc, char *argv[])
if(app->encset.bitrate != 0)
is_user_bitrate = 1;
if ((access (NVGST_DEFAULT_V4L2_NVENC_DEVICE_PATH, F_OK) != 0) &&
(access (NVGST_DEFAULT_V4L2_NVENC_DEVICE_PATH_ALT, F_OK) != 0))
FILE *fp;
fp = fopen(NVGST_DEFAULT_V4L2_NVENC_DEVICE_PATH, "r");
if (fp == NULL)
{
if (app->encset.video_enc != FORMAT_H264_SW)
g_print("Codec not supported. Falling back to opensrc H264 encoder\n");
app->encset.video_enc = FORMAT_H264_SW;
}
if (fp)
fclose(fp);
g_option_context_free (ctx);
@@ -4759,20 +4756,12 @@ done:
g_main_loop_unref (loop);
#if !GUI
/* Properly signal X event thread to exit and wait for it */
if (app->lock && app->x_event_thread) {
g_mutex_lock (app->lock);
/* Signal the X event thread to exit */
g_atomic_int_set(&app->x_thread_should_exit, TRUE);
g_cond_signal(app->x_cond); /* Wake up the waiting thread immediately */
if (app->disp.window)
nvgst_destroy_window (&app->disp);
g_mutex_unlock (app->lock);
g_mutex_lock (app->lock);
if (app->disp.window)
nvgst_destroy_window (&app->disp);
g_mutex_unlock (app->lock);
/* Join the thread before destroying the mutex */
g_thread_join(app->x_event_thread);
app->x_event_thread = NULL;
}
g_thread_join(app->x_event_thread);
if (app->disp.mDisplay)
nvgst_x11_uninit (&app->disp);
@@ -4780,19 +4769,16 @@ done:
if (app->lock) {
g_mutex_clear (app->lock);
g_free (app->lock);
app->lock = NULL;
}
if (app->cond) {
g_cond_clear (app->cond);
g_free (app->cond);
app->cond = NULL;
}
if (app->x_cond) {
g_cond_clear (app->x_cond);
g_free (app->x_cond);
app->x_cond = NULL;
}
@@ -4802,6 +4788,9 @@ done:
g_free (app->csi_options_argus);
g_free (app->overlayConfig);
g_free (app->eglConfig);
g_free (app->lock);
g_free (app->cond);
g_free (app->x_cond);
NVGST_INFO_MESSAGE ("Camera application will now exit");

View File

@@ -1,6 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2014-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
* Copyright (c) 2014-2023, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -14,7 +13,7 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
@@ -95,7 +94,6 @@ int dummy_func ()
#define NVGST_DEFAULT_CAPTURE_FPS 30
#define NVGST_DEFAULT_VIDCAP_DEVICE "/dev/video0"
#define NVGST_DEFAULT_V4L2_NVENC_DEVICE_PATH "/dev/nvhost-msenc"
#define NVGST_DEFAULT_V4L2_NVENC_DEVICE_PATH_ALT "/dev/v4l2-nvenc"
#define DEFAULT_LOCATION "/dev/null"
#define SUCCESS 0
@@ -663,7 +661,6 @@ typedef struct
GCond *x_cond;
GThread *reset_thread;
GThread *x_event_thread;
gint x_thread_should_exit; // Flag to signal X event thread to exit (atomic)
CamRes capres;
EncSet encset;

View File

@@ -1,20 +0,0 @@
SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: MIT
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -1,111 +0,0 @@
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
################################################################################
SRC:=nvgstipctestapp.c
PKGS := gstreamer-1.0 \
gstreamer-base-1.0 \
gstreamer-video-1.0 \
gstreamer-allocators-1.0 \
gstreamer-audio-1.0 \
gstreamer-app-1.0 \
glib-2.0 \
gobject-2.0 \
gthread-2.0 \
gmodule-2.0 \
# Clear the flags from env
CFLAGS :=
LDFLAGS :=
# Verbose flag
ifeq ($(VERBOSE), 1)
AT =
else
AT = @
endif
# ARM ABI of the target platform
ifeq ($(TEGRA_ARMABI),)
TEGRA_ARMABI ?= aarch64-linux-gnu
endif
# Location of the target rootfs
ifeq ($(shell uname -m), aarch64)
TARGET_ROOTFS :=
else
ifeq ($(TARGET_ROOTFS),)
$(error Please specify the target rootfs path if you are cross-compiling)
endif
endif
ifeq ($(shell uname -m), aarch64)
CROSS_COMPILE :=
else
CROSS_COMPILE ?= aarch64-unknown-linux-gnu-
endif
AS = $(AT) $(CROSS_COMPILE)as
LD = $(AT) $(CROSS_COMPILE)ld
CC = $(AT) $(CROSS_COMPILE)gcc
AR = $(AT) $(CROSS_COMPILE)ar
NM = $(AT) $(CROSS_COMPILE)nm
STRIP = $(AT) $(CROSS_COMPILE)strip
OBJCOPY = $(AT) $(CROSS_COMPILE)objcopy
OBJDUMP = $(AT) $(CROSS_COMPILE)objdump
# Specify the logical root directory for headers and libraries.
ifneq ($(TARGET_ROOTFS),)
LDFLAGS += \
-Wl,-rpath-link=$(TARGET_ROOTFS)/usr/lib \
-Wl,-rpath-link=$(TARGET_ROOTFS)/lib/$(TEGRA_ARMABI) \
-Wl,-rpath-link=$(TARGET_ROOTFS)/usr/lib/$(TEGRA_ARMABI)/gstreamer-1.0
endif
# All common dependent libraries
LDFLAGS += \
-lpthread \
-lm \
-ldl \
-L"$(TARGET_ROOTFS)/usr/lib" \
-L"$(TARGET_ROOTFS)/usr/lib/$(TEGRA_ARMABI)" \
-L"$(TARGET_ROOTFS)/usr/lib/$(TEGRA_ARMABI)/gstreamer-1.0"
OBJS := $(SRC:.c=.o)
CFLAGS +=`pkg-config --cflags $(PKGS)`
LDFLAGS +=`pkg-config --libs $(PKGS)`
APP:=nvgstipctestapp-1.0
all: $(APP)
%.o: %.c
@echo "Compiling: $<"
$(CC) -c $< $(CFLAGS) -o $@
$(APP): $(OBJS)
@echo "Linking: $@"
$(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS)
clean:
$(AT)rm -rf $(APP) $(OBJS)

View File

@@ -1,55 +0,0 @@
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
NvGstIpcTestApp Usage (command: ./nvgstipctestapp --help)
=======
=> PREREQUISITES:
1. You must install GStreamer-1.0 on the target board using apt-get, as follows:
sudo apt-get install gstreamer1.0-tools gstreamer1.0-alsa gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad gstreamer1.0-libav
2. Execute the following commands on the target board's Ubuntu command line before starting the player:
export DISPLAY=:0
xinit &
NvGstIpcTestApp Usage
-----------------------------------------------
Run with the command line.
$ nvgstipctestapp server <rtsp_url> <socket_path>
$ nvgstipctestapp client <socket_path>
e.g.
$ nvgstipctestapp server rtsp://127.0.0.1/video1 /tmp/test1
$ nvgstipctestapp client /tmp/test1
This sample act as either server or client based on command line arguments.
The server accepts H.264/H.265 video stream RTSP URL and IPC socket path
as input. It does the decoding of the stream and listens for the connection
on the IPC socket path. It sends decoded data over IPC to the connected client.
The client accepts IPC socket path as input. It sends connection request to the
server. Once server accepts the request, it starts receiving the decoded data
over IPC which is further pushed into the pipeline.

View File

@@ -1,634 +0,0 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <gst/gst.h>
#include <glib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#define MAX_SOURCE_BINS 32
#define CONFIG_CSI_SOURCE_WIDTH 1920
#define CONFIG_CSI_SOURCE_HEIGHT 1080
#define CONFIG_CSI_SOURCE_FPS_N 30
#define CONFIG_CSI_SOURCE_FPS_D 1
/* NVIDIA Decoder source pad memory feature. This feature signifies that source
* pads having this capability will push GstBuffers containing cuda buffers. */
#define GST_CAPS_FEATURES_NVMM "memory:NVMM"
typedef struct
{
gchar *uri;
gchar *socket_path;
guint cam_src;
guint sensor_id;
guint bus_id;
GstElement *pipeline;
void *appCtx;
} NvIpcServerPipeline;
typedef struct
{
gchar *socket_path[MAX_SOURCE_BINS];
guint bus_id;
GstElement *pipeline;
void *appCtx;
} NvIpcClientPipeline;
typedef struct
{
GMainLoop *loop;
NvIpcServerPipeline ipcserver[MAX_SOURCE_BINS];
NvIpcClientPipeline ipcclient;
gboolean quit;
} AppCtx;
static gboolean
bus_call (GstBus * bus, GstMessage * msg, gpointer user_data)
{
GMainLoop *loop = (GMainLoop *) user_data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("End of stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_WARNING:
{
gchar *debug;
GError *error = NULL;
gst_message_parse_warning (msg, &error, &debug);
g_printerr ("WARNING from element %s: %s\n",
GST_OBJECT_NAME (msg->src), error->message);
g_free (debug);
g_printerr ("Warning: %s\n", error->message);
g_error_free (error);
break;
}
case GST_MESSAGE_ERROR:
{
gchar *debug;
GError *error = NULL;
gst_message_parse_error (msg, &error, &debug);
g_printerr ("ERROR from element %s: %s\n",
GST_OBJECT_NAME (msg->src), error->message);
if (debug)
g_printerr ("Error details: %s\n", debug);
g_free (debug);
g_error_free (error);
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_STATE_CHANGED:{
GstState oldstate = GST_STATE_NULL, newstate = GST_STATE_NULL;
gst_message_parse_state_changed (msg, &oldstate, &newstate, NULL);
switch (newstate) {
case GST_STATE_PLAYING:
g_print ("Pipeline running\n");
break;
case GST_STATE_PAUSED:
if (oldstate == GST_STATE_PLAYING) {
g_print ("Pipeline paused\n");
}
break;
case GST_STATE_READY:
if (oldstate == GST_STATE_NULL) {
g_print ("Pipeline ready\n");
} else {
g_print ("Pipeline stopped\n");
}
break;
case GST_STATE_NULL:
g_print ("Pipeline Null\n");
g_main_loop_quit (loop);
break;
default:
break;
}
break;
}
default:
break;
}
return TRUE;
}
static void
cb_newpad (GstElement * decodebin, GstPad * decoder_src_pad, gpointer data)
{
GstCaps *caps = gst_pad_get_current_caps (decoder_src_pad);
if (!caps) {
caps = gst_pad_query_caps (decoder_src_pad, NULL);
}
const GstStructure *str = gst_caps_get_structure (caps, 0);
const gchar *name = gst_structure_get_name (str);
GstElement *source_bin = (GstElement *) data;
GstCapsFeatures *features = gst_caps_get_features (caps, 0);
/* Need to check if the pad created by the decodebin is for video and not
* audio. */
if (!strncmp (name, "video", 5)) {
/* Link the decodebin pad only if decodebin has picked nvidia
* decoder plugin nvdec_*. We do this by checking if the pad caps contain
* NVMM memory features. */
if (gst_caps_features_contains (features, GST_CAPS_FEATURES_NVMM)) {
/* Get the source bin ghost pad */
GstPad *bin_ghost_pad = gst_element_get_static_pad (source_bin, "src");
if (!gst_ghost_pad_set_target (GST_GHOST_PAD (bin_ghost_pad),
decoder_src_pad)) {
g_printerr ("Failed to link decoder src pad to source bin ghost pad\n");
}
gst_object_unref (bin_ghost_pad);
} else {
g_printerr ("Error: Decodebin did not pick nvidia decoder plugin.\n");
}
}
}
static void
decodebin_child_added (GstChildProxy * child_proxy, GObject * object,
gchar * name, gpointer user_data)
{
g_print ("Decodebin child added: %s\n", name);
if (g_strrstr (name, "decodebin") == name) {
g_signal_connect (G_OBJECT (object), "child-added",
G_CALLBACK (decodebin_child_added), user_data);
}
}
static GstElement *
create_source_bin (guint index, gchar * uri)
{
GstElement *bin = NULL, *uri_decode_bin = NULL;
gchar bin_name[16] = { };
g_snprintf (bin_name, 15, "source-bin-%02d", index);
/* Create a source GstBin to abstract this bin's content from the rest of the
* pipeline */
bin = gst_bin_new (bin_name);
/* Source element for reading from the uri.
* We will use decodebin and let it figure out the container format of the
* stream and the codec and plug the appropriate demux and decode plugins. */
uri_decode_bin = gst_element_factory_make ("uridecodebin", NULL);
if (!bin || !uri_decode_bin) {
g_printerr ("One element in source bin could not be created.\n");
return NULL;
}
/* We set the input uri to the source element */
g_object_set (G_OBJECT (uri_decode_bin), "uri", uri, NULL);
/* Connect to the "pad-added" signal of the decodebin which generates a
* callback once a new pad for raw data has beed created by the decodebin */
g_signal_connect (G_OBJECT (uri_decode_bin), "pad-added",
G_CALLBACK (cb_newpad), bin);
g_signal_connect (G_OBJECT (uri_decode_bin), "child-added",
G_CALLBACK (decodebin_child_added), bin);
gst_bin_add (GST_BIN (bin), uri_decode_bin);
/* We need to create a ghost pad for the source bin which will act as a proxy
* for the video decoder src pad. The ghost pad will not have a target right
* now. Once the decode bin creates the video decoder and generates the
* cb_newpad callback, we will set the ghost pad target to the video decoder
* src pad. */
if (!gst_element_add_pad (bin, gst_ghost_pad_new_no_target ("src",
GST_PAD_SRC))) {
g_printerr ("Failed to add ghost pad in source bin\n");
return NULL;
}
return bin;
}
static GstElement*
create_csi_source_bin (guint index, guint sensor_id) {
GstElement *bin = NULL, *src_elem = NULL, *caps_filter = NULL;
GstPad *source_pad = NULL, *ghost_sourcepad = NULL;
GstCaps *caps = NULL;
gchar bin_name[16] = {};
g_snprintf(bin_name, 15, "source-bin-%02d", index);
/* Create a source GstBin to abstract this bin's content from the rest of the
* pipeline */
bin = gst_bin_new(bin_name);
src_elem = gst_element_factory_make ("nvarguscamerasrc", "csi_src_elem");
if (!bin || !src_elem) {
g_printerr("One element in source bin could not be created.\n");
return NULL;
}
g_object_set (G_OBJECT (src_elem), "sensor-id", sensor_id, NULL);
caps_filter = gst_element_factory_make("capsfilter", "src_cap_filter");
if (!caps_filter) {
g_printerr("Could not create 'src_cap_filter'");
return NULL;
}
caps = gst_caps_new_simple(
"video/x-raw", "format", G_TYPE_STRING, "NV12", "width", G_TYPE_INT,
CONFIG_CSI_SOURCE_WIDTH, "height", G_TYPE_INT, CONFIG_CSI_SOURCE_HEIGHT,
"framerate", GST_TYPE_FRACTION, CONFIG_CSI_SOURCE_FPS_N,
CONFIG_CSI_SOURCE_FPS_D, NULL);
GstCapsFeatures *feature = NULL;
feature = gst_caps_features_new ("memory:NVMM", NULL);
gst_caps_set_features (caps, 0, feature);
g_object_set (G_OBJECT (caps_filter), "caps", caps, NULL);
gst_bin_add_many (GST_BIN (bin), src_elem, caps_filter, NULL);
if (!gst_element_link_many (src_elem, caps_filter, NULL)) {
g_printerr ("Elements could not be linked. Exiting.\n");
gst_caps_unref (caps);
return NULL;
}
source_pad = gst_element_get_static_pad (caps_filter, "src");
ghost_sourcepad = gst_ghost_pad_new ("src", source_pad);
gst_pad_set_active (ghost_sourcepad, TRUE);
if (!gst_element_add_pad (bin, ghost_sourcepad)) {
g_printerr ("Failed to add ghost pad in source bin\n");
gst_caps_unref (caps);
gst_object_unref (source_pad);
return NULL;
}
gst_caps_unref (caps);
gst_object_unref (source_pad);
return bin;
}
static GstElement *
create_ipc_source_bin (NvIpcClientPipeline *ipcclient, guint index, gchar *socket_path)
{
GstElement *bin = NULL, *nvunixfdsrc = NULL, *capsfilter = NULL, *queue = NULL;
GstPad *source_pad = NULL, *ghost_sourcepad = NULL;
gchar bin_name[16] = { };
ipcclient->socket_path[index] = strdup(socket_path);
g_snprintf (bin_name, 15, "source-bin-%02d", index);
/* Create a source GstBin to abstract this bin's content from the rest of the
* pipeline */
bin = gst_bin_new (bin_name);
nvunixfdsrc = gst_element_factory_make ("nvunixfdsrc", NULL);
capsfilter = gst_element_factory_make ("capsfilter", NULL);
queue = gst_element_factory_make ("queue", NULL);
if (!bin || !nvunixfdsrc || !capsfilter || !queue) {
g_printerr ("One element in source bin could not be created.\n");
return NULL;
}
GstCaps* caps = gst_caps_new_simple ("video/x-raw",
"format", G_TYPE_STRING, "NV12", NULL);
GstCapsFeatures *feature = NULL;
feature = gst_caps_features_new ("memory:NVMM", NULL);
gst_caps_set_features (caps, 0, feature);
g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL);
gst_caps_unref (caps);
g_object_set (G_OBJECT(nvunixfdsrc), "socket-path", ipcclient->socket_path[index], NULL);
g_object_set (G_OBJECT(nvunixfdsrc), "buffer-timestamp-copy", TRUE, NULL);
gst_bin_add_many (GST_BIN (bin), nvunixfdsrc, capsfilter, queue, NULL);
if (!gst_element_link_many(nvunixfdsrc, capsfilter, queue, NULL)) {
g_printerr ("Failed to link in source bin\n");
return NULL;
}
source_pad = gst_element_get_static_pad (queue, "src");
ghost_sourcepad = gst_ghost_pad_new ("src", source_pad);
gst_pad_set_active (ghost_sourcepad, TRUE);
if (!gst_element_add_pad (bin, ghost_sourcepad)) {
g_printerr ("Failed to add ghost pad in source bin\n");
return NULL;
}
gst_object_unref (source_pad);
return bin;
}
static int
create_client_pipeline (int argc, char *argv[])
{
AppCtx appCtx;
GMainLoop *loop = NULL;
GstElement *pipeline = NULL, *compositor = NULL, *sink = NULL, *fpssink = NULL;
GstBus *bus = NULL;
guint bus_watch_id;
guint i =0, num_sources = 0;
guint tiler_rows, tiler_columns, tiler_row, tiler_xpos, tiler_ypos,
tiler_column, tiler_width, tiler_height;
gboolean PERF_MODE = g_getenv("NV_IPC_TEST_PERF_MODE") &&
!g_strcmp0(g_getenv("NV_IPC_TEST_PERF_MODE"), "1");
memset(&appCtx, 0, sizeof(AppCtx));
appCtx.loop = loop = g_main_loop_new (NULL, FALSE);
/* Create gstreamer elements */
pipeline = gst_pipeline_new (NULL);
compositor = gst_element_factory_make ("nvcompositor", NULL);
g_object_set (G_OBJECT (compositor), "start-time-selection", 1, NULL);
if (!pipeline || !compositor) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
gst_bin_add (GST_BIN (pipeline), compositor);
num_sources = argc - 2;
tiler_row = 0;
tiler_column = 0;
tiler_rows = (guint) round (sqrt (num_sources));
tiler_columns = (guint) ceil (1.0 * num_sources / tiler_rows);
tiler_width = 1920/tiler_columns;
tiler_height = 1080/tiler_columns;
g_print("rows %d columns %d width %d height %d\n", tiler_rows, tiler_columns, tiler_width, tiler_height);
for (i = 0; i < num_sources; i++) {
GstPad *sinkpad, *srcpad;
gchar pad_name[16] = { };
GstElement *source_bin= NULL;
source_bin = create_ipc_source_bin (&appCtx.ipcclient, i, argv[i + 2]);
if (!source_bin) {
g_printerr ("Failed to create source bin. Exiting.\n");
return -1;
}
gst_bin_add (GST_BIN (pipeline), source_bin);
g_snprintf (pad_name, 15, "sink_%u", i);
sinkpad = gst_element_request_pad_simple (compositor, pad_name);
if (!sinkpad) {
g_printerr ("compositor request sink pad failed. Exiting.\n");
return -1;
}
srcpad = gst_element_get_static_pad (source_bin, "src");
if (!srcpad) {
g_printerr ("Failed to get src pad of source bin. Exiting.\n");
return -1;
}
if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK) {
g_printerr ("Failed to link source bin to stream muxer. Exiting.\n");
return -1;
}
tiler_xpos = (tiler_column * tiler_width);
tiler_ypos = (tiler_row * tiler_height);
g_print("xpos %d ypos %d width %d height %d\n", tiler_xpos, tiler_ypos, tiler_width, tiler_height);
if (tiler_column < tiler_columns - 1) {
tiler_column++;
} else {
tiler_row++;
tiler_column = 0;
}
g_object_set (sinkpad, "xpos", tiler_xpos, NULL);
g_object_set (sinkpad, "ypos", tiler_ypos, NULL);
g_object_set (sinkpad, "width", tiler_width, NULL);
g_object_set (sinkpad, "height", tiler_height, NULL);
gst_object_unref (srcpad);
gst_object_unref (sinkpad);
}
fpssink = gst_element_factory_make ("fpsdisplaysink", NULL);
if (!fpssink) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
if (PERF_MODE)
sink = gst_element_factory_make ("fakesink", NULL);
else
sink = gst_element_factory_make ("nv3dsink", NULL);
if (!sink) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
g_object_set (G_OBJECT (sink), "sync", FALSE, NULL);
g_object_set (G_OBJECT (fpssink), "text-overlay", FALSE, "sync", FALSE, "video-sink", sink, NULL);
/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
gst_bin_add_many (GST_BIN (pipeline), fpssink, NULL);
if (!gst_element_link_many (compositor, fpssink, NULL)) {
g_printerr ("Elements could not be linked. Exiting.\n");
return -1;
}
if (PERF_MODE)
g_signal_connect(pipeline, "deep-notify", G_CALLBACK( gst_object_default_deep_notify ), NULL );
/* Set the pipeline to "playing" state */
g_print ("Now playing:");
for (i = 0; i < num_sources; i++) {
g_print (" %s,", argv[i + 2]);
}
g_print ("\n");
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Wait till pipeline encounters an error or EOS */
g_print ("Running...\n");
g_main_loop_run (loop);
appCtx.quit = TRUE;
for (i = 0; i < num_sources; i++) {
g_free(appCtx.ipcclient.socket_path[i]);
}
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));
g_source_remove (bus_watch_id);
g_main_loop_unref (loop);
return 0;
}
static int
create_server_pipeline (int argc, char *argv[])
{
AppCtx appCtx;
guint i =0, num_sources = 0;
GMainLoop *loop = NULL;
char **arg = argv + 2;
gboolean PERF_MODE = g_getenv("NV_IPC_TEST_PERF_MODE") &&
!g_strcmp0(g_getenv("NV_IPC_TEST_PERF_MODE"), "1");
memset(&appCtx, 0, sizeof(AppCtx));
appCtx.loop = loop = g_main_loop_new (NULL, FALSE);
while (*arg) {
GstElement *pipeline = NULL;
GstBus *bus = NULL;
guint bus_watch_id;
GstElement *source_bin=NULL, *nvunixfdsink= NULL, *fpssink;
/* Create gstreamer elements */
appCtx.ipcserver[i].pipeline = pipeline = gst_pipeline_new (NULL);
if (!pipeline) {
g_printerr ("Failed to create pipeline. Exiting.\n");
return -1;
}
if (!strcmp(*arg, "-cs")) {
arg++;
appCtx.ipcserver[i].cam_src = atoi(*arg++);
appCtx.ipcserver[i].sensor_id = 0;
if (!strcmp(*arg, "-sid")) {
arg++;
appCtx.ipcserver[i].sensor_id = atoi(*arg++);
}
source_bin = create_csi_source_bin (i, appCtx.ipcserver[i].sensor_id);
} else {
appCtx.ipcserver[i].uri = strdup(*arg++);
source_bin = create_source_bin (i, appCtx.ipcserver[i].uri);
}
if (!source_bin) {
g_printerr ("Failed to create source bin. Exiting.\n");
return -1;
}
gst_bin_add (GST_BIN (pipeline), source_bin);
appCtx.ipcserver[i].socket_path = strdup(*arg++);
nvunixfdsink = gst_element_factory_make ("nvunixfdsink", NULL);
if (!nvunixfdsink) {
g_printerr ("Failed to create nvunixfdsink. Exiting.\n");
return -1;
}
fpssink = gst_element_factory_make ("fpsdisplaysink", NULL);
if (!fpssink) {
g_printerr ("Failed to create fpssink. Exiting.\n");
return -1;
}
gst_bin_add (GST_BIN (pipeline), fpssink);
g_object_set (G_OBJECT (fpssink), "text-overlay", FALSE, "sync", FALSE, "video-sink", nvunixfdsink, NULL);
g_object_set (G_OBJECT(nvunixfdsink), "sync", FALSE, NULL);
g_object_set (G_OBJECT(nvunixfdsink), "socket-path", appCtx.ipcserver[i].socket_path, NULL);
g_object_set (G_OBJECT(nvunixfdsink), "buffer-timestamp-copy", TRUE, NULL);
/* link the elements together */
if (!gst_element_link_many (source_bin, fpssink, NULL)) {
g_printerr ("Elements could not be linked. Exiting.\n");
return -1;
}
/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
appCtx.ipcserver[i].bus_id = bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
appCtx.ipcserver[i].appCtx = &appCtx;
if (PERF_MODE)
g_signal_connect(pipeline, "deep-notify", G_CALLBACK(gst_object_default_deep_notify), NULL);
i++;
num_sources++;
}
/* Set the pipeline to "playing" state */
g_print ("Now playing:");
for (i = 0; i < num_sources; i++) {
gst_element_set_state (appCtx.ipcserver[i].pipeline, GST_STATE_PLAYING);
g_print("server is started path: %s\n", appCtx.ipcserver[i].socket_path);
}
/* Wait till pipeline encounters an error or EOS */
g_print ("Running...\n");
g_main_loop_run (loop);
appCtx.quit = TRUE;
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
g_print ("Deleting pipeline\n");
for (i = 0; i < num_sources; i++) {
gst_element_set_state (appCtx.ipcserver[i].pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (appCtx.ipcserver[i].pipeline));
g_source_remove (appCtx.ipcserver[i].bus_id);
g_print("server is closed path: %s\n", appCtx.ipcserver[i].socket_path);
if (appCtx.ipcserver[i].uri)
g_free(appCtx.ipcserver[i].uri);
if (appCtx.ipcserver[i].socket_path)
g_free(appCtx.ipcserver[i].socket_path);
}
g_main_loop_unref (loop);
return 0;
}
int
main (int argc, char *argv[])
{
int ret = 0;
/* Check input arguments */
if (argc < 3) {
g_printerr ("Usage: %s <server> <rtsp_url> <socket_path>\n", argv[0]);
g_printerr ("OR: %s <server> -cs <camera_source> -sid <sensor_id> <socket_path> \n", argv[0]);
g_printerr ("OR: %s <client> <socket_path> \n", argv[0]);
g_printerr ("-cs : camera source to use (0 = CSI)\n");
g_printerr ("-sid : camera sensor ID value (0, 1, ...)\n");
return -1;
}
/* Standard GStreamer initialization */
gst_init (&argc, &argv);
if (strcmp(argv[1], "client") == 0) {
ret = create_client_pipeline(argc, argv);
} else {
ret = create_server_pipeline(argc, argv);
}
return ret;
}

View File

@@ -1,6 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
* Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -14,7 +13,7 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
@@ -22,7 +21,7 @@
*/
#include "nvgst_x11_common.h"
#include <stdbool.h>
Display *
nvgst_x11_init (displayCtx * dpyCtx)
@@ -49,7 +48,7 @@ saver_off (displayCtx * dpyCtx)
{
int nothing;
if (DPMSQueryExtension (dpyCtx->mDisplay, &nothing, &nothing)) {
BOOL enabled = false;
BOOL enabled;
CARD16 powerLevel;
DPMSInfo (dpyCtx->mDisplay, &powerLevel, &enabled);
@@ -72,7 +71,7 @@ saver_on (displayCtx * dpyCtx)
{
int nothing;
if (DPMSQueryExtension (dpyCtx->mDisplay, &nothing, &nothing)) {
BOOL enabled = false;
BOOL enabled;
CARD16 powerLevel;
DPMSInfo (dpyCtx->mDisplay, &powerLevel, &enabled);

View File

@@ -1,6 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
* Copyright (c) 2013-2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -14,7 +13,7 @@
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
@@ -294,8 +293,8 @@ on_video_sink_flow (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
GstEvent *ev = GST_PAD_PROBE_INFO_DATA (info);
if (GST_EVENT_TYPE (ev) == GST_EVENT_QOS) {
GstClockTimeDiff jitter = 0;
GstClockTime ts = GST_CLOCK_TIME_NONE;
GstClockTimeDiff jitter;
GstClockTime ts;
gst_event_parse_qos (ev, 0, NULL, &jitter, &ts);
@@ -560,7 +559,7 @@ on_input (GIOChannel * ichannel, GIOCondition cond, gpointer data)
goto ret;
} else if (g_str_has_prefix (tbuffer, "r") && yes1 && app->pipeline) {
GstState state = GST_STATE_NULL, pending = GST_STATE_NULL;
GstState state, pending;
in->interval = atof (tbuffer + 1) * GST_USECOND;
if (app->buffering) {
@@ -597,7 +596,7 @@ on_input (GIOChannel * ichannel, GIOCondition cond, gpointer data)
}
} else if (g_str_has_prefix (tbuffer, "p") && yes1 && app->pipeline) {
GstState state = GST_STATE_NULL, pending = GST_STATE_NULL;
GstState state, pending;
in->interval = atof (tbuffer + 1) * GST_USECOND;
if (app->buffering) {
@@ -613,7 +612,7 @@ on_input (GIOChannel * ichannel, GIOCondition cond, gpointer data)
res = NVGST_RET_ERR;
} else if (!g_strcmp0 (tbuffer, "spos") && app->running) {
GstClockTimeDiff pos = 0;
GstClockTimeDiff pos;
GstFormat format = GST_FORMAT_TIME;
if (gst_element_query_position (app->pipeline, format, &pos))
@@ -637,7 +636,7 @@ on_input (GIOChannel * ichannel, GIOCondition cond, gpointer data)
} else if (g_str_has_prefix (tbuffer, "f") &&
is_valid_number (tbuffer + 1, TRUE, TRUE)) {
GstClockTimeDiff pos = 0;
GstClockTimeDiff pos;
GstFormat format = GST_FORMAT_TIME;
if (gst_element_query_position (app->pipeline, format, &pos) &&
@@ -651,7 +650,7 @@ on_input (GIOChannel * ichannel, GIOCondition cond, gpointer data)
res = NVGST_RET_ERR;
}
} else if (g_str_has_prefix (tbuffer, "<")) {
GstClockTimeDiff pos = 0;
GstClockTimeDiff pos;
GstFormat format = GST_FORMAT_TIME;
if (gst_element_query_position (app->pipeline, format, &pos) &&
@@ -668,12 +667,12 @@ on_input (GIOChannel * ichannel, GIOCondition cond, gpointer data)
res = NVGST_RET_ERR;
}
} else if (g_str_has_prefix (tbuffer, ">")) {
GstClockTimeDiff pos = 0;
GstClockTimeDiff pos;
GstFormat format = GST_FORMAT_TIME;
if (gst_element_query_position (app->pipeline, format, &pos) &&
format == GST_FORMAT_TIME) {
GstClockTimeDiff dur = 0;
GstClockTimeDiff dur;
in->interval = pos + 10000000000ULL;
if (gst_element_query_duration (app->pipeline, format, &dur)
@@ -776,7 +775,7 @@ exec_ops (NvGstOperation operation)
GST_TIME_ARGS (seekPos));
if (GST_CLOCK_TIME_IS_VALID (in->attrs.segment_duration)) {
GstClockTimeDiff pos = 0;
GstClockTimeDiff pos;
GstFormat format = GST_FORMAT_TIME;
if (gst_element_query_position (app->pipeline, format, &pos) &&
@@ -904,8 +903,8 @@ goto_next_track (gpointer data)
destroy_current_track ();
}
if(app->stats)
stats_func(app->pfData.average_fps, app->pfData.frames_rendered, app->pfData.frames_dropped);
if(app->stats)
stats_func(app->pfData.average_fps, app->pfData.frames_rendered, app->pfData.frames_dropped);
NVGST_INFO_MESSAGE_V ("uriCount: %d, uriTotal: %d", (gint) app->uriCount,
(gint) app->uriTotal);
@@ -964,7 +963,7 @@ _tag_info (const GstTagList * list, const gchar * tag, gpointer data)
tagCount = gst_tag_list_get_tag_size (list, tag);
for (index = 0; index < tagCount; index++) {
gchar *pStr = NULL;
gchar *pStr;
if (gst_tag_get_type (tag) == G_TYPE_STRING) {
if (!gst_tag_list_get_string_index (list, tag, index, &pStr))
@@ -1047,7 +1046,7 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
GstElementFactory *factory = gst_element_get_factory (src);
const gchar *klass = gst_element_factory_get_klass (factory);
if (strstr (klass, "Decode") && strstr (klass, "Video")) {
guint64 frames_dropped = 0;
guint64 frames_dropped;
gst_message_parse_qos_stats (msg, NULL, NULL, &frames_dropped);
if (frames_dropped > app->pfData.frames_dropped_decoder) {
g_atomic_int_inc (&app->pfData.frames_dropped);
@@ -1060,7 +1059,7 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
break;
case GST_MESSAGE_WARNING:{
GError *gerror = NULL;
GError *gerror;
gchar *debug;
gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (msg));
@@ -1080,7 +1079,7 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
const GstStructure *str = gst_message_get_structure (msg);
if (gst_structure_has_name (str, "decoder-status")) {
guint DecodedMBs = 0, ConcealedMBs = 0, FrameDecodeTime = 0;
guint DecodedMBs, ConcealedMBs, FrameDecodeTime;
const gchar *decoder_error_str =
gst_structure_get_string (str, "DecodeErrorString");
@@ -1113,8 +1112,8 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
break;
case GST_MESSAGE_INFO:{
GError *gerror = NULL;
gchar *debug = NULL;
GError *gerror;
gchar *debug;
gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (msg));
gst_message_parse_info (msg, &gerror, &debug);
@@ -1129,7 +1128,7 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
break;
case GST_MESSAGE_BUFFERING:{
gint percent = 0;
gint percent;
gboolean busy = FALSE;
gst_message_parse_buffering (msg, &percent);
@@ -1161,7 +1160,7 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
} else {
if (!busy && app->buffering == FALSE) {
GstState state = GST_STATE_NULL, pending = GST_STATE_NULL;
GstState state, pending;
if (gst_element_get_state (app->pipeline, &state, &pending,
GST_CLOCK_TIME_NONE) == GST_STATE_CHANGE_FAILURE) {
@@ -1198,7 +1197,7 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
break;
case GST_MESSAGE_STATE_CHANGED:{
GstState old = GST_STATE_NULL, new = GST_STATE_NULL, pending = GST_STATE_NULL;
GstState old, new, pending;
inAttrs *in = app->input;
gst_message_parse_state_changed (msg, &old, &new, &pending);
@@ -1268,7 +1267,7 @@ bus_call (GstBus * bus, GstMessage * msg, gpointer data)
app->running = TRUE;
if (app->stats) {
GstClockTimeDiff duration = 0;
GstClockTimeDiff duration;
GstFormat format = GST_FORMAT_TIME;
fps_init (&app->pfData);
@@ -1518,10 +1517,6 @@ get_keys (GstCaps * caps, gchar * str, gchar * xstr)
}
}
pgp++;
if (val) {
g_free (val);
val = NULL;
}
}
}
}
@@ -1634,8 +1629,7 @@ create_element (GstCaps * caps, gchar * str, gchar * xstr, gchar ** skeys)
NVGST_WARNING_MESSAGE_V
("property %s does not exist in element %s, ignoring", prop[0],
tokens[0]);
g_free(prop[0]);
g_free(prop[1]);
g_strfreev (prop);
vtoken++;
continue;
}
@@ -2324,9 +2318,6 @@ autoplug_select (GstElement * dbin, GstPad * pad, GstCaps * caps,
g_strcmp0(name, "video/x-wmv") &&
g_strcmp0(name, "video/x-h263"))
app->svd = g_strconcat (NVGST_DEFAULT_VIDEO_DEC, NULL);
/* Use nvjpegdec for jpeg format */
else if (!app->svd && !g_strcmp0(name, "image/jpeg"))
app->svd = g_strconcat (NVGST_DEFAULT_IMAGE_DEC, NULL);
in->video_dec = get_keys (caps, NVGST_VIDEO_DEC, app->svd);
if (in->video_dec) {
@@ -2942,7 +2933,6 @@ setup_track (void)
if (!g_str_has_prefix (input->uri, "file://")) {
if (!(g_str_has_prefix (input->uri, "rtsp://") ||
g_str_has_prefix (input->uri, "http://") ||
g_str_has_prefix (input->uri, "https://") ||
g_str_has_prefix (input->uri, "udp://"))) {
uri = g_strconcat ("file://", input->uri, NULL);
} else
@@ -2981,8 +2971,6 @@ setup_track (void)
if (g_str_has_prefix (input->uri, "http://")) {
source = create_element (NULL, NVGST_HTTP_SRC, app->shttp, NULL);
} else if (g_str_has_prefix (input->uri, "https://")) {
source = create_element (NULL, NVGST_HTTP_SRC, app->shttp, NULL);
} else if (g_str_has_prefix (input->uri, "rtsp://")) {
source = create_element (NULL, NVGST_RTSP_SRC, app->srtsp, NULL);
} else if (g_str_has_prefix (input->uri, "udp://")) {
@@ -3250,7 +3238,6 @@ static void
nvgst_handle_xevents ()
{
XEvent e;
e.type = 0;
Atom wm_delete;
displayCtx *dpyCtx = &app->disp;
@@ -3291,12 +3278,14 @@ on_input_thread (gpointer data)
GQueue *que = g_queue_new ();
gchar *buffer = NULL;
int i = 0;
changemode (1);
while (!trd_exit) {
if (kbhit ()) {
if (buffer == NULL)
buffer = g_malloc (256);
buffer[i] = getchar ();
if (buffer[i] == 27) {
@@ -3341,10 +3330,8 @@ on_input_thread (gpointer data)
if (g_queue_is_empty (que)) {
g_queue_push_tail (que, buffer);
g_timeout_add (20, on2_input, que);
} else {
/*If queue is not empty then buffer is not pushed to queue, so it needs to be freed explicitly to avoid resource leak */
g_free(buffer);
}
buffer = NULL;
} else

View File

@@ -98,7 +98,6 @@ dummy_func ()
#define NVGST_DEFAULT_AUDIO_SINK "alsasink"
#define NVGST_DEFAULT_VIDEO_SINK "nv3dsink"
#define NVGST_DEFAULT_VIDEO_DEC "nvv4l2decoder"
#define NVGST_DEFAULT_IMAGE_DEC "nvjpegdec"
#define NVGST_DEFAULT_FILE_SRC "filesrc"
#define NVGST_DEFAULT_RTSP_SRC "rtspsrc"
#define NVGST_DEFAULT_HTTP_SRC "souphttpsrc"

View File

@@ -1 +1 @@
jetson_38.2
jetson_35.6