Can an sdp error cause stream corruption? - raspberry-pi

I am trying to get a RTP (over udp) live stream (h264) from my Raspberry Pi using GStreamer (rpicamsrc). The video is being capture and forwarded to the browser using the Kurento Media Server, i.e. RPi -> KMS -> Browser.
The stream comes through with about 4s delay (which is not ideal but okay) however what is displayed seems to be corrupted and I am not sure why.
Corrupted Stream Display:
Some colleagues have suggested problems with interlacing/ p-frames (?) but I don't have any clue about this or what I should be looking for.
Mangled SDP from receiver
String rtpSdpOffer =
"v=0\r\n"
+ "o=- 0 0 IN IP4 " + senderIp + "\r\n"
+ "s=Kurento Tutorial - RTP Player\r\n"
+ "c=IN IP4 " + senderIp + "\r\n"
+ "t=0 0\r\n";
if (useAudio) {
rtpSdpOffer +=
"m=audio " + senderRtpPortA + " RTP/AVPF 96\r\n"
+ "a=rtpmap:96 opus/48000/2\r\n"
+ "a=sendonly\r\n"
+ sdpComediaAttr
+ "a=ssrc:" + senderSsrcA + " cname:" + senderCname + "\r\n";
}
rtpSdpOffer +=
"m=video " + senderRtpPortV + " " + senderProtocol + " 103\r\n"
+ sdpCryptoAttr
+ "a=rtpmap:103 " + senderCodecV + "/90000\r\n"
+ "a=rtcp-fb:103 goog-remb\r\n"
+ "a=sendonly\r\n"
+ sdpComediaAttr
+ "a=ssrc:" + senderSsrcV + " cname:" + senderCname + "\r\n"
+ "";
Gstreamer script to begin stream
PEER_A={KMS_AUDIO_PORT} PEER_V={KMS_VIDEO_PORT} PEER_IP={KMS_PUBLIC_IP} \
SELF_PATH="{PATH_TO_VIDEO_FILE}" \
SELF_A=5006 SELF_ASSRC=445566 \
SELF_V=5004 SELF_VSSRC=112233 \
bash -c 'gst-launch-1.0 -e \
rtpbin name=r sdes="application/x-rtp-source-sdes,cname=(string)\"user\#example.com\"" \
rpicamsrc ! video/x-raw,width=200,height=150,framerate=25/1 ! decodebin name=d \
d. ! x264enc tune=zerolatency \
! rtph264pay ! "application/x-rtp,payload=(int)103,clock-rate=(int)90000,ssrc=(uint)$SELF_VSSRC" \
! r.send_rtp_sink_1 \
r.send_rtp_src_1 ! udpsink host=$PEER_IP port=$PEER_V bind-port=$SELF_V \
r.send_rtcp_src_1 ! udpsink host=$PEER_IP port=$((PEER_V+1)) bind-port=$((SELF_V+1)) sync=false async=false \
udpsrc port=$((SELF_V+1)) ! tee name=t \
t. ! queue ! r.recv_rtcp_sink_1 \
t. ! queue ! fakesink dump=true async=false'
Any help is greatly appreciated

SDP can cause corruption. If the codec data you would transmit in there does not match the stream. But it looks like you don't transmit codec data via SDP - but probably in-band.
The artifact in the image looks like a rowbyte/stride problem. Maybe caused by your video dimensions. It is recommend to use resolutions multiple of 16. However it should still work. It could be that the decoder/renderer does something weird. I would try to receive the stream and save to file watch it in a regular video player and check whether it displays better and what video dimensions are being reported.

Related

If YAD is a fork of Zenity why is there no --imagelist?

