Transmita vídeo h264 sem transcodificação de uma câmera Logitech C920



O atraso não foi superior a 0,3 segundos, devido ao fato de a câmera estar conectada a um BeagleBone Blue fraco com uma carga de processador não superior a 30% e o fluxo de vídeo ser transmitido por um roteador wifi a um laptop.

Inicialmente, a tarefa era transmitir vídeo do robô para um computador grande sem carregar o processador e sem atrasos. No processo de busca de câmeras e programas para esta tarefa, verificou-se que existem câmeras com codificação de vídeo baseada em hardware na própria câmera , após as quais a câmera Logitech C920 foi comprada. E começaram os testes e as experiências, durante os quais duas opções de tradução foram encontradas sem transcodificação.

Todas as ações adicionais são verificadas no Ubuntu 16.04, a segunda opção provavelmente funciona no Windows

Transmita vídeo codificado por hardware de uma câmera Logitech C920 via cvlc e v4l2


clvc - transmissão de vídeo do servidor via vlc na linha de comando.

Hardware que codifica um fluxo de vídeo


Defina as câmeras de formato de pixel como H264

v4l2-ctl --device=/dev/video1 --set-fmt-video=width=800,height=600,pixelformat=1 

Teste o H264 com vlc, para que não redefina as configurações:

 cvlc v4l2:///dev/video1 --demux h264 

Se você tentar isso, o vlc redefinirá as configurações antes de jogar:

 cvlc v4l2:///dev/video1:chroma=h264 

A reprodução funciona. Obtemos o fluxo H264 da câmera. Agora vamos passar pela rede via HTTP:

 cvlc v4l2:///dev/video1:chroma=h264:width=800:height=600 --sout '#standard{access=http,mux=ts,dst=localhost:8080,name=stream,mime=video/ts}' -vvv 

(na rede, você precisa usar o endereço IP do seu dispositivo local em vez do host local)

Lançamento do receptor:

 mplayer http://localhost:8080/ 

Acontece que o MPEG-TS permite que o mplayer se conecte ao fluxo a qualquer momento com um pequeno atraso (provavelmente esperando por um quadro-chave ou sth).

Se você usar mux = avi, mime = video / avi, precisará executar o mplayer no momento em que iniciar o vlc, caso contrário, o mplayer não começará a ser reproduzido.

Erro Ffmpeg


  • Se você tentar jogar o ffmpeg em vez do vlc, provavelmente encontrará este problema: ffmpeg.org/trac/ffmpeg/ticket/1387
  • Assim que você executar o ffmpeg, ele mudará para "Vídeo: rawvideo (YUY2 / 0x32595559)"
  • Enquanto estiver aceitando MJPEG, ele não funcionará com o H.264
  • O mesmo acontece ao usar qv4l2: iniciar a captura no modo H264 na verdade fornece a janela de vídeo YUY2

Reproduzir vídeo decodificado por hardware


O Mplayer pode reproduzir o buffer de quadros, verifique se o X não está funcionando e digite:

 mplayer http://192.168.1.100:8080/ -fs -framedrop -vo fbdev 

Você também pode jogar na janela X se quiser: execute o X na linha de comando:

 Xorg -retro &> /dev/zero 

Há toneladas de mensagens de erro fbdev que silenciosamente colocamos em / dev / zero

Reproduza um fluxo de vídeo de uma fonte LAN vlc (consulte a seção acima):

 DISPLAY=":0" mplayer http://192.168.1.100:8080/ -fs -framedrop 


Raspberry pi


Caso você tenha artefatos na imagem e os fluxos do Raspberry Pi, use:

 cvlc v4l2:///dev/video0:chroma=h264 ... 

Pode ser necessário atualizar o firmware:

 apt-get install rpi-update raspi-config rpi-update reboot 

Resumo de transmissão via cvlc e v4l2


Os testes mostraram que a carga do processador no Beaglebone Blue não ultrapassa 30%, o que é muito bom para um processador fraco, mas não está claro como enviar esse vídeo para o ROS.

Se a largura de banda do wifi não for suficiente, o atraso do vídeo aumentará bastante. Em teoria, isso pode ser resolvido alternando de tcp para udp, a documentação do cvlc menciona a possibilidade de transmissão via udp.

Transmita vídeo codificado por hardware de uma câmera Logitech C920 via Gstreamer


Artigo original do desenvolvedor que suporta este método no Gstreamer.
Instale o gstreamer no Ubuntu 16.04

 sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools sudo apt-get install libgstreamer-plugins-base1.0-dev 

A fonte uvch264src permite:


  • Capture simultaneamente um fluxo de vídeo codificado em hardware h264 e um fluxo de vídeo de rastreador.
  • Configurar codificação de vídeo por hardware (taxa de bits, quadros-chave e mais)

