-
Notifications
You must be signed in to change notification settings - Fork 358
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When I define and set pts and dts myself, the value of tbr will become 100 #1347
Comments
|
The problem is that it will cause video freezes and the video cannot be played at fps speed. The result of my analysis is that the speed of tbr must be consistent with the fps speed to avoid video freezes. In addition, I will write a demo to test it. @WyattBlue |
This is a demo I wrote. As long as I enable the add_video_pts_dts method and set pts and dts myself, the tbr value in the rtmp stream will be greater than the fps value and become 100. As long as I do not set pts and dts myself, the tbr value will be the normal sum. Consistent fps @WyattBlue You try this demo import fractions
import os
import queue
import threading
import time
import av
class TestAvLive:
def __init__(self, rtsp, rtmp):
self.frame_queue = queue.Queue()
self.video_pts = 10
self.audio_pts = 10
self.frame_count = 0
self.rtsp = rtsp
self.rtmp = rtmp
def test_in(self):
options = {'buffer_size': '1024000', 'rtsp_transport': 'tcp', 'stimeout': '20000000', 'max_delay': '500000'}
self.in_video = av.open(self.rtsp, 'r', format=None, options=options, metadata_errors='strict')
self.in_video.streams.video[0].thread_type = "AUTO"
self.in_video_stream = self.in_video.streams.video[0]
self.in_audio_stream = self.in_video.streams.audio[0]
for packet in self.in_video.demux(self.in_video_stream, self.in_audio_stream):
if packet.stream.type == 'video':
for frame in packet.decode():
self.frame_queue.put((frame, 'video'))
elif packet.stream.type == 'audio':
self.frame_queue.put((packet, 'audio'))
def get_frame_duration(self):
in_video_stream = self.in_video_stream
in_audio_stream = self.in_audio_stream
print(in_video_stream.time_base, in_audio_stream.time_base)
try:
video_frame_duration = in_video_stream.time_base.denominator / 25
audio_frame_duration = in_audio_stream.time_base.denominator / in_audio_stream.rate
except Exception as e:
video_frame_duration = 3600
audio_frame_duration = 1000
print(video_frame_duration, audio_frame_duration)
return int(video_frame_duration), audio_frame_duration
def add_video_pts_dts(self, packet):
return packet
for i in packet:
i.pts = i.dts = self.video_pts
self.video_pts += self.video_frame_duration
return packet
def test_out(self):
time.sleep(2)
audio_rate = 44100
self.video_frame_duration, self.audio_frame_duration = self.get_frame_duration()
out_archive = av.open(self.rtmp, 'w', format='flv')
encode_m = "h264_nvenc" if os.name == 'posix' else "h264"
archive_video_stream = out_archive.add_stream(encode_m, rate=25, options={"framerate": '25'})
archive_audio_stream = out_archive.add_stream('aac', rate=audio_rate)
archive_video_stream.height = 1080
archive_video_stream.width = 1920
archive_video_stream.bit_rate = 3072000
archive_video_stream.pix_fmt = 'nv12'
archive_video_stream.gop_size = 60
archive_video_stream.time_base = fractions.Fraction(1, 25)
print(archive_video_stream.time_base)
archive_video_stream.framerate = fractions.Fraction(25, 1)
archive_audio_stream.time_base = fractions.Fraction(1, audio_rate)
print(archive_video_stream.time_base, archive_audio_stream.time_base)
while True:
frame, data_type = self.frame_queue.get()
if data_type == 'video':
print("video pts:{} dts:{}".format(frame.pts, frame.dts))
undistort_frame = frame.to_ndarray(format='bgr24')
frame = av.VideoFrame.from_ndarray(undistort_frame, format='bgr24')
out_video_packet = self.add_video_pts_dts(archive_video_stream.encode(frame))
out_archive.mux(out_video_packet)
self.frame_count += 1
elif data_type == 'audio':
out_archive.mux(frame)
def run(self):
threads = [
threading.Thread(target=self.test_in),
threading.Thread(target=self.test_out),
]
[thread.start() for thread in threads]
[thread.join() for thread in threads]
if __name__ == '__main__':
rtsp = "rtsp://admin:abc@12345@192.168.4.112:554/ch1/stream1"
rtmp = 'rtmp://192.168.1.91:1935/live/6666/9944'
t = TestAvLive(rtsp,rtmp)
t.run()
|
When I run it, I get this. I don't think it show cases the actual problem
|
You need to modify the addresses of rtmp and rtsp in the demo
|
If you enable the add_video_pts_dts method and set pts and dts yourself, it will cause tbr to become 100 instead of consistent with the value of fps, which will cause the video stream to freeze. So my question is how to control the value of this tbr
|
Does this only happen in rtmp inputs? Can you replicate this in other rtmp streams? |
Yes, I tested other rtmp streams and it was the same. I tried to write the input rtmp stream to an mp4 video file and it was the same.
This is the output result
When I try to change the time base to match the frame rate
|
When I turn off the custom setting pts, the output mp4 file seems to become normal, but I
When I turn off the custom pts setting and set the time scale to 90000, the output mp4 file seems to be normal. But if I output the rtmp stream, set the time scale to 90000 and turn off the custom pts setting, the picture will become very stuck. Only when the time scale is set to the same as the pts will it not be stuck. I don't understand why this happens. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
When I set the pts and dts myself, the btr will become 100 uncontrollably. When I don't modify the pts and dts, the value of the btr is consistent with the fps.
When I modify pts and dts
When I don't modify pts and dts
I also set time_base:
The text was updated successfully, but these errors were encountered: