1 (04.10.2017 18:02:51 отредактировано Peter)

Здравствуйте!

Если для ffmpeg входом является tcp-поток, то что для неё будет входным файлом?
В справке для этого случая

ffmpeg -i <input> -f <format> tcp://<hostname>:<port>?listen ...

и что в этом случае будет input? Причём одновременно может быть запущено несколько ffmpeg для разных портов.
В программе на Qt создаётся несколько объектов типа QTcpServer, каждый будет устанавливать соединение со своей ffmpeg,
при этом создаётся QTcpSocket, он и будет передавать, всё это на одном компьютере.
Чем будет input? В /dev появится какое-то устройство,  тогда какое? Или оно там уже есть? Или что?

/dev/tcp? /dev/tcp/hostname/port?

Пётр.

2

Peter, скорее всего подразумевается файл аудио или видео.
tcp://<hostname>:<port> listen... - адрес машины, с которой идёт трансляция, в сети, где:
TCP - статический протокол передачи данных (так называемый "безопасный").
Hostname - IP-адрес машины или же название сайта/сервера/компьютера (в локальной сети).
Port - порт передачи данных (для шлюза или файерволла).
Listen - команда сканирования сети...

Linux Mint 19.3 Mate Edition
Windows 7

3

Я не понял, при чём тут файл, если поток принимается из сети.
Я уже смоттел в Интернете, пишут, что в bash есть свой /dev/tcp.
Посмотрите по
/dev/tcp

Пётр.

4

Здравствуйте!

Я пытаюсь в программе на Qt последовательность QImage преобразовать в YUV-поток
и передать его ffmpeg, чтобы она из него создала avi-файл.
Для этого из содержимого QImage заполняется массив с таким же количеством точек,
по 3 байта на точку, а RGB переводится в YUV.  Я смотрел, какие массивы строит
y4mcolorbars, в них 3 байта на точку.  Для передачи используется QTcpServer.

Когда происходит соединение с ffmpeg, создаётся QTcpSoket, он передаёт заголовок,
заканчивающийся символом '\n'. Заголовок такой:

YUV4MPEG2 W1280 H1024 F24:1 Ip C444

1280 и 1024 - это размер кадра, соответственно размер массива - 3932160 байтов.
Перед передачей очередного массива этот же сокет передаёт слово FRAME, тоже с '\n',
а затем он передаёт сам массив одной командой и вот после 1-го же массива
соединение разрывается:

 Консоль:
Socket error! 1 Удалённый узел закрыл соединение
Socket was disconnected.

Вот скрипт, которым запускается ffmpeg:

#!/bin/bash

# 1st - port number, 2nd - fps
nprt=$1
fps=$2
pprn=${HOME}"/image2avi_3.log"
pprne=${HOME}"/image2avi_3e.log"
rm -f $pprne
touch $pprne
idprn=${HOME}"/ffmpeg_id_3"
fpath=${HOME}"/hard/avi"
fdt=`date +%Y_%m_%d_%H_%M_%S`
flnm=${fdt}_${fps}
fflnm=${fpath}/${flnm}
vcod=libx264
hostn=`hostname`
echo $1 $2 $hostn $nprt $flnm > $pprn

echo 3 <> /dev/tcp/${hostn}/$nprt

/usr/bin/ffmpeg -v error -f yuv4mpegpipe -i 3 -r $fps -vcodec $vcod \
-vpre libx264-ultrafast-old -f avi ${fflnm}_v.avi \
tcp://${hostn}:${nprt}?listen&timeout=12000000  >& $pprne &

piav=`pidof ffmpeg`
echo $piav > $idprn
echo "ffmpeg is running" >> $pprn

Опытным путём было установлено, что констукция

tcp://${hostn}:${nprt}?listen

должна быть последней в команде, т.к всё, что после неё, не воспринимается,
либо я не так это делаю. Например, когда она была после "-i 3", bash сообщал,
что команды "-r" не существует.
При этом avi-файл не создаётся вообще, даже нулевой длины.

Вопросы такие, если кто знает:
Почему соединение разрывается после 1-й же попытки передачи массива?
Можно ли такие большие массивы посылать одной командой?
Правильно ли указан формат при вызове ffmpeg и как надо, если нет?
Т.е. цель - сформировать поток, подобно тому, как это делатет jpeg2yuv
и передать его ffmpeg, чтобы она построила из него avi-файл.

Возможно, не обязательно передавать кадры в формате YUV, а можно и в RGB,
но мне сначала надо добиться, чтобы работало хоть как-то.

Пётр.

5

Я ошибся, соединение разрывается ещё до попытки передать FRAME.

Пётр.

6

Причём закрывается мгновенно: происходит соединение, что-то печатается,
посылается заголовок потока, выполняются команды connect, ещё что-то
печатается и связь разрывается и между соединением и разрывом проходит
меньше одной микросекунды - я в этих случаях вызываю gettimeofday()
и разница 0. Похоже, что посылка чем-то не нравится.

Пётр.

7 (20.10.2017 16:43:48 отредактировано Peter)

Здравствуйте!

Мне не удаётся правильно сформировать видеопоток из QImage для ffmpeg.
Для начала я попытался построить видеопоток такой, какой делает jpeg2avi, но без дискретизации,
т.к. в QImage находится полностью декодированное изображение в BMP.
Т.е. заголовок потока начинается с YUV4MPEG2 и заканчивается опцией C444, а не C420jpeg.
Каждая точка переводится в формат YUV и ffmpeg посылается заполненный массив, на каждую точку 3 байта.
ffmpeg строит avi, но непраильно - при просмотре всё размыто и фон сильно зелёный,
а mplayer сообщает

 Консоль:
Could not find matching colorspace

что он вызывает "-vf scale" и что он преобразует
BICUBIC scaler, yuv444p to yuv420p using MMX2.

Я также пробовал применить для входного потока опцию "-vf <filter>"
пробовал указывать filter как lutyuv, но не помогло.
Как же построить поток?

После этого я пробовал передвать и RGB с "-vf lutrgb", ничего не изменилось.

Пётр.

8

Склеил Ваши темы в одну.

ᛈᚺ'ᚾᚷᛚᚢᛁ ᛗᚷᛚᚹ'ᚾᚨᚠᚺ ᚲᛏᚺᚢᛚᚺᚢ ᚱ'lᚷᛖᚺ ᚹᚷᚨᚺ'ᚾᚨᚷᛚ ᚠᚺᛏᚨᚷᚾ

Asus Prime B460M-K, i5-10500, Intel 630 UHD, DDR4 32 GB, SSD 500GB + HDD 2TB | Linux Mint 21.3 Cinnamon + Fedora 39 MATE (Compiz) + Windows 11 + macOS 12 Monterey