Gstreamer RTSP-Server gst_rtsp_media_factory_set_launch() Example - udp

I want to change the pipeline by using the gst_rtsp_media_factory_set_launch() function to receive an interrupt in the middle from RTSP-Server. I used the media_configure() callback function to get the GstElement for the pipeline. If an interrupt is received in the middle, it is changed to GST_STATE_NULL and then the command entered into the gst_rtsp_media_factory_set_launch() function has been changed. Specifically, when the user presses Ctrl+C while streaming V4L2 video0, V4L2 video1 will be streamed. The implementation was successful(i.e. change from video0 to video1), but there is a problem that the screen freezes for about 3 seconds after Ctrl+C and moves on to the next screen. This was not the case when using UDP, but this problem occurs when using RTSP. Please advise me, Thank You!
#include <gst/rtsp-server/rtsp-server.h>
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GstRTSPMediaFactory *factory;
GMainLoop *loop;
GstElement *pipeline;
void INThandler(int sig_no)
{
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_rtsp_media_factory_set_launch (factory, "( v4l2src device=/dev/video1 ! compositor ! vpuenc_h264 ! rtph264pay pt=96 name=pay0 )");
//gst_rtsp_media_factory_set_launch (factory, "( filesrc location=test2.mp4 ! qtdemux ! decodebin ! compositor ! queue2 ! vpuenc_h264 ! rtph264pay pt=96 name=pay0 )");
}
static void media_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media,
gpointer user_data)
{
pipeline = gst_rtsp_media_get_element (media);
}
int main(int argc,char * argv[])
{
signal(SIGINT, INThandler);
gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE);
server = gst_rtsp_server_new ();
gst_rtsp_server_set_service(server, "5002");
mounts = gst_rtsp_server_get_mount_points (server);
factory = gst_rtsp_media_factory_new ();
gst_rtsp_media_factory_set_launch (factory, "( v4l2src device=/dev/video0 ! queue2 ! vpuenc_h264 ! rtph264pay pt=96 name=pay0 )");
//gst_rtsp_media_factory_set_launch (factory, "( filesrc location=test1.mp4 ! qtdemux ! decodebin ! compositor ! queue2 ! vpuenc_h264 ! rtph264pay pt=96 name=pay0 )");
g_signal_connect (factory, "media-configure", (GCallback) media_configure, NULL);
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
g_object_unref (mounts);
gst_rtsp_server_attach (server, NULL);
g_main_loop_run(loop);
return 0;
}

Related

How to get the value 3 on the first request without await?