Zenity is used in many of my bash projects, but looking at the advanced features of YAD there are many reasons to switch. After some testing unfortunately I discovered there is no --imagelist option for the list type dialog. This is a major problem as most of my projects use imagelists.
The below example runs on zenity version 3.28.1
#!/bin/bash
table=(~/image.png " " "Title1" " " "description1" "output1" ~/image.png " " "Title2" " " "description2" "output2" ~/image.png " " "Title3" " " "description3" "output3")
zenity --list --title="page title" --text="some random text" --imagelist --ok-label=Open --cancel-label=Home --print-column=6 --hide-column=6 --separator=' ' --width=600 --height=400 \
--column="Cover image" \
--column=" " \
--column="Name" \
--column=" " \
--column="details" \
--column="Folder" \
"${table[#]}"
the dialog should look like this:
In this example ${table[#]} is an array that contains all the data for each row including the file-path to the image in column 1. Is there a way to do this in YAD?
I installed YAD and looked at all the help pages provided in terminal, also tried to run similar imagelist examples, but it seems to be not supported (syntax is mostly the same as YAD is a fork of zenity)
With yad the columns can have a type associated with them. In your case you want to use the :IMG type for the first column, and the other two can remain as plain text.
table=(
~/image.png "" "Title1" "" "description1" "output1"
~/image.png "" "Title2" "" "description2" "output2"
~/image.png "" "Title3" "" "description3" "output3"
)
yad \
--list \
--title="page title" \
--text="some random text" \
--imagelist \
--print-column=6 \
--hide-column=6 \
--separator=' ' \
--width=600 \
--height=400 \
--column="Cover image:IMG" \
--column=" " \
--column="Name" \
--column=" " \
--column="details" \
--column="Folder" \
--button="Home":1 \
--button="Open":20 \
--response=20 \
"${table[#]}"
The output, missing your images
That will set the exit code to 20 if you press Enter or click Open on a list item, as well as outputting "output1" or "output2" etc.
That said, I have been experiencing issues with the exit codes or output text not appearing correctly. The above example works fine for me, but if I change the the Open exit code to "25" instead of "20" it stops working. No idea why it behaves inconsistently.

Generate many files with wildcard, then merge into one

I have two rules on my Snakefile: one generates several sets of files using wildcards, the other one merges everything into a single file. This is how I wrote it:
chr = range(1,23)
rule generate:
input:
og_files = config["tmp"] + '/chr{chr}.bgen',
output:
out = multiext(config["tmp"] + '/plink/chr{{chr}}',
'.bed', '.bim', '.fam')
shell:
"""
plink \
--bgen {input.og_files} \
--make-bed \
--oxford-single-chr \
--out {config[tmp]}/plink/chr{chr}
"""
rule merge:
input:
plink_chr = expand(config["tmp"] + '/plink/chr{chr}.{ext}',
chr = chr,
ext = ['bed', 'bim', 'fam'])
output:
out = multiext(config["tmp"] + '/all',
'.bed', '.bim', '.fam')
shell:
"""
plink \
--pmerge-list-dir {config[tmp]}/plink \
--make-bed \
--out {config[tmp]}/all
"""
Unfortunately, this does not allow me to track the file coming from the first rule to the 2nd rule:
$ snakemake -s myfile.smk -c1 -np
Building DAG of jobs...
MissingInputException in line 17 of myfile.smk:
Missing input files for rule merge:
[list of all the files made by expand()]
What can I use to be able to generate the 22 sets of files with the wildcard chr in generate, but be able to track them in the input of merge? Thank you in advance for your help
In rule generate I think you don't want to escape the {chr} wildcard, otherwise it doesn't get replaced. I.e.:
out = multiext(config["tmp"] + '/plink/chr{{chr}}',
'.bed', '.bim', '.fam')
should be:
out = multiext(config["tmp"] + '/plink/chr{chr}',
'.bed', '.bim', '.fam')

How to add quality in FFmpeg video transcoding?

I don't have much knowledge of FFmpeg. I have googled and made the following code for creating two quality hls transcoding for the video files. It is working fine.
I want to create 4 types of video quality. 720,480,320,240.
final arguments = '-y -i $videoPath ' +
'-preset ultrafast -g 48 -sc_threshold 0 ' +
'-map 0:0 -map 0:1 -map 0:0 -map 0:1 ' +
'-c:v:0 libx264 -b:v:0 2000k ' +
'-c:v:1 libx264 -b:v:1 365k ' +
'-c:a copy ' +
'-var_stream_map "v:0,a:0 v:1,a:1" ' +
'-master_pl_name master.m3u8 ' +
'-f hls -hls_time 6 -hls_list_size 0 ' +
'-hls_segment_filename "$outDirPath/%v_fileSequence_%d.ts" ' +
'$outDirPath/%v_playlistVariant.m3u8';
I am using flutter_ffmpeg (https://pub.dev/packages/flutter_ffmpeg) plugin to call this code.
Any help is appreciated.

Progress 4gl Secure Socket Authentication

Currently attempting to perform a socket connection to a host that has authentication setup using the username:password#domain syntax. The following curl request works fine when run via command line:
/opt/pware/bin/curl -s -v -S -k -X POST -d #/test/worldpay.xml https://username:password#secure-test.worldpay.com/jsp/merchant/xml/paymentService.jsp
The problem lies when attempting to post the same worldpay.xml payload file using progress secure socket. My socket connects using the following:
DEFINE VARIABLE vhSocket AS HANDLE NO-UNDO.
CREATE SOCKET vhSocket.
vhSocket:CONNECT('-H test.worldpay.com -S 443 -ssl -nohostverify') NO-ERROR.
IF vhSocket:CONNECTED() EQ FALSE THEN
DO:
Message "COULD NOT CONNECT".
vhSocket:DISCONNECT().
DELETE OBJECT vhSocket NO-ERROR.
RETURN.
END.
ELSE
Message "CONNECTED!".
I am setting up my header as follows once the socket connection is opened:
ASSIGN
vRequest = 'POST ' +
username + ":" + password + "#" + "/jsp/merchant/xml/paymentService.jsp" +
' HTTPS/1.1' + chr(13) + chr(10) +
'Connect: close' + chr(13) + chr(10) +
'Host: ' + "secure-test.worldpay.com" + chr(13) + chr(10) +
'Content-Length: ' + string(LENGTH(postdata,"raw")) + chr(13) + chr(10) +
'Content-Type: text/xml' + chr(13) + chr(10) +
chr(13) + chr(10) +
postData +
chr(13) + chr(10).
set-byte-order(vData) = BIG-ENDIAN.
set-size(vData) = LENGTH(vRequest,"raw").
put-string(vData,1,LENGTH(vRequest,"raw")) = vRequest.
vReturnCode = vhSocket:WRITE(vData, 1, LENGTH(vRequest,"raw")).
Any help on figuring out how the header should be structured or how to perform basic authentication over Secure Sockets in Progress would be greatly appreciated. Thanks guys!
For http(s) basic authentication, you don't POST the username as part of the URL.
See https://en.wikipedia.org/wiki/Basic_access_authentication#Client_side
This is what we use in our http client, you'll have to change the call to AddHttpHeader to code that send that header line to the server socket.
/*------------------------------------------------------------------------------
Purpose: Adds a basic authorization header to the request
Notes:
#param pcUserName The UserName to use for basic authorization
#param pcPassword The password to use for basic authorization
------------------------------------------------------------------------------*/
METHOD PUBLIC VOID SetBasicAuthorization (pcUserName AS CHARACTER,
pcPassword AS CHARACTER):
DEFINE VARIABLE cBase64 AS LONGCHAR NO-UNDO.
DEFINE VARIABLE mAuthorization AS MEMPTR NO-UNDO .
ASSIGN cBase64 = SUBSTITUTE ("&1:&2":U, pcUserName, pcPassword) .
SET-SIZE (mAuthorization) = LENGTH (cBase64) .
PUT-STRING (mAuthorization, 1, LENGTH (cBase64)) = cBase64 .
ASSIGN cBase64 = BASE64-ENCODE (mAuthorization) .
AddHttpHeader (SUBSTITUTE ("Authorization Basic &1":U, cBase64)) .
FINALLY:
SET-SIZE (mAuthorization) = 0 .
END FINALLY.
END METHOD .
So in your case, try this:
ASSIGN
vRequest = 'POST ' + "/jsp/merchant/xml/paymentService.jsp" +
' HTTPS/1.1' + chr(13) + chr(10) +
'Connect: close' + chr(13) + chr(10) +
'Host: ' + "secure-test.worldpay.com" + chr(13) + chr(10) +
'Content-Length: ' + string(LENGTH(postdata,"raw")) + chr(13) + chr(10) +
'Content-Type: text/xml' + chr(13) + chr(10) +
'Authorization: Basic ' + cBase64 + chr(13) + chr(10) +
chr(13) + chr(10) +
postData +
chr(13) + chr(10).

Scala Process for Linux is stuck

I'm trying to use Scala Process in order to concate two files and send the result to a new file.
The code works fine, but when i remove the permissions to the folder, it seems to be stuck.
Here is the code:
val copyCommand = Seq("bash", "-c", "cat \"" + headerPath + "\" \"" + FilePath + "\"")
Process(copyCommand).#>>(new File(FileWithHeader)).!
Maybe something like this can help (without invoking bash)?
import sys.process._
(Seq("cat", "file-1.txt", "file-2.txt") #>> new java.io.File("files-1n2.txt")).!
I preformed the concatination in the same comend without creating new file and it's work fine:
val copyCommand = Seq("bash", "-c", "cat \"" + headerPath + "\" \"" + FilePath + "\">FileWithHeader")
Process(copyCommand).#!