Я транслирую несколько потоков UDP с помощью ffmpeg с одного устройства, также есть параллельный процесс для каждого потока, который вычисляет оценку для каждого кадра и отправляет оценку на другой порт. На принимающей стороне клиент читает кадр и оценку для каждого потока и отображает кадр из потока, который имеет наилучшую оценку.
Проблема заключается в том, что при наличии нескольких потоков приемник начинаетстановятся очень запаздывающими и пропускают так много кадров, даже страннее, хуже при низких битрейтах (при 200 кбит / с и 4 видеопотоках, около 40% пропущенных кадров и задержка ~ 10 с).
Чтобы исключить проблему с сетью,Я попытался просто отобразить все потоки на стороне клиента в разных процессах (каждый процесс читает и отображает один поток). Таким образом, было минимальное время ожидания и падение. Похоже, что несколько VideoCaptures в одном процессе как-то замедляют его.
Вот соответствующая часть кода клиента.
# thread per stream, reads frames and queues them up
def rx_thread(ip, vport, tport, q):
global die
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((ip, tport))
reader = s.makefile('r')
cap = cv2.VideoCapture('udp://'+ip+':'+str(vport))
while not die:
score = float(reader.readline())
ret, frame = cap.read()
if not ret:
die = True
break
q.put((frame, score))
cap.release()
reader.close()
s.close()
output = open(argv[1], 'w', buffering=1)
# arg[3] .. are pairs of video port and score port
queues = []
for i in range(3, len(argv), 2):
q = queue.Queue(30)
t = threading.Thread(target=rx_thread,
args=(argv[2], int(argv[i]),int(argv[i+1]), q))
t.start()
queues.append(q)
frames_count = 0
start = None
while True:
try:
frames, info = zip(*map(lambda q: q.get(True, 5), queues))
except queue.Empty:
die = True
break
if start is None:
start = time()
output.write('start: %.3f\n' % start)
frames_count += 1
# get stream with max score and show
index = info.index(max(info))
cv2.imshow('Video', frames[index])
if cv2.waitKey(1) & 0xFF == ord('q'):
die = True
break
output.write('frames_count: %d\n' % frames_count)
Редактировать :
Некоторые предположили, что это может быть связано с тем, как отправляются результаты. Я пытался полностью игнорировать результаты (я не открываю гнездо для показателей, и я ставлю фиктивную оценку 1,0 для каждого кадра, когда ставлю в очередь). В общем, клиент просто читает несколько видеопотоков. Проблема все еще сохраняется. В начале всегда есть куча ошибок, подобных этим:
[mpeg4 @ 0x7ff838016fc0] Error, header damaged or not MPEG-4 header (f_code=0)
[mpeg4 @ 0x7ff838016fc0] header damaged
[mpeg4 @ 0x7ff838046c40] warning: first frame is no keyframe
[mpeg4 @ 0x7ff840016f80] Error, header damaged or not MPEG-4 header (qscale=0)
Ошибка first frame is no keyframe
, кажется, возникает ровно n-1 раз, когда число потоков равно n.