Gstreamer 1.0 - Creating custom message/event/signal - gstreamer

I am writing a custom plugin for gstreamer 1.0 in C.
This plugin perform some processing on frames and should send an event to the application whenever some conditions are met.
It should not block the pipeline not interfere with it, just a signal so the application can trigger an action unrelated to the pipeline on the side.
The processing is working well but ... i don't know what to do next.
There is a lot of already existing message like EOS or seek but how do i create my own?
The message should contain custom data and therefore i must create one myself that i could send.
Either by sending events or signal i could not find any examples/documentations/explainations on how to handle custom events from a plugin.
I don't even have a sample code to start with.
Any insight would be appreciated.

Take a look at the fpsdisplaysink element:
https://github.com/GStreamer/gst-plugins-bad/blob/master/gst/debugutils/fpsdisplaysink.c
This one emits signals which the application can connect to. Most interesting probably the signal creation:
g_signal_new ("fps-measurements", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 3, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
and the periodically triggering of said signal:
g_signal_emit (G_OBJECT (self),
fpsdisplaysink_signals[SIGNAL_FPS_MEASUREMENTS], 0, rr, dr,
average_fps);
Detailed information should be found at the GLib signals documentation:
https://developer.gnome.org/gobject/stable/gobject-Signals.html
#
Alternatively you create your own GstMessage and post it on the bus. See the GstMessage documentation:
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html
GstMessage *gst_message_new_application (GstObject *src,
GstStructure *structure);
You can then wrap your data inside the GstStructure. And then post the message to the bus with gst_bus_post().

Thank you Florian for your insight which helped me a lot.
I ended up using gst_message_new and gst_post_bus.
For those who might be interested here is the code in python where i implemented a run loop.
def connect(bus, name):
def _connect(f):
bus.connect(name, f)
return f
return _connect
....
bus = self.pipeline.get_bus()
bus.add_signal_watch()
ret = self.pipeline.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
logger.error("ERROR: Unable to set the pipeline to the playing state")
loop = GObject.MainLoop()
print()
#connect(bus, "message::"+Gst.MessageType.get_name(Gst.MessageType.ERROR))
def on_error(bus, message):
err, dbg = message.parse_error()
print("ERROR:", message.src.get_name().encode('utf-8'), ":", err.message.encode('utf-8'))
if dbg:
print("debugging info:", dbg)
loop.quit()
#connect(bus, "message::"+Gst.MessageType.get_name(Gst.MessageType.EOS))
def on_eos(bus, message):
logger.info("End-Of-Stream reached")
loop.quit()
.... other events
try:
loop.run()
except KeyboardInterrupt:
pass
print("START : Pipeline has stopped")
self.pipeline.set_state(Gst.State.NULL)

Related

Is there any way to close Eventhubconsumerclient.receive if it has been a while without any messages?

I just implemented eventhub with version 5, which has been changed a bit from previous version.
current running code is following:
consumer_client = EventHubConsumerClient.from_connection_string(conn_str=CONNECTION_STR,
consumer_group='fconsumer',
eventhub_name=EVENTHUB_NAME)
consumer_client.receive(on_event=on_event,
partition_id = "0",
track_last_enqueued_event_properties=False,
starting_position="#latest")
By adding an argument for the time duration (or keep_alive ag from prev version), I would make it stop receiving messages and close it after a certain amount of time. Is this possible?
consumer_client.receive(...) will be a blocking call and it won't return on its own. You need to create a thread for consuming events and in the main thread you can get to decide when to close the consumer client. Sample code snippet as below...
thread = threading.Thread(
target=consumer_client.receive,
kwargs={
"on_event": on_event,
"on_partition_initialize": on_partition_initialize,
"on_partition_close": on_partition_close,
"on_error": on_error,
"starting_position": "-1", # "-1" is from the beginning of the partition.
}
)
thread.daemon = True
thread.start()
time.sleep(RECEIVE_DURATION)
consumer_client.close()
thread.join()

Send Image or Document with Inline Menu

I am coding an Python Telegram Bot with python-telegram-bot. I created a custom inline menu.
I want that the User could press a button and will get an picture. The send_photo function needs an instance of bot an update.
But I don't know how to pass that on to the CallBackQuery handler.
Does anyone have an idea how to solve it?
The send photo function:
def gvu(bot, update):
bot.send_photo(update.message.chat_id, photo=open('botpic/gvu.jpg', 'rb'))
The Handler in Main Routine:
updater.dispatcher.add_handler(CallbackQueryHandler(pattern="1", callback=gvu))
return self.callback(dispatcher.bot, update, **optional_args)
The error:
TypeError: callback_handler() got an unexpected keyword argument 'chat_data'
This works for me:
buttonsMenu = [
[telegram.InlineKeyboardButton("UP", callback_data="UpVote")],
[telegram.InlineKeyboardButton("DOWN", callback_data="DownVote")],
]
keyboard_markup = telegram.InlineKeyboardMarkup(buttonsMenu)
context.bot.sendPhoto(chat_id=update.message.chat.id, photo=open('./imgpath.jpg'), 'rb'),caption='messageText', reply_markup=keyboard_markup)
This will send an image, with text and 2 butttons below the text msg.
Now for the callback query, i did this in main():
# Callbacks for the msg buttons
dp.add_handler(CallbackQueryHandler(vote, pattern="UpVote"))
dp.add_handler(CallbackQueryHandler(vote, pattern="DownVote"))
Where vote , is a def that runs the code i want for that callback.
hope it makes sense.
Read into documentation here:
https://core.telegram.org/bots/api#inlinequery
https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinekeyboard.py

