I am working on a project in which multiple same pipelines are started. We would like to do it in OOP way.
We are currently running into trouble that we have to make the callback functions static in the class because gstreamer libraries are pointers to functions. For example:
gst_bus_add_watch(bus, GstBusFunc(busCall), data);
where busCall has to be defined in class as followed:
static gboolean busCall(GstBus *bus, GstMessage *message, gpointer *data);
We are worried to have this static callback function shared by multiple object of pipelines.
Has anyone tried this before? Any good suggestions of multiple pipeline implementation?
Related
I ran into a problem I don't understand in my c++ android ndk code. When using the camera there are a number of callbacks you give the camera2 api such as these defined in a ACameraCaptureSession_captureCallbacks structure. Today I was trying to put all my camera code into a class, but when it came time to assign the callback functions I couldn't figure out how to do it. Right now I still have the callback functions as just external functions outside of the class.
So for the class:
ACameraCaptureSession_captureCallbacks captureCallbacks;
DualCamera::DualCamera(){
captureCallbacks.context = this;
captureCallbacks.onCaptureCompleted = onCaptureCompleted;
}
Then for the function:
void onCaptureCompleted (
void* context, ACameraCaptureSession* session,
ACaptureRequest* request, const ACameraMetadata* result){
}
Defined like this it works fine, but if I try to bring onCaptureCompleted inside my class I can't figure out how to assign it to captureCallBacks.onCaptureCompleted. I tried this.onCaptureCompleted, &DualCamera::onCaptureCompleted, casting to void * and a few others but I'm stuck. What's the right way to do this?
Thank you
I've been trying to get a persistent object from a thread for hours.
I want to write a shared library in C++ that starts a persistent loop in a function.
In the following code snippets there is a class called Process. Process initializes a TCP/IP interface to read and write data from a Simulink model.
This is only for declaration and should not be important for this problem, but now you know what I talk about when mentioning the processes.
main.cpp
I know, it looks kinda ugly/unprofessional, but I'm fairly new to C++..
// frustrated attempt to make everything persistent
static vector<std::thread> processThreads;
static ProcessHandle processHandle;
static vector<std::promise<Process>> promiseProcess;
static vector<std::future<Process>> futureProcess;
EXPORT int initializeProcessLoop(const char *host, int port)
{
std::promise<Process> promiseObj;
futureProcess.push_back(std::future<Process>(promiseObj.get_future()));
processThreads.push_back(std::thread(&ProcessHandle::addProcess, processHandle, host, port, &promiseProcess[0]));
Process val = futureProcess[0].get();
processHandle.handleList.push_back(val);
return (processHandle.handleList.size() - 1);
}
ProcessHandle.cpp
The addProcess function from ProcessHandle creates the Process that should be persistent, adds it to a static vector member of ProcessHandle and passes the promise to the execution loop.
int ProcessHandle::addProcess(const char *address, int port, std::promise<Process> * promiseObj) {
Process process(address, port);
handleList.push_back(process);
handleList[handleList.size() - 1].exec(promiseObj);
return handleList.size() - 1;
}
To the main problem now...
If I change "initializeProcessLoop" to include:
if(processHandle.handleList[0].isConnected())
{
processHandle.handleList[0].poll("/Compare To Constant/const");
}
after i've pushed "val" to the processHandle.handleList everything works fine and I can poll the data as it should be.
If I instead poll it from - for examle - the main function, the loop crashes inside of the "initializeProcessLoop" because "Process val" is reassigned (?) with futureProcess[0].get().
How can I get the Process variable and the threaded loop to be consistent after the function returns?
If there are any questions to the code (and I bet there will be), feel free to ask. Thanks in advance!
PS: Obligatory "English is not my native language, please excuse any spelling errors or gibberish"...
Okay, first I have to declare, that the coding style above and following are by any means not best practice.
While Sam Varshavchik is still right with how to learn C++ the right way, just changing
Process val = futureProcess[0].get();
to
static Process val = futureProcess[0].get();
did the job.
To be clear: don't do this. It's a quick fix but it will backfire in the future. But I hope that it'll help anyone with a similar problem.
If anyone has a better solution (it can't get any worse, can it?), feel free to add your answer to this question.
Goal
Broadly, I want to accomplish the following:
Generate a series of images in real-time from a program
Pass the images to a DirectShow source filter, which is registered as a capture source
Select the resulting "virtual webcam" in a program like Lync
The image generation is already written and must leverage an existing framework. I am currently working on the interface between the framework and DirectShow. My current implementation for passing the images is described below.
Interfacing
A COM interface is described in an .idl file, and the generated .c/.h files are included in the source filter and, by extension, the framework module.
Additional methods allow for specifying a media format to support and tuning parameters based on the rate of image generation.
The passImage method passes a pointer to a generated image buffer and the size of the buffer. This is called by a framework sink module when it receives new data to pass.
MyInterface.idl
[
object,
uuid("46B4BD3C-CD67-4158-BB83-89EA95306A4D"),
] interface IExtLiveSrc : IUnknown
{
...
HRESULT passImage
(
[in] unsigned long size,
[in, size_is(size)] BYTE **img
);
};
DirectShow Source Filter
The source filter is implemented as two classes and an associated CLSID that are exported as a DLL and registered using regsvr32. The DLLRegisterServer method is implemented appropriately to register the COM object under CLSID_VideoInputDeviceCategory.
MyFilter.h
class CVSource : public CSource {
static CUnknown *WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
// private constructor
}
class CVSourceStream : public CSourceStream
, public virtual IKsPropertySet
, public virtual IAMStreamConfig
, public virtual IExtLiveSrc
{
// constructor, IUnknown, IKsPropertySet, IAMStreamConfig methods
...
HRESULT FillBuffer(IMediaSample *pms);
STDMETHODIMP passImage(unsigned long size, BYTE **img);
}
Note: the pin (CSourceStream-derived class) implements the interface used to pass images. Assume that buffer size negotiation has already been established.
passImage()
STDMETHODIMP CVSourceStream::passImage(unsigned long size, BYTE **img) {
memcpy_s(this->bufferedImg, size, *img, size);
return S_OK;
}
FillBuffer()
HRESULT CVSourceStream::FillBuffer(IMediaSample *pms) {
// Set timestamp on IMediaSample instance
...
BYTE *pData;
pms->GetPointer(&pData);
long lDataLen = pms->GetSize();
memcpy_s(pData, lDataLen, this->bufferedImg, lDataLen);
return S_OK;
}
Question
Ignoring locking and synchronization for the moment (I know that FillBuffer() should block until data is available), I've made the following observations.
Adding a generated test sequence of buffers directly to FillBuffer() leads to Lync correctly displaying them.
When running my program, passImage() behaves correctly and the buffer instance variable receives the correct data. However, FillBuffer() never seems to be called when debugging.
Based on research I've done, it appears my issue is that the two different processes (my framework program and Lync) don't share the same data in the source filter DLL due to creating two separate instances of the filter graph.
What is the cleanest way for Lync's instance of the filter graph to share data with the images my program is despositing? I've seen "inter-process communication" tossed around. Though I'm not familiar with the concept, what would be a clear list of steps I would need to take towards my goal (pipes, sockets, shared memory, registry, etc.)?
Links
A similar discussion on the MSDN forums.
There's discussion of a similar problem to what I have but not enough concrete details, and I don't want to post on an old thread.
A similar question on stack overflow.
This is actually quite similar to what I already have. However, I need to run a new application that presumably creates its own filter graph.
You have to pass data between processes: Lync will always use the filter in its process, without asking where it takes data from. And since it is supposed to take data from external process, it has to deal with interprocess communication and "somehow connect" to remote process where the data comes from.
There are options how you can implement this "somehow" exactly. I would prefer using memory mapped files and events/mutexes for synchronization. Producer process generates data and stores them in MMF, then consumer filter inside Lync processes reads this and delivers as generated video.
I am trying to write a custom version of a lock screen tile. I tried my best to optimize the speed in C#, it still can't match an app called Lock Screen Native.
So now I want to try C++ and see if it would be the same fast.
C#
static void Main(string[] args) {
Shell_TurnScreenOn(false);
}
[DllImport("ShellChromeAPI.dll")]
private extern static void Shell_TurnScreenOn(bool value);
How do I write it in C++? (As Dllimport doesn't seem to work in Windows Phone.)
Figured it out finally...
Get the pointer of LoadLibraryExW and then use it to load the dll.
http://vilic.info/blog/archives/1138
I'm a newer to NPAPI. I come across one problem.
in my plugin, I need to return some data from C++ to JavaScript, yes,that's callback. but the callback thread and the main thread are separate threads. So I use NPN_PluginThreadAsyncCall, but the problem can not be solved also. When callback, the firefox crashed...
Can anyone help me?
the bellow codes are in the callback thread, Can anyone tell me, why it crashed?
npnfuncs->pluginthreadasynccall(instance,callBackfunc,(void*)pdata);
/////////////////////////////////////////////////////////////////////
void callBackfunc(void* arg)
{
NPObject *winobj;
npnfuncs->getvalue(instance,NPNVWindowNPObject,&winobj);
NPVariant handler;
NPIdentifier id1 = npnfuncs->getstringidentifier("MyTest".c_str());
npnfuncs->getproperty(instance, winobj, id1, &handler);
NPObject* handlerObj= NPVARIANT_TO_OBJECT(handler);
NPVariant prototype;
NPIdentifier id2 = npnfuncs->getstringidentifier("prototype");
npnfuncs->getproperty(instance, serviceHandlerObj, id2, &prototype);
NPObject* prototypeObj= NPVARIANT_TO_OBJECT(prototype);
NPIdentifier id = npnfuncs->getstringidentifier("fun".c_str());
NPVariant voidResponse;
int status=npnfuncs->invoke(instance,prototypeObj,id,args,argCount,&voidResponse);
return;
}
thanks
Best Regards
greatsea
... What is "MyTest".c_str() supposed to be? This is C++, no? c_str() is a method of a std::string class, and I don't see that being sued here, so trying to do a .c_str() on it shouldn't even compile, unless there is something going on here that I really don't understand.
Also be aware that at least Safari 5.1 has stopped supporting NPN_PluginThreadAsyncCall and different methods need to be used to make cross-thread callbacks. I don't know if other browsers have or will or not; so far it doesn't seem so.
Is there a reason you're not just using FireBreath for your plugin? It solves all of these problems for you and lets you just focus on your plugin...