I have just ported my C++ game to OS X and the first time it ran I get the following exception when trying to call SDL_SetVideoMode.
2012-09-28 15:01:05.437 SCRAsteroids[28595:707] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error (1000) creating CGSWindow on line 259'
* First throw call stack:
(
0 CoreFoundation 0x00007fff8b53b716 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff90e30470 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8b53b4ec +[NSException raise:format:] + 204
3 AppKit 0x00007fff8a26a579 _NSCreateWindowWithOpaqueShape2 + 655
4 AppKit 0x00007fff8a268d70 -[NSWindow _commonAwake] + 2002
5 AppKit 0x00007fff8a2277e2 -[NSWindow _commonInitFrame:styleMask:backing:defer:] + 1763
6 AppKit 0x00007fff8a22692f -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1568
7 AppKit 0x00007fff8a2262ff -[NSWindow initWithContentRect:styleMask:backing:defer:] + 45
8 libSDL-1.2.0.dylib 0x0000000107c228f6 -[SDL_QuartzWindow initWithContentRect:styleMask:backing:defer:] + 294
9 libSDL-1.2.0.dylib 0x0000000107c20505 QZ_SetVideoMode + 2837
10 libSDL-1.2.0.dylib 0x0000000107c17af5 SDL_SetVideoMode + 917
11 SCRAsteroids 0x0000000107be60fb _ZN11SDLGraphics4initEP6IWorldii + 291
)
libc++abi.dylib: terminate called throwing an exception
Abort trap: 6
My init code looks like this:
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
return false;
const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
if (!videoInfo) {
fprintf(stderr, "Video query failed: %s\n",
SDL_GetError());
return false;
}
/* the flags to pass to SDL_SetVideoMode */
videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */
videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */
/* This checks to see if surfaces can be stored in memory */
if (videoInfo->hw_available)
videoFlags |= SDL_HWSURFACE;
else
videoFlags |= SDL_SWSURFACE;
if (w == 0) {
widthViewport = videoInfo->current_w;
heightViewport = videoInfo->current_h;
cout << "Will use full screen resolution of ";
videoFlags |= SDL_FULLSCREEN;
} else {
cout << "Will use full user supplied resolution of ";
widthViewport = w;
heightViewport = h;
videoFlags |= SDL_RESIZABLE; /* Enable window resizing */
}
cout << widthViewport << "x" << heightViewport << "\n";
/* This checks if hardware blits can be done */
if (videoInfo->blit_hw)
videoFlags |= SDL_HWACCEL;
/* Sets up OpenGL double buffering */
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
/* get a SDL surface */
surface = SDL_SetVideoMode(widthViewport, heightViewport,
SCREEN_BPP, videoFlags);
It gets into that last SDL call and throws the exception above. I have tried it in both full screen and resizable window mode, same thing.
I build my app old school, on the command line, as opposed to using Xcode.
SDL_main was yet again the culprit. My C++ main routine was in a file that does not include SDL.h, so it was not being redefined to SDL_main. The code that includes SDL is instead in a reusable static library, no main routine you see. I manually changed the name of my function to SDL_main and this means that SDL provides the essential main routine. I don't like doing this, but for the moment, on SDL 1.2.15 for Mac, it is necessary.
On Windows, the same new code causes linker conflicts. That's a new problem.
There are problems with calling the videocard in cocoa. So you need to initalize it before calling SDL_Setvideomode
Add the following method, and call it first in your main method
#include <dlfcn.h> //To make it work on mac
//This must be called before playing with SDL, else it won't work on osx.
void pre_init()
{
void* cocoa_lib;
cocoa_lib = dlopen( "/System/Library/Frameworks/Cocoa.framework/Cocoa", RTLD_LAZY );
void (*nsappload)(void);
nsappload = (void(*)()) dlsym( cocoa_lib, "NSApplicationLoad");
nsappload();
}
`
Same issue, but solved by linking libSDLmain (as well as libSDL). This in turn requires two frameworks: Foundation and Cocoa.
I didn't rename the main function.
Related
I have written a C++ application (deamon) which has some issues with application crashing due segmentation faults.
To get information about the code where the crash(es) happens i use libunwind. Which works very well on x86_x64 linux systems. There i get a nice stacktrace.
But on ARM architectures, the stacktrace only consists of the stack up to the "Deamon-code" iself and not into the shared libraries i use
I am using gcc 4.9 (for arm arm-linux-gnueabihf-g++4.9)
I am building the libraries and the deamon in debug mode (-g) with following parameters to get the tables for stack tracing
-funwind-tables -fasynchronous-unwind-tables -mapcs-frame -g
for the linker i use for the shared libs
-shared -pthread -static-libgcc -static-libstdc++ -rdynamic
Here is the sample stack trace of x86
1 0x0000000000403f68 sp=0x00007f0c2be8d630 crit_err_hdlr(int, siginfo_t*, void*) + 0x28
2 0x00007f0c2dfa33d0 sp=0x00007f0c2be8d680 __restore_rt + 0x0
3 0x00007f0c2dfa32a9 sp=0x00007f0c2be8dc18 raise + 0x29
4 0x00007f0c2e958bab sp=0x00007f0c2be8dc20 Raumserver::Request::RequestAction_Crash::crashLevel4() + 0x2b
5 0x00007f0c2e958d9c sp=0x00007f0c2be8dc60 Raumserver::Request::RequestAction_Crash::executeAction() + 0x12c
6 0x00007f0c2e96f045 sp=0x00007f0c2be8dce0 Raumserver::Request::RequestAction::execute() + 0x55
7 0x00007f0c2e940c83 sp=0x00007f0c2be8de00 Raumserver::Manager::RequestActionManager::requestProcessingWorkerThread()
+ 0x113
8 0x00007f0c2ee86380 sp=0x00007f0c2be8df00 execute_native_thread_routine + 0x20
9 0x00007f0c2df996fa sp=0x00007f0c2be8df20 start_thread + 0xca
10 0x00007f0c2dccfb5d sp=0x00007f0c2be8dfc0 clone + 0x6d
11 0x0000000000000000 sp=0x00007f0c2be8dfc8 + 0x6d
and here the trace from the arm devices. It seems that the stack information
for the shared libs is not present?!
1 0x0000000000013403 sp=0x00000000b49fe930 crit_err_hdlr(int, siginfo_t*, void*) + 0x1a
2 0x00000000b6a3b6a0 sp=0x00000000b49fe960 __default_rt_sa_restorer_v2 + 0x0
3 0x00000000b6b5774c sp=0x00000000b49fecd4 raise + 0x24
Here is a summary from the code for building the stacktrace which is called from the signal handler:
#ifdef __arm__
#include <libunwind.h>
#include <libunwind-arm.h>
#else
#include <libunwind.h>
#include <libunwind-x86_64.h>
#endif
...
void backtrace()
{
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
int n=0;
int err = unw_step(&cursor);
while ( err )
{
unw_word_t ip, sp, off;
unw_get_reg(&cursor, UNW_REG_IP, &ip);
unw_get_reg(&cursor, UNW_REG_SP, &sp);
char symbol[256] = {"<unknown>"};
char buffer[256];
char *name = symbol;
if ( !unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off) )
{
int status;
if ( (name = abi::__cxa_demangle(symbol, NULL, NULL, &status)) == 0 )
name = symbol;
}
sprintf(buffer, "#%-2d 0x%016" PRIxPTR " sp=0x%016" PRIxPTR " %s + 0x%" PRIxPTR "\n",
++n,
static_cast<uintptr_t>(ip),
static_cast<uintptr_t>(sp),
name,
static_cast<uintptr_t>(off));
if ( name != symbol )
free(name);
...
err = unw_step(&cursor);
}
}
And here the summary for the deamon itself:
int main(int argc, char *argv[])
{
Raumserver::Raumserver raumserverObject;
//Set our Logging Mask and open the Log
setlogmask(LOG_UPTO(LOG_NOTICE));
openlog(DAEMON_NAME, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
pid_t pid, sid;
//Fork the Parent Process
pid = fork();
if (pid < 0) { syslog (LOG_NOTICE, "Error forking the parent process"); exit(EXIT_FAILURE); }
//We got a good pid, Close the Parent Process
if (pid > 0) { syslog (LOG_NOTICE, "Got pid, closing parent process"); exit(EXIT_SUCCESS); }
//Change File Mask
umask(0);
//Create a new Signature Id for our child
sid = setsid();
if (sid < 0) { syslog (LOG_NOTICE, "Signature ID for child process could not be created!"); exit(EXIT_FAILURE); }
// get the working directory of the executable
std::string workingDirectory = getWorkingDirectory();
//Change Directory
//If we cant find the directory we exit with failure.
if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }
//Close Standard File Descriptors
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// Add some system signal handlers for crash reporting
//raumserverObject.addSystemSignalHandlers();
AddSignalHandlers();
// set the log adapters we want to use (because we do not want to use the standard ones which includes console output)
std::vector<std::shared_ptr<Raumkernel::Log::LogAdapter>> adapters;
auto logAdapterFile = std::shared_ptr<Raumkernel::Log::LogAdapter_File>(new Raumkernel::Log::LogAdapter_File());
logAdapterFile->setLogFilePath(workingDirectory + "logs/");
adapters.push_back(logAdapterFile);
// create raumserver object and do init
raumserverObject.setSettingsFile(workingDirectory + "settings.xml");
raumserverObject.initLogObject(Raumkernel::Log::LogType::LOGTYPE_ERROR, workingDirectory + "logs/", adapters);
raumserverObject.init();
// go into an endless loop and wait until daemon is killed by the syste,
while(true)
{
sleep(60); //Sleep for 60 seconds
}
//Close the log
closelog ();
}
Anybody an idea if i have missed some compiler flags? Is something missing?
I have found a lot of posts and all refere to the mentioned compiler flags or to libunwind. I have tried several other codes i found but they only give me a stack depth of 1
Thanks!
EDIT 11.11.2016:
For testing i built static libs instead of shared ones and added them to the application, so there are no dynamic links anymore. Unfortunetaly the stack trace is the same bad one.
I have even tried to compile the whole stuff with the thumb mode and changed the arm compiler to to gcc5/g++5
-mthumb -mtpcs-frame -mtpcs-leaf-frame
Same issue :-(
I have recently been working with OpenGL and have decided to use C++ for my latest project with OpenGL. I am using xCode 8.1 with my library paths and header paths linked correctly. Everything compiles fine but i get this error at runtime:
2016-11-03 15:17:24.649264 Modulo[25303:14858638] [General] ERROR: Setting <GLFWContentView: 0x100343da0> as the first responder for window <GLFWWindow: 0x100222540>, but it is in a different window ((null))! This would eventually crash when the view is freed. The first responder will be set to nil.(
0 AppKit 0x00007fff85c069a4 -[NSWindow _validateFirstResponder:] + 566
1 AppKit 0x00007fff853f79eb -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff8549f66a -[NSWindow _realMakeFirstResponder:] + 406
3 AppKit 0x00007fff8549f480 -[NSWindow makeFirstResponder:] + 123
4 libglfw3.3.dylib 0x000000010011194a _glfwPlatformCreateWindow + 610
5 libglfw3.3.dylib 0x000000010010d533 glfwCreateWindow + 428
6 Modulo 0x00000001000010a8 main + 296
7 libdyld.dylib 0x00007fff9c828255 start + 1
8 ??? 0x0000000000000001 0x0 + 1)
The code I run to generate this error is as follows:
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main(int argc, const char * argv[]) {
//Engine Startup.
std::cout << "<----- Engine Start-Up ----->" << std::endl;
//Initialize GLFW.
if(!glfwInit()) {
std::cout << "- GLFW Failed to Initialize!" << std::endl;
return -1;
}
std::cout << "+ GLFW Initialized!" << std::endl;
//Create GLFWWindow
GLFWwindow* window = glfwCreateWindow(640, 480, "Engine", nullptr, nullptr);
if(!window) {
std::cout << "- GLFWWindow Failed to Create!" << std::endl;
glfwTerminate();
return -1;
}
std::cout << "+ GLFWWindow Created!" << std::endl;
return 0;
}
The program performs as it should but this error could become an issue later and also makes the console hard to debug so I would like to try and sort it out early!
Thank you in advance and if any more information is needed please let me know! :)
I'm a beginner and I also faced this issue.
I got an error but succeed to create window. How about adding:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
before glfwCreateWindow?
Note discussion here GLFW first responder error which indicates it is a known bug in macOS Sierra, which has been addressed in the git repo for GLFW, but not yet released.
I am using the SDL2 2.0.3 library with the SDL_image library 2.0.0 in Visual C++ 2010 Express. I am utilizing the SDL_image library to load a variety of PNG and JPEG files from a resources folder. While the library initializes without any errors and loads BMP and JPEG files, it breaks when given a PNG file.
"Unhandled exception at 0x00000000 in appname.exe: 0xC0000005: Access violation."
Inside of my texture manager, (an object that stores and manages textures for the program), is a function to load a texture from a given file name string. Here is the code, including the commented line I used before implementing SDL_image to do the loading. It is within the line bitmapSurface = IMG_Load(... that the exception above is thrown.
/**
* Attempts to load a given image file and reports to the console any failures
*
* #param fileName The exact file name of the resource to be loaded
* #return The SDL_Texture loaded from the given fileName
*/
SDL_Texture* TextureManager::loadTexture(string fileName)
{
//Create our surface in RAM
SDL_Surface *bitmapSurface = NULL;
//bitmapSurface = SDL_LoadBMP(fileName.c_str()); //OLD METHOD; standard SDL, BMP only
bitmapSurface = IMG_Load(fileName.c_str()); //NEW METHOD; SDL_image lib, many formats
//Verify it exists
if (bitmapSurface == NULL)
cout << "Image resource not loaded: " << fileName << " Message: " << IMG_GetError() << endl;
//Create a texture in VRAM from the surface
SDL_Texture *bitmapTexture = NULL;
bitmapTexture = SDL_CreateTextureFromSurface(this->renderer, bitmapSurface);
//Verify it exists
if (bitmapTexture == NULL)
cout << "Failed to create texture: " << fileName << endl;
return bitmapTexture;
}
Call Stack:
00000000()
SDL2_image.dll!6a887a01()
[Frames below may be incorrect and/or missing, no symbols loaded for SDL2_image.dll]
SDL2.dll!6c77da4b()
SDL2_image.dll!6a88792e()
SDL2_image.dll!6a881693()
SDL2_image.dll!6a8817e9()
> appname.exe!TextureManager::loadTexture(std::basic_string<char,std::char_traits<char>,std::allocator<char> > fileName) Line 143 + 0xe bytes C++
00daf5e0()
Here is the constructor for my TextureManager:
/**
* Creates a new TextureManager with the current SDL_Renderer
*
* #param renderer The current renderer instance of the current graphic window
*/
TextureManager::TextureManager(SDL_Renderer* renderer)
{
//Assign our renderer link
this->renderer = renderer;
//Create the vector to hold textures
this->textures = new vector<Texture*>();
//SDL_image initialization
int flags = IMG_INIT_JPG|IMG_INIT_PNG;
int initted = IMG_Init(flags); //Use IMG_Quit(); at closing
if(initted&flags != flags)
{
//Handle error
printf("IMG_Init: Failed to init required jpg and png support!\n");
printf("IMG_Init: %s\n", IMG_GetError());
}
else
{
cout << "SDL_Image initialized for JPEG and PNG support" << endl;
}
}
For your information, I am using Windows 10 x64, which is up to date. Graphics drivers for dual NVidia GTX 550ti are up to date as well.
All DLL files (including the pnglib dll) are in the debug folder and do load. If I remove the DLL file from the program, the image fails to load and provides the message as coded above for NULL surfaces. No exceptions occur.
Question summary:
Why is this exception thrown, why is it only thrown for PNG files, and how can I trace it when the call stack's details end at my call that appears to work properly? Am I doing something wrong, or is there a configuration step I may have missed?
EDIT: Thanks to #Nandu I have recompiled the DLL SDL_image, and got a better call stack output here:
00000000()
> SDL2_image.dll!IMG_LoadPNG_RW(SDL_RWops * src) Line 375 + 0x11 bytes C
SDL2_image.dll!IMG_LoadTyped_RW(SDL_RWops * src, int freesrc, const char * type) Line 193 + 0x12 bytes C
SDL2_image.dll!IMG_Load(const char * file) Line 134 + 0xf bytes C
appname.exe!TextureManager::loadTexture(std::basic_string<char,std::char_traits<char>,std::allocator<char> > fileName) Line 143 + 0xe bytes C++
appname.exe!TextureManager::loadFromDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > relPath) Line 117 + 0x73 bytes C++
appname.exe!SDL_main(int argc, char * * argv) Line 31 C++
appname.exe!main(int argc, char * * argv) Line 140 + 0xd bytes C
appname.exe!__tmainCRTStartup() Line 555 + 0x19 bytes C
appname.exe!mainCRTStartup() Line 371 C
kernel32.dll!77963744()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!77c3a064()
ntdll.dll!77c3a02f()
This suggests the problem is occurring on line 374 of IMG_png.c:
/* Create the PNG loading context structure */
png_ptr = lib.png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL,NULL,NULL);
VS reports that lib is NULL at this time, which would explain the error! The question becomes, why is it NULL? It seems this code should be doing a check for that, but nonetheless, nobody else seems to having this problem on the almighty internet.
Thank you all very much for you help, but the problem, as usual, was rather obvious!
As noted here by #Gigi: SDL_Image IMG_Load fails on png with: "Failed loading libpng16-16.dll:"
I suggest you try including all the rest - there may be a dependency that you and I are not aware of. In fact I just checked, and libpng requires zlib: libpng.org/pub/png/libpng.html
I'm not sure why my original search or suggestions didn't bring that post up.
I originally excluded the DLLs for other file formats I wasn't using (or initializing in my code), but once I included the zlib DLL, bingo. PNGs load exactly as expected.
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'm following these tutorials on modern OpenGL. I've done them up to number 15 "Camera Control - Part 2". The tutorial suggests using glutWarpPointer(). The problem is, my program crashes at that call. This is my code:
c_camera::c_camera(int width, int height, const c_vector3f& Pos, const c_vector3f& Target, const c_vector3f& Up){
m_windowWidth = width;
m_windowHeight = height;
m_pos = Pos;
m_target = Target;
m_target.Normalize();
m_up = Up;
m_up.Normalize();
Init();
}
void c_camera::Init(){
c_vector3f HTarget(m_target.x, 0.0, m_target.z);
HTarget.Normalize();
if (HTarget.z >= 0.0f){
if (HTarget.x >= 0.0f){
m_AngleH = 360.0f - (asin(HTarget.z) TO_DEG);
} else {
m_AngleH = 180.0f + (asin(HTarget.z) TO_DEG);
}
} else {
if (HTarget.x >= 0.0f){
m_AngleH = (asin(-HTarget.z) TO_DEG);
} else {
m_AngleH = 90.0f + (asin(-HTarget.z) TO_DEG);
}
}
m_AngleV = -(asin(m_target.y) TO_DEG);
m_OnUpperEdge = false;
m_OnLowerEdge = false;
m_OnLeftEdge = false;
m_OnRightEdge = false;
m_mousePos.x = m_windowWidth / 2;
m_mousePos.y = m_windowHeight / 2;
cout << "this gets printed just fine" << endl;
glutWarpPointer(500,400); //program crashes
cout << "this doesn't get printed" << endl;
}
I'm not sure if I'm doing something weird here, or if I just have a bad glut version (seems unlikely to me) or if the tutorial is just wrong... Do I need to set up something glut specific before I can call glutWarpPointer()? I am new to glut, and new to modern OpenGL (I learned immediate mode first).
A quick google search didn't help me much. Any help would be appreciated.
Edit: I am on windows, and I'm using mingw 4.5
Edit2: These are the details windows gives me about the crash:
Problem Event Name: APPCRASH
Application Name: modern_opengl.exe
Application Version: 0.0.0.0
Application Timestamp: 51044575
Fault Module Name: glut32.dll
Fault Module Version: 0.0.0.0
Fault Module Timestamp: 3bea4ff3
Exception Code: c0000005
Exception Offset: 0000a879
OS Version: 6.2.9200.2.0.0.256.48
Locale ID: 1043
Additional Information 1: 5861
Additional Information 2: 5861822e1919d7c014bbb064c64908b2
Additional Information 3: f3d5
Additional Information 4: f3d5be0cad2787556264647dc02181c3
Edit3: This is my call stack:
0 1000A879 glutWarpPointer() (C:\Windows\system\glut32.dll:??)
1 004033FB c_camera::Init(this=0x4aa0e0) (C:\CodeBlocks\projects\modern_opengl\c_camera.cpp:50)
2 00403164 c_camera::c_camera(this=0x4aa0e0, width=800, height=600, Pos=..., Target=..., Up=...) (C:\CodeBlocks\projects\modern_opengl\c_camera.cpp:18)
3 00402F4B __static_initialization_and_destruction_0(__initialize_p=1, __priority=65535) (C:\CodeBlocks\projects\modern_opengl\main.cpp:55)
4 00403004 GLOBAL_sub_I_vertices() (C:\CodeBlocks\projects\modern_opengl\main.cpp:177)
5 0043595B __do_global_ctors() (../mingw/gccmain.c:59)
6 00401098 __mingw_CRTStartup() (../mingw/crt1.c:236)
7 00401284 mainCRTStartup() (../mingw/crt1.c:264)
Your function seems to be in c_camera::Init, which seems to be called before main probably due to it being instantiated as a global object (globals are constructed before main is entered). You should delay glut calls till after you enter main and called glutInit is called.