A fonte secundária do visor é um conceito interessante. Além do fluxo principal H.264, você obtém um fluxo secundário de baixa resolução no formato MJPG ou YUV. Não tenho certeza se esse é um recurso da câmera gstreamer, driver ou bloco de origem, mas espero que seja útil para nossas câmeras Beaglebone, desde que a função não use um processador muito grande para converter entre raw e jpg.

A seguir, é apresentado um exemplo de um pipeline que exibe um fluxo H.264 de alta resolução e um fluxo no visor:

 gst-launch-1.0 -v -e uvch264src device=/dev/video0 name=src auto-start=true src.vfsrc ! queue ! video/x-raw,format=YUY2,width=320,height=240,framerate=10/1 ! xvimagesink sync=false src.vidsrc ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false 

O fluxo primário H.264 é decodificado usando o bloco avdec_h264, acessível através do pacote gst-libav, veja notas no wiki do oz9aec . O painel do visor pode ser conectado ao fakelink, se não for necessário, mas não acho que possa ser desativado (você ainda pode desativá-lo). Pelo menos é a impressão de que estou lendo a postagem original do KaKaRoTo .

Você provavelmente ficará sobrecarregado quando vir um grande número de parâmetros que podem ser configurados para este bloco de origem:

 gst-inspect-1.0 uvch264src 

Lista de parâmetros Uvch264src
Detalhes da fábrica:
Classificação nenhuma (0)
Fonte UVC H264 de nome longo
Fonte / vídeo do Klass
Descrição Fonte de câmera de codificação UVC H264
Autor Youness Alaoui <youness.alaoui@collabora.co.uk>

Detalhes do plug-in:
Nome uvch264
Descrição Plugin de câmeras de codificação H264 compatível com UVC
Nome do arquivo /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstuvch264.so
Versão 1.8.3
Licença LGPL
Módulo de origem gst-plugins-bad
Data de lançamento da fonte 19/08/2016
Pacote binário GStreamer Bad Plugins (Ubuntu)
URL de origem launchpad.net/distros/ubuntu/+source/gst-plugins-bad1.0

GObject
+ ---- GInitiallyUnowned
+ ---- GstObject
+ ---- GstElement
+ ---- GstBin
+ ---- GstBaseCameraSrc
+ ---- GstUvcH264Src

Interfaces implementadas:
Gstchildproxy

Modelos de bloco:
Modelo SRC: 'vidsrc'
Disponibilidade: Sempre
Recursos:
video / x-raw
formato: {I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16 , NV61, NV24, GREY8, GREY16_BE, GREY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10_10410 , GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE}
largura: [1, 2147483647]
altura: [1, 2147483647]
taxa de quadros: [0/1, 2147483647/1]
image / jpeg
largura: [1, 2147483647]
altura: [1, 2147483647]
taxa de quadros: [0/1, 2147483647/1]
video / x-h264
largura: [1, 2147483647]
altura: [1, 2147483647]
taxa de quadros: [0/1, 2147483647/1]
formato de fluxo: {byte-stream, avc}
alinhamento: au
perfil: {alto, principal, linha de base, linha de base restrita}

Modelo SRC: 'imgsrc'
Disponibilidade: Sempre
Recursos:
VAZIO

Modelo SRC: 'vfsrc'
Disponibilidade: Sempre
Recursos:
video / x-raw
formato: {I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16 , NV61, NV24, GREY8, GREY16_BE, GREY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10_10410 , GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE}
largura: [1, 2147483647]
altura: [1, 2147483647]
taxa de quadros: [0/1, 2147483647/1]
image / jpeg
largura: [1, 2147483647]
altura: [1, 2147483647]
taxa de quadros: [0/1, 2147483647/1]

Sinalizadores de elemento:
nenhum conjunto de sinalizadores

Sinalizadores de lixeira:
nenhum conjunto de sinalizadores

Implementação do elemento:
Possui a função change_state (): 0x7ff438f22ba0

O elemento não possui recursos de relógio.
O elemento não possui recursos de manipulação de URI.

Almofadas:
Src: 'vfsrc'
Src: 'imgsrc'
SRC: 'vidsrc'

