Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e61bf9fccf | |||
| 5d90da81d6 | |||
| 831efb2354 | |||
| e6eaa57dca | |||
|
|
dd6da41b0d | ||
|
|
b799d39427 | ||
| 7b92fb6073 | |||
|
|
f6fd5e50c8 | ||
| 11096da4e3 |
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,2 +1,8 @@
|
||||
*.log
|
||||
container/Drivers/*
|
||||
container/Drivers/*
|
||||
__pycache__
|
||||
*.yuv
|
||||
*.mp4
|
||||
*.csv
|
||||
*log*txt
|
||||
.env
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "GStreamerLatencyPlotter"]
|
||||
path = GStreamerLatencyPlotter
|
||||
url = https://github.com/podborski/GStreamerLatencyPlotter.git
|
||||
[submodule "gstAutotest"]
|
||||
path = gstAutotest
|
||||
url = https://vptyp.tech/git/vptyp/gstAutotest.git
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
from itertools import product
|
||||
|
||||
options = {
|
||||
"x264enc": {
|
||||
"bitrate" : ["10000", "20000", "5000"],
|
||||
"speed-preset" : ["ultrafast", "fast", "medium"],
|
||||
"tune": ["zerolatency"],
|
||||
"slices-threads": ["true", "false"],
|
||||
"b-adapt": ["true", "false"],
|
||||
"rc-lookahead": ["40", "0"],
|
||||
"ref": ["3", "0"]
|
||||
|
||||
},
|
||||
"nvh264enc" : {
|
||||
"bitrate" : ["10000", "20000", "5000"],
|
||||
"preset" : ["4", "5", "1"],
|
||||
"rc-lookahead" : ["0"],
|
||||
"rc-mode" : ["2", "0", "5"],
|
||||
"zerolatency": ["true", "false"],
|
||||
|
||||
},
|
||||
"nvv4l2h264enc": {
|
||||
"bitrate" : ["10000000", "20000000", "5000000"],
|
||||
"profile": ["0", "1", "2"],
|
||||
"preset-id": ["1", "2", "3"],
|
||||
"control-id": ["1", "2"],
|
||||
"tuning-info-id": ["4", "2"]
|
||||
}
|
||||
}
|
||||
|
||||
videos = [""]
|
||||
|
||||
testsource = "videotestsrc pattern=smpte"
|
||||
videosrc = ["filesrc location=", "! qtdemux ! h264parse ! avdec_h264"]
|
||||
|
||||
psnr_check = {
|
||||
"x264enc": "-pixel_format yuv420p -color_range pc",
|
||||
"nvh264enc": "-pixel_format nv12 -color_range tv",
|
||||
"nvv4l2h264enc": "-pixel_format yuv420p -color_range tv"
|
||||
}
|
||||
|
||||
formats = {
|
||||
"x264enc" : "I420",
|
||||
"nvh264enc" : "NV12",
|
||||
"nvv4l2h264enc": "I420"
|
||||
}
|
||||
|
||||
profiles = ["baseline", "main"]
|
||||
|
||||
def makeVideoSrc(idx):
|
||||
return videosrc[0] + videos[idx] + videosrc[1]
|
||||
|
||||
def generateEncoderStrings():
|
||||
global options
|
||||
result = dict()
|
||||
for encoder, value in options.items():
|
||||
result[encoder] = generate_combinations(value)
|
||||
return result
|
||||
|
||||
def generate_combinations(config_dict):
|
||||
"""
|
||||
Generate all combinations of values from a configuration dictionary.
|
||||
|
||||
Args:
|
||||
config_dict (dict): Dictionary with parameter names as keys and lists of values as values
|
||||
|
||||
Returns:
|
||||
list: List of strings containing all parameter combinations
|
||||
"""
|
||||
combinations = []
|
||||
|
||||
# Get the keys and values in consistent order
|
||||
keys = list(config_dict.keys())
|
||||
value_lists = [config_dict[key] for key in keys]
|
||||
|
||||
# Generate all combinations using itertools.product
|
||||
for combo in product(*value_lists):
|
||||
# Create a list of key=value strings
|
||||
param_strings = []
|
||||
for key, value in zip(keys, combo):
|
||||
param_strings.append(f"{key}={value}")
|
||||
|
||||
# Join all parameter strings with space separator
|
||||
combinations.append(" ".join(param_strings))
|
||||
|
||||
return combinations
|
||||
|
||||
def generateRecordString(options, ):
|
||||
pass
|
||||
|
||||
print(len(generateEncoderStrings()[""]))
|
||||
@ -1,85 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
# Idea is next:
|
||||
# on set of experiments we are calculating all latency information -> each element avg, std, max numbers, total is not calculated, because it requires
|
||||
# additional parsing for parallel branches (from tee)
|
||||
# Ideally we would write data to table
|
||||
|
||||
idxCache = dict()
|
||||
|
||||
def findWord(words, wordToSearch):
|
||||
global idxCache
|
||||
if wordToSearch in idxCache:
|
||||
for idx in idxCache[wordToSearch]:
|
||||
if words[idx].startswith(wordToSearch):
|
||||
return words[idx]
|
||||
for word in words:
|
||||
if word.startswith(wordToSearch):
|
||||
idx = words.index(word)
|
||||
if not wordToSearch in idxCache:
|
||||
idxCache[wordToSearch] = []
|
||||
idxCache[wordToSearch].append(idx)
|
||||
return words[idx]
|
||||
return ""
|
||||
|
||||
# taken with love from GStreamerLatencyPlotter implementation
|
||||
def readAndParse(filename):
|
||||
result = dict()
|
||||
|
||||
with open(filename, "r") as latencyFile:
|
||||
lines = latencyFile.readlines()
|
||||
for line in lines:
|
||||
if line.find("new format string") != -1:
|
||||
continue
|
||||
words = line.split()
|
||||
if not words[len(words) - 1].startswith("ts="):
|
||||
continue
|
||||
|
||||
def findAndRemove(wordToSearch):
|
||||
res = findWord(words, wordToSearch)
|
||||
res = res[res.find(")") + 1:len(res) - 1]
|
||||
return res
|
||||
|
||||
name = findWord(words, "element=(string)")
|
||||
if name == "":
|
||||
name = findWord(words, "src-element=(string)")
|
||||
if name == "":
|
||||
continue
|
||||
src = findAndRemove("src=(string)")
|
||||
name = name[name.find(")") + 1:len(name) - 1]
|
||||
if name not in result:
|
||||
result[name] = {"latency":[], "ts":[]}
|
||||
|
||||
timeWord = findWord(words, "time=(guint64)")
|
||||
tsWord = findWord(words, "ts=(guint64)")
|
||||
result[name]["latency"].append(int(timeWord[14:len(timeWord) - 1])/1e6) # time=(guint64)=14
|
||||
result[name]["ts"].append(int(tsWord[12:len(tsWord) - 1])/1e9) # ts=(guint64)=12
|
||||
return result
|
||||
|
||||
|
||||
def getLatencyTable(filename):
|
||||
parsed = readAndParse(filename)
|
||||
df = pd.DataFrame(parsed)
|
||||
print(df)
|
||||
latency_row = df.loc['latency']
|
||||
ts_list = df.loc['ts']
|
||||
|
||||
avg_latency = latency_row.apply(np.mean)
|
||||
median_latency = latency_row.apply(np.median)
|
||||
max_latency = latency_row.apply(np.max)
|
||||
std_latency = latency_row.apply(np.std)
|
||||
dt_max_latency = dict()
|
||||
min_timestamp = ts_list.apply(np.min)
|
||||
|
||||
for column in df.columns:
|
||||
max_index = np.argmax(latency_row[column])
|
||||
dt = ts_list[column][max_index] - min_timestamp.min()
|
||||
dt_max_latency[column] = dt
|
||||
|
||||
df_dt_max = pd.Series(dt_max_latency)
|
||||
resultDf = pd.concat([df_dt_max, max_latency, avg_latency, median_latency, std_latency], axis=1)
|
||||
resultDf.columns = ['dTmax', 'max', 'avg', 'median', 'std']
|
||||
print(resultDf)
|
||||
|
||||
getLatencyTable("latency_traces-x264enc-big-pr-main.log")
|
||||
17
README.md
17
README.md
@ -4,6 +4,23 @@ In this repository collected different pipelines with workarounds for zero laten
|
||||
Main idea for now is using of docker container with running Ubuntu 22.04 distro inside, mostly for testing purposes.
|
||||
We must passthrough in this case GPU and Decklink devices for this purpose it is necessary to have similar driver versions on host and container system, otherwise it just will not work.
|
||||
Component diagram showing what we want to achieve
|
||||
|
||||
## How to run
|
||||
|
||||
It is suggested to use `nohup` for background execution.
|
||||
|
||||
```sh
|
||||
# create venv
|
||||
$ python3 -m venv ./.Python
|
||||
$ . .Python/bin/activate
|
||||
$ pip install -r gstAutotest/requirements.txt
|
||||
$ nohup python3 ./gstAutotest/gstreamerAutotest.py -c="./gstAutotest/autotest-conf.yaml" &
|
||||
```
|
||||
Output will be saved in **results** folder.
|
||||
|
||||
|
||||
## UML diagram with latency element explanation
|
||||
|
||||
```plantuml
|
||||
``@startuml
|
||||
node "Host" {
|
||||
|
||||
16
compose-gstreamer-x264.sh
Executable file
16
compose-gstreamer-x264.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
gst-launch-1.0 \
|
||||
compositor name=comp sink_0::xpos=0 sink_0::ypos=0 sink_1::xpos=1920 sink_1::ypos=0 background=1 ! \
|
||||
'video/x-raw,width=3840,height=1080,framerate=60/1,format=I420' ! \
|
||||
x264enc bitrate=8000 speed-preset=ultrafast tune=zerolatency sliced-threads=true b-adapt=false rc-lookahead=0 ref=0 frame-packing=3 ! \
|
||||
rtph264pay ! \
|
||||
udpsink host=239.239.239.3 port=2055 auto-multicast=true sync=false async=false qos=false \
|
||||
\
|
||||
decklinkvideosrc device-number=0 connection=0 mode=1080p60 drop-no-signal-frames=false ! \
|
||||
'video/x-raw,format=(string)UYVY' ! \
|
||||
comp.sink_0 \
|
||||
\
|
||||
decklinkvideosrc device-number=1 connection=0 mode=1080p60 drop-no-signal-frames=false ! \
|
||||
'video/x-raw,format=(string)UYVY' ! \
|
||||
comp.sink_1
|
||||
@ -1,18 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
gst-launch-1.0 \
|
||||
compositor name=comp sink_0::xpos=0 sink_0::ypos=0 sink_1::xpos=1920 sink_1::ypos=0 ! nvvideoconvert ! \
|
||||
'video/x-raw(memory:NVMM),width=3840,height=1080,framerate=60/1,format=I420' ! \
|
||||
nvv4l2h264enc bitrate=10000000 control-rate=1 idrinterval=1 tuning-info-id=3 preset-id=1 profile=0 ! \
|
||||
h264parse config-interval=1 ! \
|
||||
mpegtsmux ! \
|
||||
rtpmp2tpay ! \
|
||||
udpsink host=239.239.239.3 port=2055 auto-multicast=true sync=false async=false qos=false \
|
||||
\
|
||||
decklinkvideosrc device-number=0 connection=1 mode=1080p60 drop-no-signal-frames=true ! \
|
||||
'video/x-raw,format=(string)UYVY' ! \
|
||||
comp.sink_0 \
|
||||
\
|
||||
decklinkvideosrc device-number=1 connection=1 mode=1080p60 drop-no-signal-frames=true ! \
|
||||
'video/x-raw,format=(string)UYVY' ! \
|
||||
comp.sink_1
|
||||
compositor name=comp background=1 sink_0::xpos=0 sink_0::ypos=0 sink_1::xpos=1920 sink_1::ypos=0 ! \
|
||||
capsfilter caps='video/x-raw,width=3840, height=1080,framerate=60/1' ! \
|
||||
nvvideoconvert ! \
|
||||
capsfilter caps='video/x-raw(memory:NVMM),width=3840,height=1080,framerate=60/1,format=NV12' ! \
|
||||
nvv4l2h264enc bitrate=8000000 control-rate=1 idrinterval=256 tuning-info-id=3 preset-id=1 profile=0 ! \
|
||||
rtph264pay ! \
|
||||
udpsink host=239.239.239.3 port=2055 auto-multicast=true sync=false async=false qos=false \
|
||||
\
|
||||
decklinkvideosrc device-number=0 connection=0 mode=1080p60 drop-no-signal-frames=false ! \
|
||||
'video/x-raw,format=(string)UYVY' ! \
|
||||
comp.sink_0 \
|
||||
\
|
||||
decklinkvideosrc device-number=1 connection=0 mode=1080p60 drop-no-signal-frames=false ! \
|
||||
'video/x-raw,format=(string)UYVY' ! \
|
||||
comp.sink_1
|
||||
|
||||
25
compose-playback.sh
Normal file → Executable file
25
compose-playback.sh
Normal file → Executable file
@ -1,16 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
gst-launch-1.0 udpsrc address=239.239.239.3 port=2055 ! \
|
||||
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP2T" ! \
|
||||
rtpmp2tdepay ! \
|
||||
tsdemux ! \
|
||||
h264parse ! \
|
||||
avdec_h264 ! \
|
||||
videoconvert ! \
|
||||
tee name=t \
|
||||
\
|
||||
t. ! queue ! videocrop left=0 right=1920 top=0 bottom=0 ! \
|
||||
autovideosink sync=false \
|
||||
\
|
||||
t. ! queue ! videocrop left=1920 right=0 top=0 bottom=0 ! \
|
||||
autovideosink sync=false
|
||||
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" ! \
|
||||
rtph264depay ! \
|
||||
capsfilter caps='video/x-h264, width=3840,height=1080' ! \
|
||||
avdec_h264 ! \
|
||||
capsfilter caps='video/x-raw, width=3840,height=1080' ! \
|
||||
tee name=t \
|
||||
\
|
||||
t. ! queue leaky=2 ! videocrop left=0 right=1920 top=0 bottom=0 ! \
|
||||
autovideosink sync=false \
|
||||
\
|
||||
t. ! queue leaky=2 ! videocrop left=1920 right=0 top=0 bottom=0 ! \
|
||||
autovideosink sync=false
|
||||
|
||||
14
compose-sink.sh
Executable file
14
compose-sink.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
gst-launch-1.0 \
|
||||
compositor name=comp background=1 sink_0::xpos=0 sink_0::ypos=0 sink_1::xpos=1920 sink_1::ypos=0 ! \
|
||||
'video/x-raw,width=3840,height=2160,framerate=60/1' ! \
|
||||
autovideosink sync=false \
|
||||
\
|
||||
decklinkvideosrc device-number=0 connection=0 mode=1080p60 drop-no-signal-frames=true ! \
|
||||
'video/x-raw,format=(string)UYVY' ! \
|
||||
comp.sink_0 \
|
||||
\
|
||||
decklinkvideosrc device-number=1 connection=0 mode=1080p60 drop-no-signal-frames=true ! \
|
||||
'video/x-raw,format=(string)UYVY' ! \
|
||||
comp.sink_1
|
||||
@ -7,6 +7,8 @@ sudo docker run \
|
||||
--device /dev/blackmagic/io1:/dev/blackmagic/io1 \
|
||||
-v ~/git/gstreamer-pipelines/:/app \
|
||||
-v /tmp/.X11-unix:/tmp/.X11-unix \
|
||||
-v $HOME/.Xauthority:/root/.Xauthority \
|
||||
-e XDG_RUNTIME_DIR \
|
||||
-e DISPLAY=$DISPLAY \
|
||||
--network=host \
|
||||
-v ~/git/gstreamer-pipelines/container/Drivers/:/drivers \
|
||||
|
||||
17
ffmpeg-psnr-check.sh
Normal file → Executable file
17
ffmpeg-psnr-check.sh
Normal file → Executable file
@ -1,23 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <input_video> <reference_video>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v ffmpeg &> /dev/null
|
||||
then
|
||||
echo "ffmpeg could not be found, please install it."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
name=nvv4l2h264enc
|
||||
specific=eleph-pr-baseline-preset1-cbr-hqp-10
|
||||
|
||||
#
|
||||
#this script checks the PSNR between two video streams using ffmpeg
|
||||
# one video stream is the reference and the other is the test stream both are recorded files
|
||||
ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format yuv444p -color_range pc -framerate 30 -i "$1" -i "$2" -filter_complex "psnr" -f null /dev/null
|
||||
ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format yuv420p -color_range tv -framerate 60 -i base-${name}-${specific}.yuv -i encoded-${name}-${specific}.mp4 -filter_complex "psnr" -f null /dev/null
|
||||
# example working:
|
||||
# ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format yuv444p -color_range pc -framerate 30 -i base.yuv -i test.mp4 -filter_complex "psnr" -f null /dev/null
|
||||
# ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format yuv420p -color_range tv -framerate 60 -i base-${name}-${specific}.yuv -i encoded-${name}-${specific}.mp4 -filter_complex "psnr" -f null /dev/null
|
||||
# ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format nv12 -color_range tv -framerate 60 -i base-${name}-${specific}.yuv -i encoded-${name}-${specific}.mp4 -filter_complex "psnr" -f null /dev/null
|
||||
# ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format yuv420p -color_range pc -framerate 60 -i base.yuv -i test.mp4 -filter_complex "psnr" -f null /dev/null
|
||||
|
||||
#this script checks the SSIM between two video streams using ffmpeg
|
||||
ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format yuv444p -color_range pc -framerate 30 -i "$1" -i "$2" -filter_complex "[0:v][1:v]ssim=stats_file=ssim_results.txt" -f null /dev/null
|
||||
ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format yuv420p -color_range tv -framerate 60 -i base-${name}-${specific}.yuv -i encoded-${name}-${specific}.mp4 -filter_complex "[0:v]fps=60[v0];[1:v]fps=60[v1];[v0][v1]ssim=stats_file=ssim_results.txt" -f null /dev/null
|
||||
|
||||
# ffmpeg -f rawvideo -video_size 1920x1080 -pixel_format yuv422p -color_range pc -framerate 30 -i base.yuv -i test.mp4 -filter_complex "[0:v][1:v]ssim=stats_file=ssim_results.txt" -f null /dev/null
|
||||
21
gst-stereo.sh
Executable file
21
gst-stereo.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
|
||||
./gstreamer-record.sh &
|
||||
|
||||
left=$!
|
||||
|
||||
./gstreamer-record-r.sh &
|
||||
right=$!
|
||||
|
||||
cleanup() {
|
||||
kill -s SIGINT $left
|
||||
kill -s SIGINT $right
|
||||
exit 0
|
||||
}
|
||||
|
||||
trap cleanup SIGINT
|
||||
|
||||
while true; do
|
||||
sleep 1
|
||||
done
|
||||
1
gstAutotest
Submodule
1
gstAutotest
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 8daf682763f70b995a43c403ee202ce233700d11
|
||||
16
gstNvinfer.sh
Executable file
16
gstNvinfer.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
gst-launch-1.0 filesrc location=$1 ! \
|
||||
rawvideoparse format=2 height=540 width=960 framerate=60000/1001 ! \
|
||||
clocksync sync-to-first=true ! \
|
||||
nvvideoconvert ! \
|
||||
capsfilter caps="video/x-raw(memory:NVMM),format=RGBA,height=1080,width=1920" ! \
|
||||
m.sink_0 nvstreammux name=m batch-size=1 width=1920 height=1080 ! \
|
||||
nvinfer config-file-path=config.txt ! \
|
||||
nvvideoconvert ! \
|
||||
nvsegvisual ! \
|
||||
capsfilter caps="video/x-raw(memory:NVMM),format=RGBA" ! \
|
||||
nvvideoconvert ! \
|
||||
nvv4l2h264enc bitrate=6850000 profile=2 preset-id=3 control-rate=2 idrinterval=256 tuning-info-id=3 ! \
|
||||
capsfilter caps="video/x-h264,profile=main" ! h264parse ! mpegtsmux ! \
|
||||
filesink location="autotest-nvv4l2h264enc-main-test-base-daVinci.mp4"
|
||||
@ -3,15 +3,15 @@
|
||||
# Set environment variables for GStreamer latency tracing.
|
||||
# Note: We are using a different log file name to avoid overwriting the sender's log.
|
||||
GST_DEBUG_COLOR_MODE=off \
|
||||
GST_TRACERS="latency(flags=pipeline+element)" \
|
||||
GST_DEBUG="GST_TRACER:7" \
|
||||
GST_DEBUG_FILE=latency_traces_receiver.log \
|
||||
gst-launch-1.0 -v \
|
||||
udpsrc uri="udp://239.239.239.3:8889" ! \
|
||||
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP2T" ! \
|
||||
rtpmp2tdepay ! \
|
||||
tsdemux latency=0 ! \
|
||||
h264parse ! \
|
||||
avdec_h264 qos=false ! \
|
||||
videoconvert ! \
|
||||
autovideosink sync=false
|
||||
GST_TRACERS="latency(flags=pipeline+element)" \
|
||||
GST_DEBUG="GST_TRACER:7" \
|
||||
GST_DEBUG_FILE=latency_traces_receiver.log \
|
||||
gst-launch-1.0 -v \
|
||||
udpsrc uri="udp://239.239.239.3:8889" ! \
|
||||
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP2T" ! \
|
||||
rtpmp2tdepay ! \
|
||||
tsdemux latency=0 ! \
|
||||
h264parse ! \
|
||||
avdec_h264 qos=false ! \
|
||||
videoconvert ! \
|
||||
autovideosink sync=false
|
||||
|
||||
11
gstPlaybackRTPH264.sh
Executable file
11
gstPlaybackRTPH264.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set environment variables for GStreamer latency tracing.
|
||||
# Note: We are using a different log file name to avoid overwriting the sender's log.
|
||||
gst-launch-1.0 -v \
|
||||
udpsrc uri="udp://239.239.239.3:8889" ! \
|
||||
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" ! \
|
||||
rtph264depay ! \
|
||||
avdec_h264 qos=false ! \
|
||||
videoconvert ! \
|
||||
autovideosink sync=false
|
||||
18
gstX264.sh
Executable file
18
gstX264.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
export GST_DEBUG_COLOR_MODE=off
|
||||
export GST_TRACERS="latency(flags=pipeline+element)"
|
||||
export GST_DEBUG="GST_TRACER:7"
|
||||
export GST_DEBUG_FILE=latency_traces.log
|
||||
|
||||
decklink="decklinkvideosrc drop-no-signal-frames=true mode=1080p60 device-number=1 connection=0"
|
||||
|
||||
gst-launch-1.0 $decklink ! \
|
||||
videoconvert n-threads=4 ! \
|
||||
capsfilter caps="video/x-raw,width=1920,height=1080" ! \
|
||||
x264enc bitrate=20000 speed-preset=ultrafast tune=zerolatency sliced-threads=true b-adapt=false rc-lookahead=0 ref=0 key-int-max=10 ! \
|
||||
capsfilter caps="video/x-h264,profile=baseline" ! \
|
||||
h264parse config-interval=1 ! \
|
||||
mpegtsmux ! \
|
||||
rtpmp2tpay ! \
|
||||
udpsink host=239.239.239.3 port=8889 auto-multicast=true sync=false async=false qos=false
|
||||
16
gstX264OnlyPay.sh
Executable file
16
gstX264OnlyPay.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
export GST_DEBUG_COLOR_MODE=off
|
||||
export GST_TRACERS="latency(flags=pipeline+element)"
|
||||
export GST_DEBUG="GST_TRACER:7"
|
||||
export GST_DEBUG_FILE=latency_traces.log
|
||||
|
||||
decklink="decklinkvideosrc drop-no-signal-frames=true mode=1080p60 device-number=1 connection=0"
|
||||
|
||||
gst-launch-1.0 $decklink ! \
|
||||
videoconvert n-threads=4 ! \
|
||||
capsfilter caps="video/x-raw,width=1920,height=1080" ! \
|
||||
x264enc bitrate=4000 speed-preset=ultrafast tune=zerolatency sliced-threads=true b-adapt=false rc-lookahead=0 ref=0 ! \
|
||||
capsfilter caps="video/x-h264,profile=baseline" ! \
|
||||
rtph264pay ! \
|
||||
udpsink host=239.239.239.3 port=8889 auto-multicast=true sync=false async=false qos=false
|
||||
@ -5,34 +5,58 @@
|
||||
# First stream is coming from decklinkvideosrc
|
||||
# Second stream is same decklinkvideosrc but encoded using x264enc
|
||||
# Both streams are saved to files using mp4mux and filesink
|
||||
|
||||
if [ "$#" -lt 2 ]; then
|
||||
echo "Usage: $0 <reference_video_file> <test_video_file> <optional: DEBUG>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v gst-launch-1.0 &> /dev/null
|
||||
then
|
||||
echo "gstreamer could not be found, please install it."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Record both streams in one run
|
||||
if [ "$3" == "DEBUG" ]; then
|
||||
gst-launch-1.0 -e \
|
||||
videotestsrc pattern=smpte ! \
|
||||
capsfilter caps="video/x-raw,format=UYVY,width=1920,height=1080,framerate=30/1" ! \
|
||||
videoconvert ! queue ! tee name=t \
|
||||
t. ! queue ! filesink location="$1" \
|
||||
t. ! queue ! x264enc bitrate=20000 speed-preset=ultrafast tune=zerolatency ! h264parse ! mpegtsmux ! filesink location="$2"
|
||||
exit 0
|
||||
src='decklinkvideosrc device-number=1 connection=1 mode=1080p60 drop-no-signal-frames=true !'
|
||||
|
||||
if [ "$1" == "DEBUG" ]; then
|
||||
src='videotestsrc pattern=smpte !'
|
||||
fi
|
||||
|
||||
gst-launch-1.0 -e \
|
||||
decklinkvideosrc \
|
||||
device-number=1 \
|
||||
connection=1 \
|
||||
mode=auto \
|
||||
drop-no-signal-frames=true ! videoconvert ! queue ! tee name=t \
|
||||
t. ! queue ! mpegtsmux ! filesink location="$1" \
|
||||
t. ! queue ! x264enc bitrate=20000 speed-preset=ultrafast tune=zerolatency ! mpegtsmux ! filesink location="$2"
|
||||
name=nvv4l2h264enc
|
||||
specific=eleph-pr-baseline-preset1-cbr-lossless-10
|
||||
|
||||
echo $src
|
||||
|
||||
GST_DEBUG_COLOR_MODE=off \
|
||||
GST_TRACERS="latency(flags=pipeline+element)" \
|
||||
GST_DEBUG="GST_TRACER:7" \
|
||||
GST_DEBUG_FILE=latency_traces-${name}-${specific}.log \
|
||||
gst-launch-1.0 -e \
|
||||
$src \
|
||||
capsfilter caps="video/x-raw,format=UYVY,width=1920,height=1080,framerate=60/1" ! \
|
||||
videoconvert ! capsfilter caps="video/x-raw,format=I420,width=1920,height=1080,framerate=60/1" ! queue ! tee name=t \
|
||||
t. ! queue ! filesink location="base-${name}-${specific}.yuv" \
|
||||
t. ! queue ! nvvideoconvert ! \
|
||||
capsfilter caps="video/x-raw(memory:NVMM),format=I420,width=1920,height=1080" ! \
|
||||
${name} bitrate=10000000 profile=0 preset-id=1 control-rate=1 tuning-info-id=4 ! \
|
||||
capsfilter caps="video/x-h264,profile=baseline" ! h264parse ! mpegtsmux ! filesink location="encoded-${name}-${specific}.mp4"
|
||||
|
||||
|
||||
# GST_DEBUG_COLOR_MODE=off \
|
||||
# GST_TRACERS="latency(flags=pipeline+element)" \
|
||||
# GST_DEBUG="GST_TRACER:7" \
|
||||
# GST_DEBUG_FILE=latency_traces-${name}-${specific}.log \
|
||||
# gst-launch-1.0 -e \
|
||||
# $src \
|
||||
# capsfilter caps="video/x-raw,format=UYVY,width=1920,height=1080,framerate=60/1" ! \
|
||||
# videoconvert ! queue ! tee name=t \
|
||||
# t. ! queue ! filesink location="base-${name}-${specific}.yuv" \
|
||||
# t. ! queue ! x264enc bitrate=10000 speed-preset=ultrafast tune=zerolatency sliced-threads=true ! \
|
||||
# capsfilter caps="video/x-h264,profile=baseline" ! h264parse ! mpegtsmux ! filesink location="encoded-${name}-${specific}.mp4"
|
||||
|
||||
# GST_DEBUG_COLOR_MODE=off \
|
||||
# GST_TRACERS="latency(flags=pipeline+element)" \
|
||||
# GST_DEBUG="GST_TRACER:7" \
|
||||
# GST_DEBUG_FILE=latency_traces-${name}-${specific}.log \
|
||||
# gst-launch-1.0 -e \
|
||||
# $src \
|
||||
# capsfilter caps="video/x-raw,format=UYVY,width=1920,height=1080,framerate=60/1" ! \
|
||||
# videoconvert ! capsfilter caps="video/x-raw,format=NV12,width=1920,height=1080,framerate=60/1" ! queue ! tee name=t \
|
||||
# t. ! queue ! filesink location="base-${name}-${specific}.yuv" \
|
||||
# t. ! queue ! ${name} bitrate=10000 preset=5 rc-lookahead=0 rc-mode=2 zerolatency=true ! \
|
||||
# capsfilter caps="video/x-h264,profile=baseline" ! h264parse ! mpegtsmux ! filesink location="encoded-${name}-${specific}.mp4"
|
||||
|
||||
16
videosink/compose-playback.sh
Executable file
16
videosink/compose-playback.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
gst-launch-1.0 udpsrc address=239.239.239.3 port=2055 ! \
|
||||
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP2T" ! \
|
||||
rtpmp2tdepay ! \
|
||||
tsdemux ! \
|
||||
h264parse ! \
|
||||
nvv4l2decoder ! \
|
||||
nvvideoconvert ! \
|
||||
tee name=t \
|
||||
\
|
||||
t. ! queue ! videocrop left=0 right=1920 top=0 bottom=0 ! \
|
||||
autovideosink sync=false \
|
||||
\
|
||||
t. ! queue ! videocrop left=1920 right=0 top=0 bottom=0 ! \
|
||||
autovideosink sync=false
|
||||
30
videosink/gstNvH264.sh
Executable file
30
videosink/gstNvH264.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
export GST_DEBUG_COLOR_MODE=off
|
||||
export GST_TRACERS="latency(flags=pipeline+element)"
|
||||
export GST_DEBUG="GST_TRACER:7"
|
||||
export GST_DEBUG_FILE=latency_traces.log
|
||||
|
||||
decklink="decklinkvideosrc drop-no-signal-frames=true mode=1080p60 device-number=1 connection=0 buffer-size=1 "
|
||||
|
||||
gst-launch-1.0 $decklink ! \
|
||||
capsfilter caps="video/x-raw, format=(string)UYVY" ! \
|
||||
videoconvert n-threads=4 ! \
|
||||
capsfilter caps="video/x-raw,width=1920,height=1080, format=NV12" ! \
|
||||
nvh264enc rc-mode=2 bitrate=4000 preset=4 bframes=0 b-adapt=false rc-lookahead=0 zerolatency=true ! \
|
||||
capsfilter caps="video/x-h264,profile=baseline" ! \
|
||||
nvh264dec ! \
|
||||
videoconvert n-threads=4 ! \
|
||||
autovideosink
|
||||
|
||||
exit 0
|
||||
|
||||
gst-launch-1.0 $decklink ! \
|
||||
glupload ! \
|
||||
glcolorconvert ! \
|
||||
capsfilter caps="video/x-raw(memory:GLMemory),width=1280,height=720" ! \
|
||||
nvh264enc rc-mode=2 bitrate=10000 preset=3 gop-size=0 bframes=0 b-adapt=false zerolatency=true ! \
|
||||
capsfilter caps="video/x-h264,profile=baseline" ! \
|
||||
nvh264dec ! \
|
||||
glcolorconvert ! \
|
||||
glimagesink
|
||||
17
videosink/gstNvv4l2h264.sh
Executable file
17
videosink/gstNvv4l2h264.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
#export GST_DEBUG_COLOR_MODE=off
|
||||
#export GST_TRACERS="latency(flags=pipeline+element)"
|
||||
#export GST_DEBUG="GST_TRACER:7"
|
||||
#export GST_DEBUG_FILE=latency_traces.log
|
||||
|
||||
decklink="decklinkvideosrc drop-no-signal-frames=true mode=1080p60 device-number=0 connection=0 buffer-size=1"
|
||||
|
||||
gst-launch-1.0 $decklink ! \
|
||||
capsfilter caps="video/x-raw,format=(string)UYVY" ! \
|
||||
nvvideoconvert bl-output=true contiguous-buffers=true output-buffers=1 ! \
|
||||
capsfilter caps="video/x-raw(memory:NVMM),format=NV12,width=1920,height=1080" ! \
|
||||
nvv4l2h264enc bitrate=4000000 control-rate=2 idrinterval=1 tuning-info-id=3 preset-id=1 profile=0 ! \
|
||||
capsfilter caps="video/x-h264, profile=baseline" ! \
|
||||
avdec_h264 ! \
|
||||
nveglglessink
|
||||
16
videosink/gstX264.sh
Executable file
16
videosink/gstX264.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
export GST_DEBUG_COLOR_MODE=off
|
||||
export GST_TRACERS="latency(flags=pipeline+element)"
|
||||
export GST_DEBUG="GST_TRACER:7"
|
||||
export GST_DEBUG_FILE=latency_traces.log
|
||||
|
||||
decklink="decklinkvideosrc drop-no-signal-frames=true mode=1080p60 device-number=1 connection=0"
|
||||
|
||||
gst-launch-1.0 $decklink ! \
|
||||
videoconvert n-threads=4 ! \
|
||||
capsfilter caps="video/x-raw,width=1920,height=1080" ! \
|
||||
x264enc bitrate=4000 speed-preset=ultrafast tune=zerolatency sliced-threads=true b-adapt=false rc-lookahead=0 ref=0 ! \
|
||||
capsfilter caps="video/x-h264,profile=baseline" ! \
|
||||
avdec_h264 ! \
|
||||
autovideosink
|
||||
Loading…
x
Reference in New Issue
Block a user