In this case, if there was an opportunity to use await, then there would be no reason to create a question, but await is not recommended to be used in contracts:
Note: This feature was designed to be used in debots, in usual contracts use it at your own risk. https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md#synchronous-calls
Pong.sol
pragma ton-solidity ^0.51.0;
contract Pong {
function get(uint b) external responsible returns (uint) {
return b + 1;
}
}
Ping.sol
pragma ton-solidity ^0.51.0;
interface IPong {
function get(uint b) external responsible returns (uint);
}
contract Ping {
uint public result;
uint public tmp;
function run(address pong, uint a) public view returns(uint) {
update(pong, a);
tvm.accept();
return a + tmp;
}
function update(address pong, uint a) internal pure {
IPong(pong).get{callback: Ping.onGet}(a);
}
function onGet(uint b) external {
tvm.accept();
tmp = b;
}
}
Run.bash
#!/usr/bin/env bash
set -o errexit
tondev se reset
rm -fr *.abi.json *.tvc
# Deploy Pong Contract
tondev sol compile Pong.sol
tondev contract deploy Pong --value 1000000000
pongAddress=$(tondev contract info Pong | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pongAddress"
# Deploy Ping Contract
tondev sol compile Ping.sol
tondev contract deploy Ping --value 1000000000
pingAddress=$(tondev contract info Ping | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pingAddress"
# Run
tondev contract run Ping run --input "pong:$pongAddress,a:1" | grep value0
# value0:0x0000000000000000000000000000000000000000000000000000000000000001
tondev contract run Ping run --input "pong:$pongAddress,a:1" | grep value0
# value0:0x0000000000000000000000000000000000000000000000000000000000000003
The purpose of the question is to understand how to get the value 3 on the first request, if possible. If not, then a more extensive explanation of how to develop contracts in the conditions of an asynchronous blockchain.
You can do this in asynchronous style more simply (without callback and await).
I changed the code of your contracts:
pragma ton-solidity ^0.51.0;
interface IPing {
function onGet(uint b) external;
}
contract Pong {
function get(uint b) external {
IPing(msg.sender).onGet(b + 1);
}
}
pragma ton-solidity ^0.51.0;
interface IPong {
function get(uint b) external;
}
contract Ping {
uint public tmp;
function run(address pong, uint a) public {
IPong(pong).get(a);
tvm.accept();
tmp = a + tmp;
}
function onGet(uint b) external {
tvm.accept();
tmp = b + tmp;
}
}
Now call a little changed this Run.bash
#!/usr/bin/env bash
set -o errexit
tondev se reset
tondev network default se
rm -fr *.abi.json *.tvc
# Deploy Pong Contract
tondev sol compile Pong.sol
tondev contract deploy Pong --value 1000000000
pongAddress=$(tondev contract info Pong | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pongAddress"
# Deploy Ping Contract
tondev sol compile Ping.sol
tondev contract deploy Ping --value 1000000000
pingAddress=$(tondev contract info Ping | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pingAddress"
# Run
tondev contract run Ping run --input "pong:$pongAddress,a:1" &> /dev/null
tondev contract run-local Ping tmp | grep tmp
# tmp:0x0000000000000000000000000000000000000000000000000000000000000003
tondev contract run Ping run --input "pong:$pongAddress,a:1" &> /dev/null
tondev contract run-local Ping tmp | grep tmp
# tmp:0x0000000000000000000000000000000000000000000000000000000000000006
A bit of my philosophy, why it is better:
the contracts must works without waiting. So callbacks and awaits, it is not good.
Callbacks are very useful in debots, and it can take place there because debots running on your device. But it is another story…

How to select fields in a non-uniform file using different delimiters?

I'm having trouble writing a one-liner that will select out the numbers between the parentheses, wrap it in double quotes, insert a comma, then select all the text after "USER_RULE: " up to the next double quote.
Here is a small sample of my file:
#213(1547485175) pass in quick on igb0 inet proto udp from <MGMT_HOSTS:1> to <UNRAID_IP:1> port = http keep state label "USER_RULE: Local Mgmt Services"
#174(1548683908) block return in quick on ALL_LAN inet proto tcp from <LOCAL_NETWORKS:7> to <LOCAL_BROADCAST:8> label "USER_RULE: Local Broadcast Noise"
#157(1547555119) block return in log quick on ALL_LAN inet from ! <NO_PFBLOCKER:1> to <pfB_BAD_IP_v4:55258> label "USER_RULE: pfb_Bad_IP (outbound)"
#137(1547478025) pass in quick on igb0 inet proto tcp from 192.168.1.0/24 to (self:13) port = ssh flags S/SA keep state label "USER_RULE: Anti-Lockout"
#386(1548774638) pass in quick on igb0.10 route-to (ovpnc1 10.20.48.141) inet proto udp from <MOBILE_DEVICES:5> to ! <PRIVATE_NETWORKS:3> port = https keep state label "USER_RULE: Policy Route" tag NO_WAN_EGRESS
Here's my expected output:
"1547485175",Local Mgmt Services
"1548683908",Local Broadcast Noise
"1547555119",pfb_Bad_IP (outbound)
"1547478025",Anti-Lockout
"1548774638",Policy Route
I've tried various combinations of awk, sed, and grep and I can get sort of the output I want. I just can't nail it. I'll spare you my ugly failed attempts.
$ sed 's/[^(]*(\([^)]*\).*"USER_RULE: *\([^"]*\).*/"\1",\2/' file
"1547485175",Local Mgmt Services
"1548683908",Local Broadcast Noise
"1547555119",pfb_Bad_IP (outbound)
"1547478025",Anti-Lockout
"1548774638",Policy Route
Could you please try following(It is always recommended to add your effort in your post so kindly do so as we all are here to learn).
awk '
BEGIN{
s1="\""
OFS=","
}
match($0,/\([^\)]*/){
val=substr($0,RSTART+1,RLENGTH-1)
}
match($0,/USER_RULE[^"]*/){
print s1 val s1,substr($0,RSTART+11,RLENGTH-11)
}' Input_file
Output will be as follows.
"1547485175",Local Mgmt Services
"1548683908",Local Broadcast Noise
"1547555119",pfb_Bad_IP (outbound)
"1547478025",Anti-Lockout
"1548774638",Policy Route
# File a.awk:
BEGIN { q = "\"" }
{ idx = index($0, "USER_RULE:")
rule = substr($0, idx + 11)
idx = index(rule, q) - 1
print q substr($0, 6, 10) q "," substr(rule, 1, idx)
}
Run:
$ awk -f a.awk file
"1547485175",Local Mgmt Services
"1548683908",Local Broadcast Noise
"1547555119",pfb_Bad_IP (outbound)
"1547478025",Anti-Lockout
"1548774638",Policy Route

Error during nfq_open()

I'm trying to set up an nfq listener based on This bit of code:
main (int argc, char **argv)
{
struct nfq_handle *h;
struct nfq_q_handle *qh;
struct nfnl_handle *nh;
int fd;
int rv;
char buf[4096] __attribute__ ((aligned));
printf ("opening library handle\n");
h = nfq_open ();
if (!h)
{
fprintf (stderr, "error during nfq_open()\n");
exit (1);
}
...
I have the following iptables rule set:
NFQUEUE udp -- 0.0.0.0/0 192.168.50.0/24 udp dpt:10000 NFQUEUE num 5061
But running the program always gives: Error during nfq_open()
Is there something incorrect with my IPtables rule? I used the following command:
/sbin/iptables -A FORWARD --protocol udp --dport 10000 -j NFQUEUE --queue-num 5061 -d 192.168.50.0/24
Thanks.
Please add "-t" switch with the table name "nat|filter|mangle" in which you want to add rule.
This won't be an issue with the iptables command at all. I would guess that you are not running the program as root, which is required to use NFQUEUE.

Getting CPU info from Process ID

If anyone could please help me out, that would be great :)
This seems to be a tough one. Starting from the process ID, I need to be able to grab:
How much CPU the process is taking up in %
How long the process has been using the CPU
This needs to be written in Cocoa/ Objective-C or C. It also needs to work on Tiger through Snow Leopard.
Thanks!
A crude way would be to spawn of a popen command and grab some output from ps.
Ie like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void get_process_info(int pid) {
char ps_cmd[256];
sprintf(ps_cmd, "ps -O %%cpu -p %d", pid); // see man page for ps
FILE *fp = popen(ps_cmd, "r");
if (fp) {
char line[4096];
while (line == fgets(line, 4096, fp)) {
if (atoi(line) == pid) {
char dummy[256];
char cpu[256];
char time[256];
// PID %CPU TT STAT TIME COMMAND
// 32324 0,0 s001 S+ 0:00.00 bc
sscanf(line, "%s %s %s %s %s", dummy, cpu, dummy, dummy, time);
printf("%s %s\n", cpu, time); // you will need to parse these strings
pclose(fp);
return;
}
}
pclose(fp);
}
}
int main() {
get_process_info(32324);
return 0;
}

Calling fgets() on popen() of 'ssh' is flushing the beginning of stdin of the calling process (ptty issue)

I have now whittled this down to a minimal test case. Thus far I have been able to determine that this is an issue related to pseudo-terminals which come about with the pipe of ssh. Adding the '-t -t' to the ssh call improved things, in that now, it takes a second call to fgets() to cause the issue. I suspect that the stderr output of the ssh command somehow works into the issue, for now I have redirected stderr to stdout in the ssh code to execute. I do wonder if the "tcgetattr: Invalid argument" error is part of the problem, but am not sure how to get rid of that. It seems to come from the -t -t being present. I believe the -t -t is moving in the right direction, but I have to set up the pseudo terminal for stderr somehow and perhaps the test will work properly?
The Makefile:
test:
gcc -g -DBUILD_MACHINE='"$(shell hostname)"' -c -o test.o test.c
gcc -g -o test test.o
.PHONY: clean
clean:
rm -rf test.o test
The test.c source file:
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{
const unsigned int bufSize = 32;
char buf1[bufSize];
char buf2[bufSize];
int ssh = argv[1][0] == 'y';
const char *cmd = ssh ? "ssh -t -t " BUILD_MACHINE " \"ls\" 2>&1" : "ls";
FILE *fPtr = popen(cmd, "r");
if (fPtr == NULL) {
fprintf(stderr,"Unable to spawn command.\n");
perror("popen(3)");
exit(1);
}
printf("Command: %s\n", cmd);
if (feof(fPtr) == 0 && fgets(buf2, bufSize, fPtr) != NULL) {
printf("First result: %s\n", buf2);
if (feof(fPtr) == 0 && fgets(buf2, bufSize, fPtr) != NULL) {
printf("Second result: %s\n", buf2);
int nRead = read(fileno(stdin), buf1, bufSize);
if (nRead == 0) {
printf("???? popen() of ssh consumed the beginning of stdin ????\n");
} else if (nRead > 0) {
if (strncmp("The quick brown fox jumped", buf1, 26) != 0) {
printf("??? Failed ???\n");
} else {
printf("!!!!!!! Without ssh popen() did not consume stdin !!!!!!!\n");
}
}
}
}
}
This shows it running the passing way:
> echo "The quick brown fox jumped" | ./test n
Command: ls
First result: ARCH.linux_26_i86
Second result: Makefile
!!!!!!! Without ssh popen() did not consume stdin !!!!!!!
This shows it running the failing way:
> echo "The quick brown fox jumped" | ./test y
Command: ssh -t -t hostname "ls" 2>&1
First result: tcgetattr: Invalid argument
Second result: %backup%~ gmon.out
???? popen() of ssh consumed the beginning of stdin ????
Okay, I have got this working finally. The secret was to supply /dev/null as the input to my ssh command as follows from the test case above:
const char *cmd
= ssh ? "ssh -t -t " BUILD_MACHINE " \"ls\" 2>&1 < /dev/null" : "ls";
However, while the code works correctly, I get a nasty message which apparently I can ignore for my purposes (although I'd like to make the message go away):
tcgetattr: Inappropriate ioctl for device