Hello,
I’m using this pipeline to save a playable file from the camera capture:
gst-launch-1.0 --eos-on-shutdown nvarguscamerasrc sensor_id=0 ! 'video/x-raw(memory:NVMM), width=2712, height=1538, framerate=90/1' ! videorate max-rate=90 ! nvvidconv ! 'video/x-raw(memory:NVMM), format=(string)I420' ! queue leaky=downstream max-size-buffers=30 ! nvv4l2h264enc maxperf-enable=true bitrate=26500000 profile=High insert-aud=true insert-sps-pps=true insert-vui=true ! 'video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, profile=(string)high, level=(string)4.1' ! h264parse config-interval=-1 ! queue leaky=downstream max-size-buffers=200 ! mp4mux name=mux ! filesink location=/home/jetson/test12.mp4 alsasrc buffer-time=100000 latency-time=10000 device=hw:1 ! 'audio/x-raw, format=S16LE, rate=48000, channels=2' ! queue ! opusenc bitrate=64000 frame-size=20 ! mux.
The thing is, I can see in the output
H264: Profile = 100, Level = 41
NVMEDIA_ENC: bBlitMode is set to TRUE
but the output file instead is Constrained High@L5.2
How can I force it to use the lower, custom level? Is it hardcoded in the source?
Thank you!
R
DaneLLL
December 14, 2023, 2:49am
3
Hi,
It is set per resolution and framerate. according to
Advanced Video Coding - Wikipedia
It looks correct to set to level 5.2.
For 4.1, please try to encode in 1080p30.
Yes, I understand that, but when doing this from nvarguscamerasrc, we can put one caps in between the encoder and rtph264pay and the browser will get via webrtcbin the lower profile + asymmetry-allowed=1, allowing it to play just fine at this resolution, FPS & bitrate. I want to avoid transcoding and we need this quality… Is there any other way? Can’t we hint the encoder?
DaneLLL
December 15, 2023, 1:52am
5
Hi,
You can add code in gst-v4l2 to overwrite level and rebuild the plugin. Beginning of SPS in encoded H264 stream of 2712x1538p30 looks like
00 00 00 01 67 64 0C 34 … …
And can use the logic to find SPS:
Xavier AGX : Video encoding crash - #15 by DaneLLL
0x67 & 0x1F = 7
0x64 is profile. 0x0C is constrained set flag. 0x34 is level. You can overwrite 0x34 to 0x29.
Wow, your suggestion worked like a charm!
One first needs to exact the h264 stream from the mp4:
ffmpeg -i test.mp4 -c:v copy -an input.h264
Here is the script I came up with ChatGPT:
def modify_sps(input_file, output_file):
with open(input_file, "rb") as file:
stream_data = bytearray(file.read())
# Find the SPS start code: 00 00 00 01 67
sps_start_code = b'\x00\x00\x00\x01\x67'
sps_start_index = stream_data.find(sps_start_code)
if sps_start_index != -1:
# Offset to the profile, constraint flags, and level_idc position
profile_index = sps_start_index + 5
constraint_flags_index = profile_index + 1
level_index = constraint_flags_index + 1
# Read current profile, constraint flags, and level
current_profile = stream_data[profile_index]
current_constraint_flags = stream_data[constraint_flags_index]
current_level = stream_data[level_index]
print(f"Current Profile (Hex): {current_profile:02x}")
print(f"Current Constraint Flags (Hex): {current_constraint_flags:02x}")
print(f"Current Level (Hex): {current_level:02x}")
# Directly modify the constraint flags and level
stream_data[constraint_flags_index] = 0x00 # Reset constraint flags to 00
stream_data[level_index] = 0x1F # Change level to 3.1
with open(output_file, "wb") as file:
file.write(stream_data)
else:
print("SPS start code not found in the stream.")
# Example usage
modify_sps("input.h264", "output.h264")
Run the script and then repack in mp4 (to also copy the audio stream from the original file):
ffmpeg -i output.h264 -i test.mp4 -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 test-hacked.mp4
1 Like
system
Closed
January 1, 2024, 3:59pm
7
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.