Is it possible to run parallel connection between Opencv Gstreamer? - multithreading

I have 4 different stream. They are waiting for each other to establish a connection. Can I do a parallel operation. Only when I send the 9003 stream. I want to connect directly with 9003 without waiting for the others.
When I try with threads, the second thread does not start before the first thread ends.
My Code:
string gst_pipe1 = "udpsrc port=9001 caps = application/x-rtp ! rtph265depay ! h265parse ! nvh265dec ! videoconvert ! appsink sync=false";
string gst_pipe2 = "udpsrc port=9002 caps = application/x-rtp ! rtph265depay ! h265parse ! nvh265dec ! videoconvert ! appsink sync=false";
string gst_pipe3 = "udpsrc port=9003 caps = application/x-rtp ! rtph265depay ! h265parse ! nvh265dec ! videoconvert ! appsink sync=false";
string gst_pipe4 = "udpsrc port=9004 caps = application/x-rtp ! rtph265depay ! h265parse ! nvh265dec ! videoconvert ! appsink sync=false";
thread get1([]() { videoCap[0] = VideoCapture(gst_pipe9001, CAP_GSTREAMER); });
thread get2([]() { videoCap[1] = VideoCapture(gst_pipe9002, CAP_GSTREAMER); });
thread get3([]() { videoCap[2] = VideoCapture(gst_pipe9003, CAP_GSTREAMER); });
thread get4([]() { videoCap[3] = VideoCapture(gst_pipe9004, CAP_GSTREAMER); });
get1.join();
get2.join();
get3.join();
get4.join();
---------------------------------problem is solved.---------------------------------
all the pipelines listen constantly. When a connection comes from anyone, it streams it.
In the future, I had to create a buffer for synchronization and I need to get all the frames when the connection comes.
, my solution c++ dll:
vector<cv::VideoCapture> videoCap(4);
string gst_pipe[] = {
"udpsrc port=9001 caps = application/x-rtp ! rtph265depay ! h265parse ! nvh265dec ! videoconvert ! appsink sync=false",
"udpsrc port=9002 caps = application/x-rtp ! rtph265depay ! h265parse ! nvh265dec ! videoconvert ! appsink sync=false",
"udpsrc port=9003 caps = application/x-rtp ! rtph265depay ! h265parse ! nvh265dec ! videoconvert ! appsink sync=false",
"udpsrc port=9004 caps = application/x-rtp ! rtph265depay ! h265parse ! nvh265dec ! videoconvert ! appsink sync=false" };
void func1() {
videoCap[0] = VideoCapture(gst_pipe[0], CAP_GSTREAMER);
colorImages[0].create(Size(rsSplitWidth, rsSplitHeight), CV_8UC3);
while (true)
{
videoCap[0].read(colorImages[0]);
}
}
void func2() {
videoCap[1] = VideoCapture(gst_pipe[1], CAP_GSTREAMER);
colorImages[1].create(Size(rsSplitWidth, rsSplitHeight), CV_8UC3);
while (true)
{
videoCap[1].read(colorImages[1]);
}
}
void func3() {
videoCap[2] = VideoCapture(gst_pipe[2], CAP_GSTREAMER);
colorImages[2].create(Size(rsSplitWidth, rsSplitHeight), CV_8UC3);
while (true)
{
videoCap[2].read(colorImages[2]);
}
}
void func4() {
videoCap[3] = VideoCapture(gst_pipe[3], CAP_GSTREAMER);
colorImages[3].create(Size(rsSplitWidth, rsSplitHeight), CV_8UC3);
while (true)
{
videoCap[3].read(colorImages[3]);
}
}
void CaptureInitialize()
{
std::thread td1(func1);
std::thread td2(func2);
std::thread td3(func3);
std::thread td4(func4);
td1.join();
td2.join();
td3.join();
td4.join();
}
unsigned char* WrapperSingleCameras(int hCameraIndex)
{
return colorImages[hCameraIndex].ptr();
}
GUI c#:
private void startButton_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(DLLWrapper.CaptureInitialize);
thread1.Start();
Thread thread2 = new Thread(SplitBitmapInitialize);
thread2.Start();
}
unsafe private void SplitBitmapInitialize()
{
pt = new byte*[4];
BitmapSingleImage = new Bitmap[4];
while (true)
{
//DLLWrapper.mainThread();
for (int i = 0; i < 4; i++)
{
//DLLWrapper.WrapperGetFrame(i);
pt[i] = DLLWrapper.WrapperSingleCameras(i);
BitmapSingleImage[i] = new Bitmap(rsSplitWidth, rsSplitHeight, 3 * rsSplitWidth, System.Drawing.Imaging.PixelFormat.Format24bppRgb, (IntPtr)pt[i]);
//BitmapSingleImage[i] = new Bitmap(rsSplitWidth, rsSplitHeight, rsSplitWidth, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale, (IntPtr)pt[i]);
if (i == 0)
{
videoCamTopLeft.Image = BitmapSingleImage[i];
videoCamTopLeft.Refresh();
}
else if (i == 1)
{
videoCamTopRight.Image = BitmapSingleImage[i];
videoCamTopRight.Refresh();
}
else if (i == 2)
{
videoCamBottomLeft.Image = BitmapSingleImage[i];
videoCamBottomLeft.Refresh();
}
else if (i == 3)
{
videoCamBottomRight.Image = BitmapSingleImage[i];
videoCamBottomRight.Refresh();
}
}
}

Related

When app goes background the thread pause

I need your help.
I have a chronometer app very simply that show the time running.
I created a thread that count the time and update the UI.
When the app is in first plane, everything is fine.
When I press back buttom the app goes background but the Thread is paused for the system.
When I return to the App, the chronometer began to run again.
How I can do for maintenance the time running on background?
I will appreciate your hep.
Thanks,
Rodrigo.
private void cronometro(){
new Thread(new Runnable(){
#Override
public void run() {
while (true) {
if (isOn) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
mensaje_log = "Se produjo un error";
Log.d("Miapp",mensaje_log);
Escribirlog.escribir_eventos(mensaje_log);
mensaje_log = e.getMessage();
Escribirlog.escribir_eventos(mensaje_log);
Thread.currentThread().interrupt();
}
mili++;
if (mili == 999) {
seg++;
mili = 0;
saltos++;
if (saltos == 10) {
//escribe log cada 10 segundos
mensaje_log = "Corriendo...";
Log.d("Miapp",mensaje_log);
Escribirlog.escribir_eventos(mensaje_log);
saltos = 0;
}
}
if (seg == 59) {
minutos++;
seg = 0;
}
h.post(new Runnable() {
#Override
public void run() {
String m = "", s = "", mi = "";
if (mili < 10) {
m = "00" + mili;
} else if (mili < 100) {
m = "0" + mili;
} else {
m = "" + mili;
}
if (seg < 10) {
s = "0" + seg;
} else {
s = "" + seg;
}
if (minutos < 10) {
mi = "0" + minutos;
} else {
mi = "" + minutos;
}
m = m.substring(0,2); //toma los 2 primeros numeros de milisegundos
crono.setText(mi + ":" + s + ":" + m);
}
});
}
}
}
}).start();
}
In order to keep a task running in the background in flutter you will need to use a package, a one you can go with is https://pub.dev/packages/background_fetch, the way you going to use it like this:
void backgroundFetchHeadlessTask(HeadlessTask task) async {
String taskId = task.taskId;
bool isTimeout = task.timeout;
if (isTimeout) {
// This task has exceeded its allowed running-time.
// You must stop what you're doing and immediately .finish(taskId)
print("[BackgroundFetch] Headless task timed-out: $taskId");
BackgroundFetch.finish(taskId);
return;
}
print('[BackgroundFetch] Headless event received.');
// Do your work here...
BackgroundFetch.finish(taskId);
}
And then you will have to call it inside your main
void main() {
runApp(new MyApp());
BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
}
And finally call it when you need it to start fetching this way:
BackgroundFetch.start().then((int status) {
print('[BackgroundFetch] start success: $status');
}).catchError((e) {
print('[BackgroundFetch] start FAILURE: $e');
});
} else {
BackgroundFetch.stop().then((int status) {
print('[BackgroundFetch] stop success: $status');
});

Timer in command-line application

Trying to create a simple command-line application in Haxe which has a ticking Timer, but it does not seem to work out; the Timer never actually starts 'ticking'.
package;
import haxe.Timer;
class TimerCallback {
private static inline var CHAR_SPACE : Int = 32;
public static function main() : Void {
var myME = new TimerTicker();
while (Sys.getChar(false) != CHAR_SPACE) {
//loop until [space] detected, do nothing here
}
}
}
class TimerTicker {
private var myTimer : Timer = null;
public function new() {
myTimer = new Timer(20);
myTimer.run = timer_OnTick;
}
private function timer_OnTick() : Void {
Sys.println ("foobar");
}
/* destructor?! */
}
And this is the build command:
>haxe.exe -lib nme -main TimerCallback -cpp .\bin
If I am not adding -lib nme, the code does not compile (based on API doc it's OK as Timer is not supported for cpp, so only static functions are available)
If I am adding this, however, the code is compiled -as nme supports cpp Timers-, and the exe is created (win), but timer_OnTick() is never called. So exe starts, nothing happens, one press SPACE and app. quits.Additional info:
- The imported Timer.hx file is this one: haxe\lib\nme\5,1,8\haxe. And if I am right, this should be OK & working.
- Using haxe 3.1.3, nme 5.1.8, hxcpp 3.1.39 (and haxelib 3.1.0-rc.4 if matters)Any help would be much appreciated.
Okay, I've got help from the Haxe Community (mailing list). Here are the solutions if anyone happen to need them:PSEUDO CODE (not tested)
class RunLoop {
static var queue = new Deque<Void->Void>();
static var keepAlives:Int; = 1;
static public function release()
enque(function () keepAlives--);
static public function retain()
enque(function () keepAlives++);
static public function enque(task:Void->Void)
queue.add(task);
static function main() {
enque(entryPoint);
release();
}
static function entryPoint() {
//code goes here
}
static function run()
while (keepAlives:Int > 0)
queue.pop()();
}
//Now you can go an implement a timer like so:
class Timer {
var active:Bool = true;
public function new(msecs:Int) {
RunLoop.retain();
Thread.create(function () while(active) {
Sys.sleep(msecs / 1000);
if (active)
RunLoop.enque(this.run);
});
}
public dynamic function run() {}
public function stop() {
active = false;
RunLoop.release();
}
}
//And a helper for blocking code:
class Task {
var task:Void->T;
var onDone:T->Void;
public function new(task:Void->T, onDone:T->Void) {
RunLoop.retain();
Thread.create(function () {
var result = task();
RunLoop.enque(onDone.bind(result));
});
}
}
//So then the code you want would look roughly like this:
static function entryPoint() {
var timer = new Timer();
timer.run = function () trace('foobar');
function waitForSpace() {
while (Sys.getChar(false) != CHAR_SPACE) {
//loop until [space] detected, do nothing here
}
return true;
}
new Task(
waitForSpace,
function (_) timer.stop() //stop the timer so that the run loop can exit
);
} (solution provided by back2dos)
/*
1. Neko : works
2. C++: works, However, incrementing count in the if statement instead ( if( count++ == 0 ) { ... ) fails to increment count! Fixed on Git?
3. Flash : works
4. Java : fails using Haxe 3.1.3
*/
### build.hxml ###
-main Main
-swf main.swf
-swf-version 12
--next
-main Main
-neko main.n
--next
-main Main
-cpp cpp
-cmd cp cpp/Main ./main
--next
-main Main
-java java
-cmd cp java/Main.jar ./main-jar
### Main.hx ###
class Main {
public static function main() {
#if sys
var count = 0;
while( true ) {
if( count == 0 ) {
Timer.delay(function() trace("doThing1"), 3000);
Timer.delay(function() trace("doThing2"), 1000);
count++;
}
}
#else
Timer.delay(function() trace("doThing1"), 3000);
Timer.delay(function() trace("doThing2"), 1000);
#end
}
}
### Timer.hx ###
#if neko
import neko.vm.Deque;
import neko.vm.Thread;
import neko.vm.Mutex;
import neko.vm.Lock;
#elseif cpp
import cpp.vm.Deque;
import cpp.vm.Thread;
import cpp.vm.Mutex;
import cpp.vm.Lock;
#elseif java
import java.vm.Deque;
import java.vm.Thread;
import java.vm.Mutex;
import java.vm.Lock;
#end
class Timer {
#if sys
static var timerThread : TimerThread;
#else
static var timers : Array;
#end
static function __init__() {
#if sys
timerThread = new TimerThread();
#else
timers = [];
#end
}
public static function stop() {
#if sys
timerThread.quit();
#else
for( t in timers )
t.stop();
#end
}
public static function delay( func : Void -> Void, delayMillis : Int ) {
#if sys
timerThread.addTimer(delayMillis/1000, func);
#else
timers.push( haxe.Timer.delay(func, delayMillis) );
#end
}
}
#if sys
typedef TTimerData = {
time : Float,
func : Void -> Void
}
class TimerThread {
var mutex : Mutex;
var queueLock : Lock;
var queue : Array;
var running : Bool;
public function new() {
queue = [];
queueLock = new Lock();
mutex = new Mutex();
running = true;
Thread.create( mainLoop );
}
public function addTimer( delaySec : Float, cb : Void -> Void ) {
mutex.acquire();
var time = haxe.Timer.stamp() + delaySec;
var index = 0;
while( index < queue.length && time >= queue[index].time )
index++;
queue.insert(index, { time : time, func : cb });
mutex.release();
queueLock.release();
}
public function quit( ?cb : Void -> Void ) {
var me = this;
addTimer( 0, function() {
me.running = false;
if( cb != null )
cb();
} );
}
function mainLoop() {
while( running ) {
var wake : Null = null;
var now = haxe.Timer.stamp();
var ready = new Array();
mutex.acquire();
while( queue.length > 0 )
if( queue[0].time <= now )
ready.push(queue.shift());
else {
wake = queue[0].time;
break;
}
mutex.release();
for( d in ready ) {
d.func();
if( !running )
break;
}
if( !running )
break;
if( wake == null )
queueLock.wait();
else {
var delay = wake - haxe.Timer.stamp();
if( delay > 0 )
queueLock.wait(delay);
}
}
}
}
#end
(Solution provided by Zjnue, modified code of Hugh)

Why can't streaming connect to the Java socket client?

I am studying Spark streaming to process real time data, and I built the example wordCount of spark streaming, and I can run the example after:
/bin/run-example org.apache.spark.streaming.examples.JavaNetworkWordCount local[2] localhost 9999
And if I run nc -L -p 9999 in another terminal, then I can type letters in this terminal, and the example can receive the letters and give the right result.
But I developed a Java socket client to send content to 9999 port - why can't the example receive it? I think the example just monitor the 9999 port, and receive anything from the port.
Here is the Java code:
File file = new File("D:\\OutputJson.dat");
long l = file.length();
socket = new Socket();
boolean connected = false;
while (!connected) {
//not stop until send successful
try {
socket.connect(new InetSocketAddress("localhost", 9999));
connected = true;
System.out.println("connected success!");
} catch (Exception e) {
e.printStackTrace();
System.out.println("connected failed!");
Thread.sleep(5000);
}
}
dos = new DataOutputStream(socket.getOutputStream());
fis = new FileInputStream(file);
sendBytes = new byte[1024];
while ((length = fis.read(sendBytes, 0, sendBytes.length)) > 0) {
sumL += length;
System.out.println("sent:" + ((sumL / l) * 100) + "%");
dos.write(sendBytes, 0, length);
dos.flush();
}
if (sumL == l) {
bool = true;
}
This Java function is always returning the following error:
java.net.SocketException: Socket closed
I have developed another Java class to receive the data from this sending socket, and it works fine, why the can't spark receive with this one?
From memory I think I used a ServerSocket. The code was something like:
public void sendMsg(String msg) throws IOException {
ServerSocket serverSocket = null;
Socket clientSocket = null;
try {
serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
out.write(msg);
out.flush();
out.close();
} finally {
try {
clientSocket.close();
serverSocket.close();
} finally {
clientSocket = null;
serverSocket = null;
}
}
}

Limiting thread numbers to run at a time

Consider that I have around 100 subroutines which I have to run using threads.How can I limit all threads so that only 10 threads will run at a time? Can u give me a sample code.
Here is the sample code where i need to implement it
use threads;
my ($thr1) = threads->create(\&sub1,$parameter);
my ($thr2) = threads->create(\&sub2,$parameter);
...
my ($thr100) = threads->create(\&sub100,$parameter);
my $result;
for my $t(#threads){
#print "$t\n";
(my #getit)= $t->join();
my $tmp = join '', #getit;
$result .= $tmp;
}
print "$result\n";
Or Do you have any other method for it. Each subroutine will do different task.
use threads;
use Thread::Queue 3.01 qw( );
my $NUM_WORKERS = 10;
sub worker {
my ($job) = #_;
my ($sub_name, #args) = #$job;
my $sub_ref = \&$sub_name;
$sub_ref->(#args);
}
{
my $q = Thread::Queue->new();
my #workers;
for (1..$NUM_WORKERS) {
push #workers, async {
while (my $job = $q->dequeue()) {
worker($job);
}
};
}
$q->enqueue($_)
for
[ sub1 => ( #args ) ],
[ sub2 => ( #args ) ];
$q->end();
$_->join() for #workers;
}

Groovy Tcp client/server sending maps

I created a basic tcp client and server in groovy and I'm wanting to send maps from the server to the client, I'm wondering if I'm able send maps across and still being able to access the values.
//TCP Server
def book1 = [Title of Book: "Groovy Recipes", Author: "Scott Davis", Number of Pages: "241"]
server = new ServerSocket(2000)
println("Waiting for connection")
while(true) {
server.accept() { socket ->
socket.withStreams { input, output ->
w = new BufferedWriter(new OutputStreamWriter(output))
String message = "Connection was successful"
r = new BufferedReader(new InputStreamReader(input))
while(true) {
if(message != null) {
w.writeLine(message)
w.flush()
message = null
}
String a = r.readLine()
if(a=="book1") {
message = book1
} else {
message = "$a command unknown."
sendMessage(message)
println message
message = null
}
}
}
}
}
def sendMessage(String msg) {
try {
w.writeLine(msg)
w.flush();
} catch(IOException ioException) {
ioException.printStackTrace();
}
}
Here is my Client (where I'm wanting to receive the map and get the values)
//TCP Client
def grabBookInfo {
queryData()
}
public void queryData() {
def hosts = ["localhost"]
for(int aHost = 0; aHost < hosts.size; aHost++) {
bookClient(hosts[aHost]);
}
}
public void bookClient() {
def commands = ["book1"]
def answers = [commands.size]
def requestSocket = new Socket(host, 2000)
r = new BufferedReader(new InputStreamReader(requestSocket.getInputStream()));
w = new BufferedWriter(new OutputStreamWriter(requestSocket.getOutputStream()));
String message = "Connection was successful"
message = r.readLine()
println("Server>" + message)
for(int n = 0; n < commands.size; n++) {
sendMessage(commands[n]);
answers[n] = r.readLine()
}
//get map values here
//answers[0] = Book
//println Book.['Title of Book']
//println Book.['Author']
//println Book.['Number of Pages']
w.flush()
w.close()
}
public void sendMessage(msg) {
w.write(msg+"\r\n");
w.flush();
System.out.println("client>" + msg);
}
}
Am I on the right track?
In the server, use ObjectOutputStream.
In the client use ObjectInputStream.
Server:
private static final HashMap<String, Integer> TEST_MAP;
static {
TEST_MAP = new HashMap<String, Integer>();
TEST_MAP.put("one", 1);
TEST_MAP.put("two", 2);
}
...
ServerSocket ss = new ServerSocket(port);
Socket socket = ss.accept();
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(TEST_MAP);
out.close();
Client:
Socket socket = new Socket(HOST, PORT);
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Object o = in.readObject();
assert o instanceof HashMap<?, ?>;
#SuppressWarnings("unchecked")
HashMap<String, Integer> m = (HashMap<String, Integer>)o;
assertTrue(m.get("one") == 1);
assertTrue(m.get("two") == 2);
in.close();
socket.close();
Serialize the maps, example
http://www.java2s.com/Tutorial/Java/0140__Collections/SerializingHashMaps.htm

Resources