Sending message on Actor startup with real (non-temp) sender ActorRef?

I'd like an actor to send a message on startup and receive a reply later.
Sending the message from within preStart results in a temporary sender reference (because the Actor hasn't yet started?). So the reply will likely be a dead letter.
Any tips would be appreciated. Apologies if my premise is mis-informed - I am new to Akka.
One approach is to send a message to self in preStart:
class MyActor extends Actor {
def preStart(): Unit = {
self ! CallService
}
def receive = {
case CallService =>
(service ? ServiceRequest).mapTo[ServiceResponse].pipeTo(self)
case ServiceResponse =>
// do something with the response
}
}
As described in this answer, if you want the actor to send the message before it processes all other messages, then you could stash the other messages:
class MyActor extends Actor with Stash {
def preStart(): Unit = {
self ! CallService
}
def uninitialized: Receive = {
case CallService =>
(service ? ServiceRequest).mapTo[ServiceResponse].pipeTo(self)
unstashAll()
context.become(initialized)
case _ => stash() // if we get a message other than CallService, stash it
}
def initialized: Receive = {
case ServiceResponse =>
// do something with the response from the service
case ...
}
def receive = uninitialized
}
Your premise is indeed not correct: when preStart runs the actor is already fully started, it's self reference never is a temporary one. Without code it is impossible to help you further, though.
The sender should always be considered "temporary" -- cf. this blog post, for example:
The rule is simply never close over the sender method in a block of
code that is potentially executed in another thread, such as a
scheduled task or a Future. The trick is to capture the current sender
in a val, as illustrated below...
-- Closing Over An Akka Actor Sender In The Receive
Make a copy of sender, and then later when you are ready to reply, reply to that copy of the actorRef and not to "sender".

how to avoid sending messages to actors not created yet?

I hope it is ok to ask this. I am using akka and have two actors, where one is initiated/created fast and the other much slower. The rapidly created one asks the other for something (ask-pattern), and the message is sent to dead letters since the other is not initiated yet. What is the preferred way of making an actor waiting with sending it´s message? I am not so eager to make an actor sleep or something without knowing there is no other way.
I would use the functionality become()/unbecome() Akka provides for Actors. I am assuming in the following code that the slowActor gets created by the fastActor. The trick here is that the fastActor will have two behaviors: one for when the slowActor is getting initiated and the other for when it's ready to do some work. When slowActor is ready, it will send a message to the fastActor to advertise that is able to receive messages. fastActor will be watching slowActor and if it gets terminated, it will change its behavior again. What to do next would be up to your solution.
Here is a mock code as a guide (I have not compiled the code and it might contain some errors):
case object Ready
case object DoWork
case object WorkDone
class FastActor extends Actor with ActorLogging {
val slowActor = context.actorOf(SlowActor.props)
context.watch(slowActor)
def receive = slowActorNotReadyBehavior
def slowActorNotReadyBehavior = {
case DoWork => log.warning("Slow actor in not ready, I am sorry...")
case Ready => context.become(slowActorReadyBehavior)
}
def slowActorReadyBehavior = {
case DoWork => (slowActor ? DoWork).pipeTo(self)
case Terminated(ref) =>
log.error("Slow actor terminated")
context.unbecome()
//... do something with slowActor
}
}
class SlowActor extends Actor {
override def preStart = {
context.parent ! Ready
}
def receive = {
case DoWork =>
//do something
sender ! WorkDone
}
}

UWP/WinRT: How to perform a UI task upon completion of an asynchronous operation in a model?

I'm following the MVVM pattern, and have a model called a DocumentStore. The class has a method as follows:
void DocumentStore::Open_Document(StorageFile^ file) {
create_task(FileIO::ReadTextAsync(file))
.then([this, file](String^ fileContents)
{
// Take the fileContents and add them to internal data structure
});
}
My ViewModel is popping up a FileOpenPicker to get a file that it then feed as the argument into Open_Document:
create_task(picker->PickSingleFileAsync())
.then([this](StorageFile^ file)
{
m_DocStore->Open_Document(file);
// Target location to do something
}
);
I'd like to be able to perform an action after the task inside of Open_Document has completed, i.e. after the fileContents have been processed.
Is there a way for my Model to notify any interested listeners that a task is complete?
Or should my Model's Open_Document method actually be itself asynchronous? However, I need to process the data structure inside the task, and wouldn't that cause my method to be running inside a different thread context?
I'm working in C++/CX but will take any help I can get.
If I understand correctly, the process will be as following.
Open the file -> Read the content -> process the content -> do STH else.
You can push the async operation to the task chain and create a new async operation by using create_async method.
Here is the code for your reference:
create_task(StorageFile::GetFileFromApplicationUriAsync(ref new Windows::Foundation::Uri("ms-appx:///Assets/XMLFile.xml")))
.then([](StorageFile^ file) {
WriteLine("Read the file");
return FileIO::ReadTextAsync(file);
}).then([](task<String^> task) {
String ^ text = task.get();
WriteLine("Content: " + text);
return create_async([text]() {
WriteLine("Process the text: " + text);
});
}).then([](task<void> task) {
task.get();
WriteLine("Do STH else");
});
I'm posting what I ended up going with, but I accepted Jeffrey Chen's answer since it helped me get there.
My Model now has an Event DocOpened. This is fired upon completion of Open_Document. I subscribed my ViewModel to this Event with a handler that is capable of performing tasks whenever that Event is fired.