LinuxForum.Fans
Тема

Разные форматы -> ffmpeg

Автор: Peter 8 сообщений 1095 просмотров
04.10.2017 17:23 · отредактировано #425703

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

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

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

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

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

04.10.2017 18:15 #425709

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

04.10.2017 20:18 #425713

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

06.10.2017 13:15 #425765

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

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

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

text
YUV4MPEG2 W1280 H1024 F24:1 Ip C444

1280 и 1024 - это размер кадра, соответственно размер массива - 3932160 байтов.
Перед передачей очередного массива этот же сокет передаёт слово FRAME, тоже с '\n',
а затем он передаёт сам массив одной командой и вот после 1-го же массива
соединение разрывается:
[console]Socket error! 1 Удалённый узел закрыл соединение
Socket was disconnected.
[/console]

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

text

#!/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

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

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

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

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

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

06.10.2017 15:53 #425766

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

06.10.2017 16:58 #425767

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

20.10.2017 13:56 · отредактировано #425946

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

Мне не удаётся правильно сформировать видеопоток из QImage для ffmpeg.
Для начала я попытался построить видеопоток такой, какой делает jpeg2avi, но без дискретизации,
т.к. в QImage находится полностью декодированное изображение в BMP.
Т.е. заголовок потока начинается с YUV4MPEG2 и заканчивается опцией C444, а не C420jpeg.
Каждая точка переводится в формат YUV и ffmpeg посылается заполненный массив, на каждую точку 3 байта.
ffmpeg строит avi, но непраильно - при просмотре всё размыто и фон сильно зелёный,
а mplayer сообщает
[console]Could not find matching colorspace[/console]
что он вызывает "-vf scale" и что он преобразует
BICUBIC scaler, yuv444p to yuv420p using MMX2.

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

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

20.10.2017 15:03 #425948

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

Войдите или зарегистрируйтесь, чтобы ответить.