GStreamer/iMX6: streaming h264 encoded video over serial port between iMX6 and PC - serial-port

Recently, I have started to work on a project that aims at live video streaming applications based on imx6 processors. A quick description of what I have done so far and what I am trying to do:
Setup: imx6 board(Boundary devices Sabre Lite) acting as the video server(using GStreamer imx plugins), and a PC running Ubuntu on it that receives data from imx6 and streams the video using GStreamer features.
On the imx6 processor, I run the 'testvideosrc' and have successfully streamed it using the RTP over UDP using eternet interface between the imx6 and the PC.
Accessing the serial port using the device files in Linux, next I tried out dumping the video data from imx6 board to a serial port and reading this serial port on the PC. For this, the baud rate of both devices was configured to 115200 baud. The encoding 'bitrate' is configured to 5Kbps. Here are the commands:
IMX6:
#gst-launch-1.0 -v videotestsrc pattern=18 ! video/x- raw,width=100,height=50 ! imxvpuenc_h264 bitrate=5 ! h264parse ! filesink location=/dev/ttyUSB1
PC:
#CAPS=video/x-h264
#gst-launch-1.0 -v filesrc location=/dev/ttyUSB1 ! $CAPS ! h264parse ! avdec_h264 ! autovideosink sync=true
There are no errors observed on the imx6 board.
However, I see the following errors at the PC side:
# GST_DEBUG=3 gst-launch-1.0 -v filesrc location=/dev/ttyUSB1 ! $CAPS ! h264parse ! avdec_h264 ! autovideosink sync=true
Setting pipeline to PAUSED …
0:00:00.066439392 15475 0x556d8a01d160 WARN basesrc gstbasesrc.c:3583:gst_base_src_start_complete: pad not activated yet
Pipeline is PREROLLING …
0:00:21.730466251 15475 0x556d8a000940 WARN capsfilter
gstcapsfilter.c:455:gst_capsfilter_prepare_buf: error: Filter caps do not completely specify the output format
0:00:21.730523691 15475 0x556d8a000940 WARN capsfilter gstcapsfilter.c:455:gst_capsfilter_prepare_buf: error: Output caps are unfixed: video/x-h264, width=(int)[ 1, 8192 ], height=(int)[ 1, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
0:00:21.730676173 15475 0x556d8a000940 WARN basetransform gstbasetransform.c:2159:default_generate_output: could not get buffer from pool: error
0:00:21.730742223 15475 0x556d8a000940 WARN basesrc gstbasesrc.c:3055:gst_base_src_loop: error: Internal data stream error.
0:00:21.730775478 15475 0x556d8a000940 WARN basesrc gstbasesrc.c:3055:gst_base_src_loop: error: streaming stopped, reason error (-5)
ERROR: from element /GstPipeline:pipeline0/GstCapsFilter:capsfilter0: Filter caps do not completely specify the output format
Additional debug info:
gstcapsfilter.c(455): gst_capsfilter_prepare_buf (): /GstPipeline:pipeline0/GstCapsFilter:capsfilter0:
Output caps are unfixed: video/x-h264, width=(int)[ 1, 8192 ], height=(int)[ 1, 8192 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
ERROR: pipeline doesn’t want to preroll.
Setting pipeline to NULL …
Freeing pipeline …
Since, the encoding rate is 5Kbps (bitrate=5, as specified in the above command), I suppose it is possible to send this amount of data via the serial port. I realize that currently, the caps negotiation fails, however, I am unsure of how to proceed with this.
On the PC side, reading the serial port with 'cat /dev/ttyUSB1' succeeds with limited data. The data is unreadable(as expected), however it is not a continuous stream.
Does anyone have an idea, on how to solve this. I also think, I am misinterpreting the usage of Linux device files, when I am attempting to read over the serial data file using GStreamer.
My later test, would be to use an actual camera(MIPI) and try streaming it over serial port. Does it seem feasible or is a completely crazy idea to do?

With the following commands, I could get this working on serial with a baud of 19200. However, the latency is very high in the range of 5-6 seconds. With a baud of 1M, it works with less noticeable latency < 1s.
imx6:
gst-launch-1.0 -v videotestsrc pattern=18 ! video/x-raw,width=100,height=50
! imxvpuenc_h264 bitrate=5 ! h264parse ! filesink location=/dev/ttyUSB0
blocksize=1024 max-bitrate=19000 sync=false
PC:
gst-launch-1.0 -v filesrc location=/dev/ttyUSB1 blocksize=1024 ! $CAPS !
h264parse ! avdec_h264 lowres=2 skip-frame=0 ! autovideosink sync=false

Related

RTMP Nginx exec_push with alaw and h264

I have 2 RTMP servers, one NGINX with the RTMP module, and a second one that can only consume RTMP with H264 and ALAW, which will receive video from the NGINX one.
I successfully pushed my camera image to the second server using Gstreamer:
gst-launch-1.0 v4l2src device="/dev/video0" ! videoconvert ! video/x-raw,format=I420 ! x264enc speed-preset=ultrafast tune=zerolatency key-int-max=20 ! flvmux name=flvmux ! rtmpsink location=rtmp://<second_server_ip>:1935/publish/foobar audiotestsrc ! alawenc ! flvmux.
Now, I need to send a video from the NGINX server to the second server, but it needs to have H264 video encoding and ALAW audio encoding.
I tried one more intermediate step, where I streamed to the NGINX server and ran
gst-launch-1.0 rtmpsrc location=rtmp://<nginx_ip>:1935/live/100 ! videoconvert ! video/x-raw,format=I420 ! x264enc speed-preset=ultrafast tune=zerolatency key-int-max=20 ! flvmux name=flvmux ! rtmpsink location=rtmp://<second_server_ip>:1935/publish/foobar audiotestsrc ! alawenc | flvmux.
but I got
Setting pipeline to PAUSED ...
pipeline is PREROLLING ...
ERROR: from element /GstPipeline:pipeline0/GstRTMPSrc:rtmpsrc0: Internal data stream error.
Additional debug info:
gstbasesrc.c(3072): gst_base_src_loop (): /GstPipeline:pipeline0/GstRTMPSrc:rtmpsrc0:
streaming stopped, reason not-negotiated (-4)
ERROR: pipeline doesn't want to preroll.
What am I missing in the GStreamer command? And how can I add it to the NGINX application to automatically push the streams received? I'm ok with doing it with FFmpeg if I need to.
Thank you
EDIT:
My first server will be fed with a stream from a mobile app. This server (NGINX) is configured like this:
application live {
live on;
interleave on;
}
This server should push to a second server (written in Go), which is going to convert RTMP to WebRTC so I can play the stream in a browser. As I previously stated, I have successfully streamed RTMP to the second server with GStreamer, but I want the first server to automatically push to the second, and it's that push that I been able todo yet.
EDIT 2:
I have used VLC and the encoding is H264, so no problem there. But I do need ALAW instead of MPEG AAC audio, how can I change on the NGINX server when I push it to the second server?

Problem Flashing nrf52 chip using Openocd

I have a custom nrf52 chip on a pcb with swd pins exposed. I have cloned and installed the latest openocd from https://github.com/ntfreak/openocd. The latest version includes all the latest pathes for the nrf52 chip, so no need for any additional changes as suggested in many older guides online. I am able to connect to the chip using ST-LinkV2. when connected I can read and write memory locations using mdw and mdb. I can also run some basic openocd commands like dump_image e.t.c, which confirms that the setup is good. But halt and program commannds always lead to errors like:
JTAG failure -4
JTAG failure -4
JTAG failure -4
JTAG failure -4
JTAG failure -4
JTAG failure -4
target halted due to debug-request, current mode: Thread
xPSR: 00000000 pc: 00000000 msp: 00000000
jtag status contains invalid mode value - communication failure
Polling target nrf52.cpu failed, trying to reexamine
Examination failed, GDB will be halted. Polling again in 100ms
Previous state query failed, trying to reconnect
jtag status contains invalid mode value - communication failure
Polling target nrf52.cpu failed, trying to reexamine
if I try to use flash image_write I get the error,
JTAG failure
Error setting register
error starting target flash write algorithm
Failed to enable read-only operation
Failed to write to nrf52 flash
error writing to flash at address 0x00000000 at offset 0x00000000
in procedure 'dap'
jtag status contains invalid mode value - communication failure
Polling target nrf52.cpu failed, trying to reexamine
I have read different guides online, and one of the possible solutions involves the APPPROTECT register which has to be disabled to enable any writes to flash.
APP_PROTECT, But the dap commmand which is supposed to help us access this bit,
dap apreg 1 0x04 0x01
returns an error:
invalid subcommand apreg 1 0x04 0x01
Please, I will like to know if anyone has had success programming a new empty nrf52 chip with the stlink-v2 and the steps which are necessary, or if any one has encountered similar problems. Thanks.
Here is my config file:
#nRF52832 Target
source [find interface/stlink.cfg]
transport select hla_swd
source [find target/nrf52.cfg]
#reset_config srst_nogate connect_assert_srst
I solved the "protected nRF52" chip problem this way, on Windows, using a Particle.io Debugger https://store.particle.io/products/particle-debugger setup to program nRF52 chips from Arduino as described in https://www.forward.com.au/pfod/BLE/LowPower/index.html
Note: The recovery process described here does NOT need Arduino to be installed
Download OpenOCD-20181130.7z pre-compiled openocd for windows from
http://gnutoolchains.com/arm-eabi/openocd/
The latest version of openocd src on https://github.com/ntfreak/openocd should also work as it includes the apreg cmd in target\arm_adi_v5.c
unzip, open cmd prompt to unzip dir, enter cmd
bin\openocd.exe -d2 -f interface/cmsis-dap.cfg -f target/nrf52.cfg
response
Info : auto-selecting first available session transport "swd". To override use '
transport select <transport>'.
adapter speed: 1000 kHz
cortex_m reset_config sysresetreq
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : CMSIS-DAP: SWD Supported
Info : CMSIS-DAP: FW Version = 1.10
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Error: Could not find MEM-AP to control the core
Info : Listening on port 3333 for gdb connections
Open telnet program eg teraTerm and connect to localhost on port 4444, i.e. 127.0.0.1 telnet port 4444
cmd window shows
Info : accepting 'telnet' connection on tcp/4444
in telnet (i.e. teraTerm) type
nrf52.dap apreg 1 0x04
returns 0 <<< chip protected
then
nrf52.dap apreg 1 0x04 0x01
then
nrf52.dap apreg 1 0x04
returns 1 << chip un-protected
then power cycle board
Can now use arduino ide to flash softdevice and code low power BLE
Even though the dap command is listed by openOCD help, it isn't implemented for transport hla_swd that you have to use with ST-Link.
If the ST-Link is a generic type from China, it can be upgraded to CMSIS-DAP which uses the swd transport and supports the nrf52.dap apreg 1 0x04 0x01 command to disable the readback protection and erase the flash. You'll need another ST-Link to do that, or you can instead install CMSIS-DAP on a generic STM32F103C8T6 board.
After that you can either use ST-Link to program the nRF52 or continue using CMSIS-DAP, which can also be used to program STM32 MCU.
Nucleo board embedded ST-Links can also be upgraded to J-Link, which allow the use of the "recover" option in nRFgo Studio to erase the flash, it should also work with "nrfjtool --recover" or OpenOCD.
If anyone encounters this problem, I solved the problem by getting an original Jlink-Edu. I also had to pull the reset pin of the microcontroller high to get the jlink working.
There are lots of JTAG messages.
I think you might be missing the
transport select hla_swd
line in your (board) cfg file. The NRF5x chips only work properly with SWD, and ST-Link uses the hla_swd variant.

How to send boot files over uart

I have a beaglebone black board. A host with 64 bit ubuntu14.04
I wanted to transfer uImage file over uart to beaglebone.
So I stopped at u-boot and type
U-Boot# loadb
## Ready for binary (kermit) download to 0x80200000 at 115200 bps...
Now it is waiting for the file. What I have to do in order to send the uImage from pc to board.
After the loadb command prints "Ready for binary download", exit from the terminal(minicom, putty etc). Note down the serial device (eg: /dev/ttyUSB0). Install kermit or its variants (eg: gkermit and ckermit are available in Ubuntu).
Assuming that /dev/ttyUSB0 is your serial device, baudrate is 115200, and no flow control is used, provide the following parameters to kermit
$kermit
kermit> set port /dev/ttyUSB0
kermit> set speed 115200
kermit> set carrier-watch off
kermit> set flow-control none
Now issue the command send , to send the file over serial line:
kermit> send filename
After the file transfer is successful, exit from kermit (use exit command), and re-open minicom. Now you can issue further commands.
NOTE : You can explicitly specify a load address to loadb. If not specified, U-boot takes load address from environment variables.
NOTE-2 : Some terminal programs have built-in facility to send files over serial line using protocols like xmodem or kermit.

Asterisk WARNING[4695]: chan_dahdi.c:12320 do_monitor: Read failed with -1: Invalid argument

when I restart Asterisk and connect to the Asterisk console with a
asterisk -rv
Asterisk is spitting thousands of
WARNING[4695]: chan_dahdi.c:12320 do_monitor: Read failed with -1: Invalid argument
after some minutes of this crazy spitting of messages it quits with a
*CLI>
Disconnected from Asterisk server
Asterisk cleanly ending (0).
Executing last minute cleanups
a dmesg shows:
[ 3561.591539] asterisk[4695]: segfault at b3150fec ip b73a4b8d sp b3150ff0 error 6 in libc-2.19.so[b7334000+1a8000]
I have no idea how to deal with this and find no similar error anywhere.
I am using a Digium TDM410P telephony card with 2 FXO and two FXS interfaces.
Dahdi linux driver < 2.10.0.1 is incompatible with linux kernel 3.16+
See complete problem description and fix in Asterisk Jira:
https://issues.asterisk.org/jira/browse/DAHLIN-340

how to redirect the output of serial console (e.g. /dev/ttyS0) to a buffer or file

Is it possible to pipe serial console output to a file or a buffer or some virtual or pseudo device (in /dev)?
The Kernel command line has in startup at this point "console=null,115200".
(Normally it has "console=ttyS0,115200" - my requirement is: if "console=null,115200", should the output go to some other place than ttyS0, e.g. a virtual or pseudo device or to a file/buffer)
Maybe somebody know if there is good solution available?
Thanks a lot in advance!
There are two ways that I am aware of :-
First way :-
get ttylog from sourceforge :-
http://sourceforge.net/projects/ttylog/files/latest/download
Fire the below command:-
nohup ttylog -b 115200 -d /dev/ttyS0 > log.txt
this will then show you the PID of the process that is running, you now need to disown that PID so it doesn't get killed when you log out. Note that 115200 is the serial port speed/baud rate you configured grub for on the box you are monitoring.
Second way :-
Setup a serial console from system under test to some other linux/windows box. In case of linux install minicom and set minicom to listen on the serial port define in grub of system under test. Save that as dfl. You are good to go for more info :-
https://www.kernel.org/doc/Documentation/serial-console.txt

Resources