Propriedades do elemento:
nome: o nome do objeto
sinalizadores: ler, escrever
String Padrão: "uvch264src0"
pai: o pai do objeto
sinalizadores: ler, escrever
Objeto do tipo "GstObject"
manipulação assíncrona: a lixeira manipulará alterações de estado assíncronas
sinalizadores: ler, escrever
Booleano. Padrão: false
encaminhamento de mensagem: Encaminha todas as mensagens filhas
sinalizadores: ler, escrever
Booleano. Padrão: false
mode: O modo de captura (captura de imagem fixa ou gravação de vídeo)
sinalizadores: ler, escrever
Enum "GstCameraBin2Mode" Padrão: 2, "mode-video"
(1): modo-imagem - Captura de imagem fixa (padrão)
(2): mode-video - gravação de vídeo
zoom: fator de zoom digital (por exemplo, 1,5 significa 1,5x)
sinalizadores: ler, escrever
Flutuar. Intervalo: 1 - 3.402823e + 38 Padrão: 1
zoom máximo: fator de zoom digital (por exemplo, 1,5 significa 1,5x)
flags: legível
Flutuar. Intervalo: 1 - 3.402823e + 38 Padrão: 10
Pronto para captura: informa que este elemento está pronto para iniciar outra captura
flags: legível
Booleano. Padrão: true
pós-pré-visualizações: se as imagens de pré-visualização de captura devem ser postadas no barramento
sinalizadores: ler, escrever
Booleano. Padrão: true
preview-caps: os limites da imagem de visualização a ser publicada (NULL significa QUALQUER)
sinalizadores: ler, escrever
QUALQUER

