I have a function in my pkcs#11 library that I want to open a wxwidgets window when called. The function will be called when the pkcs#11 C_Sign function is called by firefox. (My C_Sign function calls login_dialog)
Here is the code
#include <wx/wx.h>
#include "wx/wxprec.h"
#include <pthread.h>
class wxP11App2 : public wxApp
{
public:
virtual bool OnInit();
};
DECLARE_APP(wxP11App2)
// Use _NO_MAIN since we don't want main() to be created
IMPLEMENT_APP_NO_MAIN(wxP11App2);
bool wxP11App2::OnInit()
{
printf("OnInit\n");
wxFrame *frame = new wxFrame((wxFrame*) NULL, -1, _T("Hello wxWidgets World"));
frame->CreateStatusBar();
frame->SetStatusText(_T("Hello World"));
frame->Show(true);
SetTopWindow(frame);
printf("OnInit done\n");
return true;
}
void* start_wxapp_func(void* args)
{
printf("Thread func\n");
int argc = 0;
wxChar* argv = NULL;
wxApp* pApp = new wxP11App2();
wxApp::SetInstance(pApp);
wxEntry(argc, &argv);
return NULL;
}
int login_dialog()
{
int rv = 0;
pthread_t thread1;
pthread_create( &thread1, NULL, start_wxapp_func, NULL);
int count = 0;
while(1) {
printf("Sleep: %d\n", count++);
sleep(1);
}
return rv;
}
However, firefox crashes when wxEntry is being called. If I call C_Sign from a newly created c++ program (as opposed to when firefox calls the C_Sign function) it works. I get my wxwidgets window. I don't use any other GUI in that program. (There is neither any wxwidgets context nor gtk context).
It seems that it's gtk that crashes firefox so I thought it might have something to do that firefox already has a gtk instance running (and since wxwidgets uses gtk it might be a problem).
Do you have any suggestions on what I should try?
UPDATE:
Here is a stack trace from firefox built with debug info:
0 gdk_drawable_get_screen mozgtk.c 561 0x7f5ab2291b09
1 wx_gdk_window_get_screen gtk2-compat.h 391 0x7f5a859beca4
2 wxClientDisplayRect display.cpp 80 0x7f5a859bedb2
3 wxGetClientDisplayRect gdicmn.cpp 902 0x7f5a85ae5300
4 wxTopLevelWindowBase::GetDefaultSize toplvcmn.cpp 216 0x7f5a85b7f8fb
5 wxTopLevelWindowGTK::Create toplevel.cpp 571 0x7f5a859d3955
6 wxFrame::Create frame.cpp 56 0x7f5a85a3bb75
7 wxFrame::wxFrame frame.h 31 0x7f5a8679dd0c
8 wxP11App2::OnInit LoginDlg_linux.cpp 27 0x7f5a8679d825
9 wxAppConsoleBase::CallOnInit app.h 93 0x7f5a8679db95
10 wxEntry init.cpp 479 0x7f5a858b789f
11 start_wxapp_func LoginDlg_linux.cpp 47 0x7f5a8679da2a
12 start_thread 312 0x7f5ab1e60182
13 clone 111 0x7f5ab116947d
So in my code, it's the creation of a new wxFrame that crashes the program.
If the problem is really due to using 2 sets of mismatching GTK+ libraries, then the most straightforward solution is to build wxWidgets using exactly the same version of GTK+ and dependent libraries that was used for building your Firefox. In practice, the simplest way to do it would probably be to build it under the same system where Firefox was built.
This is definitely not ideal from the maintenance perspective, but unfortunately I just can't suggest any other solution. If your code is GPL you could try linking GTK+ statically, but it's usually not recommended for various reasons and if it's not GPL you can't do it anyhow.
Related
I am a new guy to Qt although I have been writing in C for many years only about a year or so using c++. We are writing a camera app which has some C++ code for accessing frame buffers, video, etc. and a GUI that is written in QML. It is necessary to invoke gstreamer in a c++ class which needs to run in a separate thread and needs to be invoked from the QML code (because the QML code hangs waiting for threads to finish if it is invoked before starting the QML).
I found what looked like a great way to do it in the answer to someone else's question: How Start a Qthread from qml?. Unfortunately when I attempted to modify my code to run as shown in one of the answers I am getting a SIGABT signal. This happens when the code executes the following line:
view.engine()->rootContext()->setContextProperty("thread", &gstworker);
The main.cpp function looks like this:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>
#include <gst/gst.h>
#include "common.h"
#include "fbctl.h"
#include "gstcameraif.h"
#include "gstworker.h"
int main(int argc, char *argv[])
{
DBG_PRINT("main.cpp: register FbCtl type\n");
qmlRegisterType<FbCtl>("test.fbctl.qt", 1, 0, "FbCtl");
DBG_PRINT("main.cpp: register GstCameraIf type\n");
qmlRegisterType<GstCameraIf>("test.gstcameraif.qt", 1, 0, "GstCameraIf");
DBG_PRINT("main.cpp: register GstWorker type");
qmlRegisterType<GstWorker>("test.gstworker.qt", 1, 0, "GstWorker");
gst_init(&argc, &argv);
GstCameraIf gStreamer;
FbCtl fbSetup; // get a local instance of the frame buffer control object
fbSetup.setupOverlay(); // initialize the overlay setup
fbSetup.stopProcess(); // close opened descriptors, unmap frame buffers
qputenv("QT_QPA_EGLFS_FB", "dev/fb1"); // redirects QT to use fb1 (overlay) and gstreamer will go to fb0
GstWorker gstworker;
QQuickView view;
view.engine()->rootContext()->setContextProperty("thread", &gstworker);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
gst_deinit();
return app.exec();
}
The function call list (stack) shows the following trace:
1 __GI_raise raise.c 54 0xb5ae1910
2 __GI_abort abort.c 89 0xb5ae2ca0
3 qt_message_fatal qlogging.cpp 1687 0xb5e0fff8
4 QMessageLogger::fatal qlogging.cpp 795 0xb5e0fff8
5 qt_pixmap_thread_test qpixmap.cpp 74 0xb670ce98
6 QPixmap::QPixmap qpixmap.cpp 109 0xb670ce98
7 QCursorData::QCursorData qcursor.cpp 624 0xb66a3360
8 QCursorData::initialize qcursor.cpp 655 0xb66a3360
9 QCursor::QCursor qcursor.cpp 470 0xb66a3360
10 QWindowPrivate::QWindowPrivate qwindow_p.h 107 0xb6bb3a78
11 QQuickWindowPrivate::QQuickWindowPrivate qquickwindow.cpp 501 0xb6bb3a78
12 QQuickViewPrivate::QQuickViewPrivate qquickview.cpp 77 0xb6c306e0
13 QQuickView::QQuickView qquickview.cpp 166 0xb6c30778
14 main main.cpp 38 0x131c8
My question is what do I need to fix to get rid of the sigabt signal.
thanks for any help you can give.
When I got the error again I noticed that it was actually happening when I declared the QQuickView object. I changed the main.cpp to use the QQmlApplicationEngine (instead of creating a quickview engine) to set the context and the error no longer occurs.
FYI: The SIGABT error was given in a message box and that is all it said.
I would like to give credit to #m7913d for the help in solving this issue.
When I execute the following program on the my embedded Linux nothing happens:
#include <boost/thread/thread.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <iostream>
#include <boost/atomic.hpp>
void Test(void)
{
std::cout << "Hello World" << std::endl;
}
int main(int argc, char* argv[])
{
std::cout << "init";
boost::thread producer_thread(Test);
producer_thread.join();
std::cout << "end";
}
# ./prog -> nothing happens here
The last few lines from strace output are:
open("/lib/libboost_thread.so.1.55.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\240\272\0\0004\0\0\0"..., 512) = 512
lseek(3, 95536, SEEK_SET) = 95536
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1200) = 1200
lseek(3, 95226, SEEK_SET) = 95226
read(3, "A'\0\0\0aeabi\0\1\35\0\0\0\0055T\0\6\3\10\1\t\1\22\4\24\1\25\1"..., 40) = 40
exit_group(1) = ?
+++ exited with 1 +++
#
The cross compiled libbost_thread is right installed at /lib.
The program exit before main() being called. The program runs normal under my Ubuntu.
Target: ARM with buildroot (sama5d3)
Toolchain: arm-linux-gnueabihf-
Regards
Maybe as a hint:
Have you linked against libpthread with compile and link option -pthread for your target?
If not it can have the same effect as seen in your environment: The prog starts, try to start a new thread, have no threading enabled and call the abort() function. Because abort() simply leave the prog with error in exit code nothing else happens.
Can you also add your compile & link commands for debugging purpose please!
In addition:
Your outputs without endl will not be printed because cout is buffered. The buffer will be printed only if you call flush or send a endl. Maybe you change this in your example.
Hope that helps...
strace is a tool that traces system calls. In your example, this consists of calls to open(), lseek(), and read(). Specifically, the snippet that you pasted shows the OS's dynamic library loader opening the libboost_thread.so.1.55.0 file and reading its contents; nothing more. It doesn't really demonstrate anything about your program except that it is linked against that library.
I found the problem.
The boost library was compiled with arm-linux-gnueabi- (elibc) and the buildroot is compiled with uClibc.
My goal is to build a Game Boy emulator. In order to do this, I would like to embed an SDL2 surface into a wxWidgets window.
I found this tutorial: http://code.technoplaza.net/wx-sdl/part1/, but my program crashes as soon as I run it. However I suspect this was intended for SDL1.2. Part of the program is shown below.
It seems that if I call SDL_Init() and also attempt to show a wxFrame (which, in this case, is MainWindow), it shows the window for a second and then the program crashes. I commented all other calls to SDL in my program so far, so it seems the problem lies with calling Show() on a wxFrame and initing SDL2 in the same program.
So the question is: can SDL2 and wxWidgets 3 work together? If not, could you guys suggest to me good alternatives a GUI of a Game Boy emulator? Does wxWidgets have its own graphics frame like Qt does (I'd rather avoid Qt)?
Thanks very much!
#include "MainApp.h"
#include "MainWindow.h"
#include <stdexcept>
namespace GBEmu {
static void initSDL() {
//This and SDL_Quit() are the only calls to the SDL library in my code
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
throw std::runtime_error("Fatal Error: Could not init SDL");
}
}
bool MainApp::OnInit()
{
try {
//If I comment out this line, the MainWindow wxFrame shows up fine.
//If I leave both uncommented, the window shows up quickly and then
//crashes.
initSDL();
//If I comment out this line and leave initSDL() uncommented,
//the program will not crash, but just run forever.
(new MainWindow("GBEmu", {50,50}, {640,480}))->Show();
} catch(std::exception &e) {
wxLogMessage(_("Fatal Error: " + std::string(e.what())));
}
return true;
}
int MainApp::OnExit() {
SDL_Quit();
return wxApp::OnExit();
}
}
wxIMPLEMENT_APP(GBEmu::MainApp);
EDIT: Here is more information on how it crashes: It crashes with a Segfault in what seems to be the pthread_mutex_lock disassembly file. This is the output in the console with stack trace:
Starting /home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx...
The program has unexpectedly finished.
/home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx crashed
Stack trace:
Error: signal 11:
/home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx(_ZN5GBEmu7handlerEi+0x1c)[0x414805]
/lib/x86_64-linux-gnu/libc.so.6(+0x36ff0)[0x7fb88e136ff0]
/lib/x86_64-linux-gnu/libpthread.so.0(pthread_mutex_lock+0x30)[0x7fb88c12ffa0]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XrmQGetResource+0x3c)[0x7fb88d1ca15c]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XGetDefault+0xc2)[0x7fb88d1a7a92]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x94dcf)[0x7fb88af8edcf]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x97110)[0x7fb88af91110]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(cairo_surface_get_font_options+0x87)[0x7fb88af63e07]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x2b61f)[0x7fb88af2561f]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x2ef95)[0x7fb88af28f95]
This is a screenshot of where it seems to fail (line 7):
Update: In my MainWindow class, I attach a menu bar to the window. However, it seems when I comment out the setting of the menu bar, the window will show up fine even with initing of SDL. The menu bar will show up fine if I have initSDL() commented out but not the setting of the menu bar. Here is where I set the menu bar:
MainWindow::MainWindow(const wxString &title, const wxPoint &pos, const wxSize &size)
:wxFrame(nullptr, wxIDs::MainWindow, title, pos, size){
wxMenu *fileMenu = new wxMenu;
fileMenu->Append(wxID_EXIT);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(fileMenu, "&File");
//commenting this line out will allow the window to showup
//and not crash the program
SetMenuBar(menuBar);
}
You are experiencing an old heisenbug.
The workaround is simple: you have to initialize SDL before wxWidgets (basically, before GTK). To achieve this, you have to change
wxIMPLEMENT_APP(GBEmu::MainApp);
to
wxIMPLEMENT_APP_NO_MAIN(GBEmu::MainApp);
so that wxWidgets doesn't hijack your main().
Then you have to create main() manually. In it, initialize SDL, then call wxEntry():
int main(int argc, char** argv)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cerr << "Could not initialize SDL.\n";
return 1;
}
return wxEntry(argc, argv);
}
More about the bug:
I have googled around a bit and found that this bug has come up in a few places over the years. There are open reports in many bug trackers that have stack traces very similar to the one you get here (with debug symbols).
The oldest report I could find is from 2005 (!!) from the cairo bug tracker (https://bugs.freedesktop.org/show_bug.cgi?id=4373).
My best guess is that the real hiding place of this bug in either in GTK, cairo, or X. Unfortunately I do not currently have the time to look into it more in depth.
A bit of context; this program was built originally to work with USB cameras - but because of the setup between where the cameras needs to be and where the computer is it makes more sense to switch to cameras run over a network. Now I'm trying to convert the program to accomplish this, but my efforts thus far have met with poor results. I've also asked this same question over on the OpenCV forums. Help me spy on my neighbors! (This is with their permission, of course!) :D
I'm using:
OpenCV v2.4.6.0
C++
D-Link Cloud Camera 7100 (Installer is DCS-7010L, according to the instructions.)
I am trying to access the DLink camera's video feed through OpenCV.
I can access the camera through it's IP address with a browser without any issues. Unfourtunately; my program is less cooperative. When attempting to access the camera the program gives the OpenCV-generated error:
warning: Error opening file (../../modules/highgui/src/cap_ffmpeg_impl.hpp:529)
This error occurs with just about everything I try that doesn't somehow generate more problems.
For reference - the code in OpenCV's cap_ffmpeg_impl.hpp around line 529 is as follows:
522 bool CvCapture_FFMPEG::open( const char* _filename )
523 {
524 unsigned i;
525 bool valid = false;
526
527 close();
528
529 #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
530 int err = avformat_open_input(&ic, _filename, NULL, NULL);
531 #else
532 int err = av_open_input_file(&ic, _filename, NULL, 0, NULL);
533 #endif
...
616 }
...for which I have no idea what I'm looking at. It seems to be looking for the ffmpeg version - but I've already installed the latest ffmpeg on that computer, so that shouldn't be the issue.
This is the edited down version I tried to use as per Sebastian Schmitz's recommendation:
1 #include <fstream> // File input/output
2 #include <iostream> // cout / cin / etc
3 #include <windows.h> // Windows API stuff
4 #include <stdio.h> // More input/output stuff
5 #include <string> // "Strings" of characters strung together to form words and stuff
6 #include <cstring> // "Strings" of characters strung together to form words and stuff
7 #include <streambuf> // For buffering load files
8 #include <array> // Functions for working with arrays
9 #include <opencv2/imgproc/imgproc.hpp> // Image Processor
10 #include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
11 #include <opencv2/highgui/highgui.hpp> // OpenCV window I/O
12 #include "opencv2/calib3d/calib3d.hpp"
13 #include "opencv2/features2d/features2d.hpp"
14 #include "opencv2/opencv.hpp"
15 #include "resource.h" // Included for linking the .rc file
16 #include <conio.h> // For sleep()
17 #include <chrono> // To get start-time of program.
18 #include <algorithm> // For looking at whole sets.
19
20 #ifdef __BORLANDC__
21 #pragma argsused
22 #endif
23
24 using namespace std; // Standard operations. Needed for most basic functions.
25 using namespace std::chrono; // Chrono operations. Needed getting starting time of program.
26 using namespace cv; // OpenCV operations. Needed for most OpenCV functions.
27
28 string videoFeedAddress = "";
29 VideoCapture videoFeedIP = NULL;
30 Mat clickPointStorage; //Artifact from original program.
31
32 void displayCameraViewTest()
33 {
34 VideoCapture cv_cap_IP;
35 Mat color_img_IP;
36 int capture;
37 IplImage* color_img;
38 cv_cap_IP.open(videoFeedAddress);
39 Sleep(100);
40 if(!cv_cap_IP.isOpened())
41 {
42 cout << "Video Error: Video input will not work.\n";
43 cvDestroyWindow("Camera View");
44 return;
45 }
46 clickPointStorage.create(color_img_IP.rows, color_img_IP.cols, CV_8UC3);
47 clickPointStorage.setTo(Scalar(0, 0, 0));
48 cvNamedWindow("Camera View", 0); // create window
49 IplImage* IplClickPointStorage = new IplImage(clickPointStorage);
50 IplImage* Ipl_IP_Img;
51
52 for(;;)
53 {
54 cv_cap_IP.read(color_img_IP);
55 IplClickPointStorage = new IplImage(clickPointStorage);
56 Ipl_IP_Img = new IplImage(color_img_IP);
57 cvAdd(Ipl_IP_Img, IplClickPointStorage, color_img);
58 cvShowImage("Camera View", color_img); // show frame
59 capture = cvWaitKey(10); // wait 10 ms or for key stroke
60 if(capture == 27 || capture == 13 || capture == 32){break;} // if ESC, Return, or space; close window.
61 }
62 cv_cap_IP.release();
63 delete Ipl_IP_Img;
64 delete IplClickPointStorage;
65 cvDestroyWindow("Camera View");
66 return;
67 }
68
69 int main()
70 {
71 while(1)
72 {
73 cout << "Please Enter Video-Feed Address: ";
74 cin >> videoFeedAddress;
75 if(videoFeedAddress == "exit"){return 0;}
76 cout << "\nvideoFeedAddress: " << videoFeedAddress << endl;
77 displayCameraViewTest();
78 if(cvWaitKey(10) == 27){return 0;}
79 }
80 return 0;
81 }
Using added 'cout's I was able to narrow it down to line 38: "cv_cap_IP.open(videoFeedAddress);"
No value I enter for the videoFeedAddress variable seems to get a different result. I found THIS site that lists a number of possible addresses to connect to it. Since there exists no 7100 anywhere in the list & considering that the install is labeled "DCS-7010L" I used the addresses found next to the DCS-7010L listings. When trying to access the camera most of them can be reached through the browser, confirming that they reach the camera - but they don't seem to affect the outcome when I use them in the videoFeedAddress variable.
I've tried many of them both with and without username:password, the port number (554), and variations on ?.mjpg (the format) at the end.
I searched around and came across a number of different "possible" answers - but none of them seem to work for me. Some of them did give me the idea for including the above username:password, etc stuff, but it doesn't seem to be making a difference. Of course, the number of possible combinations is certainly rather large- so I certainly have not tried all of them (more direction here would be appreciated). Here are some of the links I found:
This is one of the first configurations my code was in. No dice.
This one is talking about files - not cameras. It also mentions codecs - but I wouldn't be able to watch it in a web browser if that were the problem, right? (Correct me if I'm wrong here...)
This one has the wrong error code/points to the wrong line of code!
This one mentions compiling OpenCV with ffmpeg support - but I believe 2.4.6.0 already comes with that all set and ready! Otherwise it's not that different from what I've already tried.
Now THIS one appears to be very similar to what I have, but the only proposed solution doesn't really help as I had already located a list of connections. I do not believe this is a duplicate, because as per THIS meta discussion I had a lot more information and so didn't feel comfortable taking over someone else's question - especially if I end up needing to add even more information later.
Thank you for reading this far. I realize that I am asking a somewhat specific question - although I would appreciate any advice you can think of regarding OpenCV & network cameras or even related topics.
TLDR: Network Camera and OpenCV are not cooperating. I'm unsure if
it's the address I'm using to direct the program to the camera or the
command I'm using - but no adjustment I make seems to improve the
result beyond what I've already done! Now my neighbors will go unwatched!
There's a number of ways to get the video. ffmpeg is not the only way although it's most convenient. To diagnose if ffmpeg is capable of reading the stream, you should use the standalone ffmpeg/ffplay to try to open the url. If it can open directly, it may be some minor things like url formatting such as double slashes(rtsp://IPADDRESS:554/live1.sdp instead of rtsp://IPADDRESS:554//live1.sdp). If it cannot open it directly, it may need some extra commandline switches to make it work. Then you would need to modify opencv's ffmpeg implementation # line 529 to pass options to avformat_open_input. This may require quite bit of tweaking before you can get a working program.
You can also check if the camera provide a http mjpeg stream by consulting it's manual. I do not have the camera you are using. So I cannot be of much help on this.
Alternatively, I have two suggestions below, which might help you up and running relatively quickly since you mentioned that vlc is working.
method 1
i assume that you can at least open mjpeg url with your existing opencv/ffmpeg combination. since vlc is working, just use vlc to transcode the video into mjpeg like
vlc.exe --ignore-config -I dummy rtsp://admin:admin#10.10.204.111 --sout=#transcode"{vcodec=MJPG,vb=5000,scale=1,acodec=none}:std{access=http,mux=raw,dst=127.0.0.1:9080/frame.mjpg}"
after that use http://127.0.0.1:9080/frame.mjpg to grab the frame using opencv VideoCapture. this just requires that you have a transcoder program that can convert the incoming stream into mjpeg.
method 2
you can also directly use vlc api programmatically. the following piece of code use vlc to grab the frames. relevant info for compilation
C:\Program Files (x86)\VideoLAN\VLC\sdk\include
C:\Program Files (x86)\VideoLAN\VLC\sdk\lib
libvlc.lib,libvlccore.lib
code
#include "opencv2/highgui/highgui.hpp"
#include <windows.h>
#include <vlc/vlc.h>
using namespace cv;
struct ctx
{
Mat* image;
HANDLE mutex;
uchar* pixels;
};
bool isRunning=true;
Size getsize(const char* path)
{
libvlc_instance_t *vlcInstance;
libvlc_media_player_t *mp;
libvlc_media_t *media;
const char * const vlc_args[] = {
"-R",
"-I", "dummy",
"--ignore-config",
"--quiet",
};
vlcInstance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
media = libvlc_media_new_location(vlcInstance, path);
mp = libvlc_media_player_new_from_media(media);
libvlc_media_release(media);
libvlc_video_set_callbacks(mp, NULL, NULL, NULL, NULL);
libvlc_video_set_format(mp, "RV24",100,100, 100 * 24 / 8); // pitch = width * BitsPerPixel / 8
libvlc_media_player_play(mp);
Sleep(2000);//wait a while so that something get rendered so that size info is available
unsigned int width=640,height=480;
libvlc_video_get_size(mp,0,&width,&height);
if(width==0 || height ==0)
{
width=640;
height=480;
}
libvlc_media_player_stop(mp);
libvlc_release(vlcInstance);
libvlc_media_player_release(mp);
return Size(width,height);
}
void *lock(void *data, void**p_pixels)
{
struct ctx *ctx = (struct ctx*)data;
WaitForSingleObject(ctx->mutex, INFINITE);
*p_pixels = ctx->pixels;
return NULL;
}
void display(void *data, void *id){
(void) data;
assert(id == NULL);
}
void unlock(void *data, void *id, void *const *p_pixels)
{
struct ctx *ctx = (struct ctx*)data;
Mat frame = *ctx->image;
if(frame.data)
{
imshow("frame",frame);
if(waitKey(1)==27)
{
isRunning=false;
//exit(0);
}
}
ReleaseMutex(ctx->mutex);
}
int main( )
{
string url="rtsp://admin:admin#10.10.204.111";
//vlc sdk does not know the video size until it is rendered, so need to play it a bit so that size is known
Size sz = getsize(url.c_str());
// VLC pointers
libvlc_instance_t *vlcInstance;
libvlc_media_player_t *mp;
libvlc_media_t *media;
const char * const vlc_args[] = {
"-R",
"-I", "dummy",
"--ignore-config",
"--quiet",
};
vlcInstance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
media = libvlc_media_new_location(vlcInstance, url.c_str());
mp = libvlc_media_player_new_from_media(media);
libvlc_media_release(media);
struct ctx* context = ( struct ctx* )malloc( sizeof( *context ) );
context->mutex = CreateMutex(NULL, FALSE, NULL);
context->image = new Mat(sz.height, sz.width, CV_8UC3);
context->pixels = (unsigned char *)context->image->data;
libvlc_video_set_callbacks(mp, lock, unlock, display, context);
libvlc_video_set_format(mp, "RV24", sz.width, sz.height, sz.width * 24 / 8); // pitch = width * BitsPerPixel / 8
libvlc_media_player_play(mp);
while(isRunning)
{
Sleep(1);
}
libvlc_media_player_stop(mp);
libvlc_release(vlcInstance);
libvlc_media_player_release(mp);
free(context);
return 0;
}
I coded a simple application using SDL which displays a simple window on Windows 8 (64 bits). In a first time I compiled and executed my code with Win32 configuration (default configuration) and the program works perfectly. Now I want to have the same execution but this time with x64 configuration. So I configured Visual using 'configurations manager' in my project properties and change my SDL.lib and SDLmain.lib choosing x64 libraries in the linker. The project compilation is ok but the execution fails saying that the application has failed to start properly. Here's a screen of the message (the memory address is always the same at each execution) :
And my c++ code :
#include <iostream>
#include <SDL/SDL.h>
#include <GL/glew.h>
#include <GL/glu.h>
#define WIDTH 500
#define HEIGHT 500
static float angle = 0.0f;
static void eventListener(SDL_Event *pEvent, bool *pContinue)
{
while (SDL_PollEvent(pEvent))
{
switch(pEvent->type)
{
case SDL_QUIT:
*pContinue = false;
break;
case SDL_KEYDOWN:
switch (pEvent->key.keysym.sym)
{
case SDLK_ESCAPE:
*pContinue = false;
break;
}
break;
}
}
}
#undef main
int main(void)
{
SDL_Event myEvent;
bool isAlive = true;
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Simple SDL window", NULL);
SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL);
while (isAlive == true)
{
eventListener(&myEvent, &isAlive);
}
SDL_Quit();
return (0);
}
I don't understand this message which is not precise. However my x64 SDL libraries linked to my project seems to be correct because the compilation is ok. So I wonder what's happening here. Does anyone already have encountered the same problem ?
Just googled for your error message, and it says that this error code (0x0c000007b) means INVALID_IMAGE_FORMAT.
This means that either you are mixing 32 and 64 bit binaries or you have corrupted binaries. Try to place you binary and your dependencies at the same folder and run the application. If the error continues, than one of your libraries must be corrupted. Else, it was a problem with the Windows loading a library for a different platform of your compiled binary.