filtro de visualização: um filtro de visualização personalizado para processar os dados da imagem de visualização
sinalizadores: ler, escrever
Objeto do tipo "GstElement"
auto-start: inicia automaticamente a captura ao ir para o estado PAUSED
sinalizadores: ler, escrever
Booleano. Padrão: false
colorspace-name: o nome do elemento colorspace
flags: ler, escrever, só pode ser NULL ou READY
String Padrão: "videoconvert"
jpeg-decoder-name: o nome do elemento decodificador jpeg
flags: ler, escrever, só pode ser NULL ou READY
String Padrão: "jpegdec"
num-clock-samples: número de amostras de relógio a serem coletadas para a sincronização do PTS (-1 = ilimitado)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: 0 - 2147483647 Padrão: 0
buffers num: número de buffers a serem enviados antes do envio do EOS (-1 = ilimitado)
sinalizadores: ler, escrever
Inteiro Intervalo: -1 - 2147483647 Padrão: -1
device: localização do dispositivo
sinalizadores: ler, escrever
String Padrão: "/ dev / video0"
nome do dispositivo: nome do dispositivo
flags: legível
String Padrão: ""
bitrate inicial: Taxa de bits inicial em bits / segundo (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Inteiro não assinado. Intervalo: 0 - 4294967295 Padrão: 3.000.000
unidades de fatia: unidades de fatia (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Inteiro não assinado. Intervalo: 0 - 65535 Padrão: 4
modo de fatia: define a unidade da propriedade de unidades de fatia (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Enumeração "UvcH264SliceMode" Padrão: 3, "fatia / quadro"
(0): ignorado - ignorado
(1): bits / fatia - bits por fatia
(2): MBs / fatia - MBs por fatia
(3): fatia / quadro - Fatia por quadro
iframe-period: tempo entre os quadros IDR em milissegundos (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Inteiro não assinado. Intervalo: 0 - 65535 Padrão: 10000
tipo de uso: o tipo de uso (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Enumeração "UvcH264UsageType" Padrão: 1, "tempo real"
(1): tempo real - Tempo real (videoconferência)
(2): broadcast - Transmissão
(3): armazenamento - armazenamento
(4): ucconfig0 - UCConfig 0
(5): ucconfig1 - UCConfig 1
(6): ucconfig2q - UCConfig 2Q
(7): ucconfig2s - UCConfig 2S
(8): ucconfig3 - UCConfig 3
entropia: Entropia (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Enumeração "UvcH264Entropy" Padrão: 0, "cavlc"
(0): cavlc - CAVLC
(1): cabac - CABAC
enable-sei: Ativa o tempo da imagem SEI (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Booleano. Padrão: false
num-reorder-frames: Número de quadros B entre os quadros de referência (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Inteiro não assinado. Intervalo: 0 - 255 Padrão: 0
visualização invertida: imagem invertida horizontal para fluxos não H.264 (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Booleano. Padrão: false
tamanho do balde com vazamento: tamanho do tamanho do balde com vazamento em milissegundos (controle estático)
flags: ler, escrever, só pode ser NULL ou READY
Inteiro não assinado. Intervalo: 0 - 65535 Padrão: 1000
controle de taxa: modo de controle de taxa (controle estático e dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Enumeração "UvcH264RateControl" Padrão: 1, "cbr"
(1): cbr - Taxa de bits constante
(2): vbr - Taxa de bits variável
(3): qp - QP constante
framerate fixo: Taxa de quadros fixa (controle estático e dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Booleano. Padrão: false
max-mbps: o número de macroblocos por segundo para a taxa máxima de processamento
flags: legível
Inteiro não assinado. Intervalo: 0 - 4294967295 Padrão: 0
level-idc: IDC de nível (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro não assinado. Intervalo: 0 - 255 Padrão: 40
pico de taxa de bits: o pico de taxa de bits em bits / segundo (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro não assinado. Intervalo: 0 - 4294967295 Padrão: 3.000.000
bitrate médio: o bitrate médio em bits / segundo (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro não assinado. Intervalo: 0 - 4294967295 Padrão: 3.000.000
min-iframe-qp: o tamanho mínimo da etapa de quantização para quadros I (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: -127 - 127 Padrão: 10
max-iframe-qp: o tamanho mínimo da etapa de quantização para quadros I (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: -127 - 127 Padrão: 46
min-pframe-qp: o tamanho mínimo da etapa de quantização para quadros P (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: -127 - 127 Padrão: 10
max-pframe-qp: o tamanho mínimo da etapa de quantização para quadros P (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: -127 - 127 Padrão: 46
min-bframe-qp: o tamanho mínimo da etapa de quantização para quadros B (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: -127 - 127 Padrão: 10
max-bframe-qp: o tamanho mínimo da etapa de quantização para quadros B (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: -127 - 127 Padrão: 46
ltr-buffer-size: número total de quadros de referência de longo prazo (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: 0 - 255 Padrão: 0
ltr-encoder-control: número de quadros LTR que o dispositivo pode controlar (controle dinâmico)
sinalizadores: ler, escrever, pode ser NULL, PRONTO, PAUSADO ou REPRODUZIDO
Inteiro Intervalo: 0 - 255 Padrão: 0

Ações do elemento:
"Get-enum-setting": gboolean user_function (GstElement * objeto,
gchararray arg0,
gpointer arg1,
gpointer arg2);
"Get-boolean-setting": gboolean user_function (GstElement * objeto,
gchararray arg0,
gpointer arg1,
gpointer arg2);
"Get-int-setting": gboolean user_function (GstElement * objeto,
gchararray arg0,
gpointer arg1,
gpointer arg2,
gpointer arg3);
"Start-capture": void user_function (objeto GstElement *);
"Stop-capture": void user_function (objeto GstElement *);

Muitos desses parâmetros podem ser usados ​​para configurar parâmetros na compactação H.264. Acho isso surpreendente, uma vez que a compressão é realizada pelo chip dentro da câmera. O exemplo a seguir aumenta a taxa de dados padrão de 3 para 5 Mbps e reduz o intervalo do quadro-chave padrão de 10 para 3 segundos:

 gst-launch-1.0 -v -e uvch264src initial-bitrate=5000000 average-bitrate=5000000 iframe-period=3000 device=/dev/video0 name=src auto-start=true src.vfsrc ! queue ! video/x-raw,format=YUY2,width=320,height=240,framerate=10/1 ! xvimagesink sync=false src.vidsrc ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false 

Por outro lado, não há parâmetros para ajustar os parâmetros usuais da webcam, como contraste, brilho, foco, etc. Portanto, para configurá-los, ainda precisamos de ferramentas externas, como v4l2.ctl, ou a opção mencionada em próxima seção.

v4l2src


Parece que também podemos usar o bom e velho v4l2src para capturar fluxos codificados em H.264 do Logitech C920:

 gst-launch-1.0 -v -e v4l2src device=/dev/video1 ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false 

Isto é provavelmente devido à evolução do gstreamer e do V4L2. Essa opção parece mais simples se você não precisar alterar as configurações de compactação H.264, e isso nos dá acesso às configurações da câmera, como brilho e contraste. Ele também tem a vantagem de estar em um bom pacote de plugins que pode ser melhor guardado no futuro.

Webcasting via Gstreamer


No computador receptor, inicie o receptor:

 gst-launch-1.0 -v udpsrc port=6666 ! application/x-rtp, encoding-name=H264 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink 

Em um dispositivo com uma câmera, iniciamos a transmissão de vídeo codificado por hardware:

 gst-launch-1.0 uvch264src name=src auto-start=true src.vidsrc ! video/x-h264,width=160,height=120,framerate=30/1 ! h264parse ! rtph264pay ! udpsink host=192.168.1.196 port=6666 

Agradecimentos especiais a Amomum por me ajudar a escrever este código.

Resumo do atraso na transmissão de vídeo através do Gstreamer


Mesmo com uma resolução de 1920 * 1080, a carga do processador no Beaglebone Blue não excedeu 30% e o atraso do vídeo não foi superior a 0,3 segundos. Sim, como o vídeo nesta versão foi transmitido via udp, quando os pacotes são perdidos, a imagem desmorona para o próximo quadro-chave, mas podemos configurá-lo para que os quadros-chave sejam enviados com mais frequência.

Tarefas ROS


Agora resta apenas enviar o vídeo recebido para o ROS, se alguém puder ajudar com isso, escreva em um arquivo pessoal.

Source: https://habr.com/ru/post/pt415567/


All Articles