Black screen using DirectShow SDK on PS3eye usb camera - camera

I just figured out the problem that DirectShow cannot detect PS3eye camera when another problem comes to me.
It was tested that the PS3eye camera can be read by AMcap and by OpenCV using constructor VideoCapture cap(1). When I tried to use function QueryFrame() to grab frames from camera and show it in computer, it returned me a black screen. The codes are as following:
IplImage* CCameraDS::QueryFrame()
{
HRESULT hr;
if (!m_IsOpen)
{
return NULL;
}
long evCode;
long size = 0;
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
if (SUCCEEDED(hr)) {
hr = m_pMediaControl->Run();
if (FAILED(hr))
m_pMediaControl->Stop();
m_pMediaControl->Release();
}
else {
printf("Cannot preview graph.\n");
return false;
}
m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);
m_pSampleGrabber->GetCurrentBuffer(&size, NULL);
//if the buffer size changed
if (size != m_nBufferSize)
{
if (m_pFrame)
cvReleaseImage(&m_pFrame);
m_nBufferSize = size;
m_pFrame = cvCreateImage(cvSize(m_nWidth, m_nHeight), IPL_DEPTH_8U, 3);
}
if (m_pFrame->imageData == NULL)
{
return 0;
}
hr = m_pSampleGrabber->GetCurrentBuffer(&m_nBufferSize, (long*)m_pFrame->imageData);
if (FAILED(hr))
return NULL;
cvFlip(m_pFrame);
return m_pFrame;
}
What's the problem? Am I missing something?

Related

DirectShow cannot detect PS3eye

I'm trying to use a PS3eye camera on Windows 10 with DirectShow sdk.
I've installed the driver and tested in AMCap that the PS3eye is working.
When in VS 2015, I defined a CCameraDS class with a function called CameraCount(), but when I call this function it always returns me 1 which represents the EasyCamera of my laptop. Am I missing something?
int CCameraDS::CameraCount()
{
int count = 0;
CoInitialize(NULL);
// enumerate all video capture devices
ICreateDevEnum *pCreateDevEnum = 0;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
IEnumMoniker *pEm = 0;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
if (hr != NOERROR)
{
return count;
}
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
count++;
}
pCreateDevEnum = NULL;
pEm = NULL;
return count;
}
To verify, I have another method called CameraName(),
int CCameraDS::CameraName(int nCamID, char* sName, int nBufferSize)
{
int count = 0;
CoInitialize(NULL);
// enumerate all video capture devices
ICreateDevEnum *pCreateDevEnum = 0;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
IEnumMoniker *pEm = 0;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
if (hr != NOERROR) return 0;
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
if (count == nCamID)
{
IPropertyBag *pBag=0;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if(hr == NOERROR)
{
WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,sName, nBufferSize ,"",NULL);
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
break;
}
count++;
}
pCreateDevEnum = NULL;
pEm = NULL;
return 1;
}
When I input 0, I have EasyCamera returned, but input 1 with nothing output. Where is the problem?
Problem solved.
In fact, the PS3eye driver as well as AMCap software are both compiled under x86 environment, since I used x64 environment, the driver wasn't working I think.
I didn't expect this to be the solution but it does solve the problem.

How can I write code to receive whole string from a device on rs232?

I want to know how to write code which receives specific string.for example, this one OK , in this I only need "OK" string.
Another string is also like OK
I have written code in keil c51 for at89s52 microcontroller which works but I need more reliable code.
I'm using interrupt for rx data from rs232 serial.
void _esp8266_getch() interrupt 4 //UART Rx.{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
else
{
count=0;
do
{
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data1) //rx_data1 = 0X0D /CR
{
RI=0;
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data2) // rx_data2 = 0x0A /LF
{
RI=0;
data_in_buffer=1;
if(loop_conti==1)
{
if(rec_bit_flag==1)
{
data_in_buffer=0;
loop_conti=0;
}
}
}
}
else
{
if(data_in_buffer==1)
{
received[count]=rx_buff; //my buffer in which storing string
rec_bit_flag=1;
count++;
loop_conti=1;
RI=0;
}
else
{
loop_conti=0;
rec_bit_flag=0;
RI=0;
}
}
}
while(loop_conti==1);
}
rx_buff=0;
}
This is one is just for reference, you need develop the logic further to your needs. Moreover, design is depends on what value is received, is there any specific pattern and many more parameter. And this is not a tested code, I tried to give my idea on design, with this disclaimer here is the sample..
//Assuming you get - "OK<CR><LF>" in which <CR><LF> indicates the end of string steam
int nCount =0;
int received[2][BUF_SIZE]; //used only 2 buffers, you can use more than 2, depending on how speed
//you receive and how fast you process it
int pingpong =0;
bool bRecFlag = FALSE;
int nNofbytes = 0;
void _esp8266_getch() interrupt 4 //UART Rx.
{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
if(RI) // Rx interrupt
{
received[pingpong][nCount]=SBUF;
RI =0;
if(nCount > 0)
{
// check if you receive end of stream value
if(received[pingpong][nCount-1] == 0x0D) && (received[pingpong][nCount] == 0x0A))
{
bRecFlag = TRUE;
pingpong = (pingpong == 0);
nNofbytes = nCount;
nCount = 0;
return;
}
}
nCount++;
}
return;
}
int main()
{
// other stuff
while(1)
{
// other stuff
if(bRecFlag) //String is completely received
{
buftouse = pingpong ? 0 : 1; // when pingpong is 1, buff 0 will have last complete string
// when pingpong is 0, buff 1 will have last complete string
// copy to other buffer or do action on received[buftouse][]
bRecFlag = false;
}
// other stuff
}
}

How do I register for a notification for then the sound volume changes?

I need my app to be notified when the OS X sound volume has changed. This is for a Desktop app, not for iOS. How can I register for this notification?
This can be a tiny bit tricky because some audio devices support a master channel, but most don't so the volume will be a per-channel property. Depending on what you need to do you could observe only one channel and assume that all other channels the device supports have the same volume. Regardless of how many channels you want to watch, you observe the volume by registering a property listener for the AudioObject in question:
// Some devices (but not many) support a master channel
AudioObjectPropertyAddress propertyAddress = {
kAudioDevicePropertyVolumeScalar,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
if(AudioObjectHasProperty(deviceID, &propertyAddress)) {
OSStatus result = AudioObjectAddPropertyListener(deviceID, &propertyAddress, myAudioObjectPropertyListenerProc, self);
// Error handling omitted
}
else {
// Typically the L and R channels are 1 and 2 respectively, but could be different
propertyAddress.mElement = 1;
OSStatus result = AudioObjectAddPropertyListener(deviceID, &propertyAddress, myAudioObjectPropertyListenerProc, self);
// Error handling omitted
propertyAddress.mElement = 2;
result = AudioObjectAddPropertyListener(deviceID, &propertyAddress, myAudioObjectPropertyListenerProc, self);
// Error handling omitted
}
Your listener proc should be something like:
static OSStatus
myAudioObjectPropertyListenerProc(AudioObjectID inObjectID,
UInt32 inNumberAddresses,
const AudioObjectPropertyAddress inAddresses[],
void *inClientData)
{
for(UInt32 addressIndex = 0; addressIndex < inNumberAddresses; ++addressIndex) {
AudioObjectPropertyAddress currentAddress = inAddresses[addressIndex];
switch(currentAddress.mSelector) {
case kAudioDevicePropertyVolumeScalar:
{
Float32 volume = 0;
UInt32 dataSize = sizeof(volume);
OSStatus result = AudioObjectGetPropertyData(inObjectID, &currentAddress, 0, NULL, &dataSize, &volume);
if(kAudioHardwareNoError != result) {
// Handle the error
continue;
}
// Process the volume change
break;
}
}
}
}

SDL_image's IMG_Load do not work

I am using IMG_Load() to load png file, but it simply not working.
loadedImage = IMG_Load(filename.c_str()); after this sentence, loadedImage is still NULL,not error happened.
PS:I am using VS C++2008, png file is in the develop folder. Here is my code:(It is exactly what Lazy Foo like)
//The headers
#include "SDL.h"
#include "SDL_image.h"
#include <string>
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
//The surfaces
SDL_Surface *image = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *load_image( std::string filename )
{
//The image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image using SDL_image
loadedImage = IMG_Load(filename.c_str());
//If the image loaded
if( loadedImage != NULL )
{
//Create an optimized image
//cout<<"Flag";
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old image
SDL_FreeSurface( loadedImage );
}
//Return the optimized image
return optimizedImage;
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
//Rectangle to hold the offsets
SDL_Rect offset;
//Get offsets
offset.x = x;
offset.y = y;
//Blit the surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
bool init()
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}
//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//If there was an error in setting up the screen
if( screen == NULL )
{
return false;
}
//Set the window caption
SDL_WM_SetCaption( "PNG test", NULL );
//If everything initialized fine
return true;
}
void clean_up()
{
//Free the surface
SDL_FreeSurface( image );
//Quit SDL
SDL_Quit();
}
int main( int argc, char* args[] )
{
//Initialize
if( init() == false )
{
return 1;
}
//Load the image
image = load_image( "look.png" );
//If there was a problem in loading the image
if( image == NULL )
{
return 5;
}
//Apply the surface to the screen
apply_surface( 0, 0, image, screen );
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
//Wait 2 seconds
SDL_Delay( 2000 );
//Free the surface and quit SDL
clean_up();
return 0;
}
The output return 5.
my bad.
I just copy SDL_image.dll to exe floder.
I should also copy zlib1.dll and libpng12-0.dll
Actually, all the dll is need, because if there is not such dll, the program won't give any error prompt, which is confusing.
If you download libpng from the website, you will find a file called libpng12.dll. Copying that file into system32 does not work, because SDL_image actually looks for a file called "libpng12-0.dll". I found that out after having implemented the IMG_GetError() method in my code. The error message says it very clearly...
So what you do is copying libpng12.dll to system32 and rename it to libpng12-0.dll! And everything works just fine.

how to use ICLRStrongName in .NET 4?

Related to my previous posts I'm moving to .NET 4. I've found that using the previous StrongName.h to get my assembly signing key in unmanaged code is now deprecated, and I need to use MetaHost.h and ICLRStrongName::StrongNameTokenFromAssembly.
The previous StrongNameTokenFromAssembly(..) was very straight forward, now this new one has no documentation on how to use. Does anyone have experience with this interface?
Wow... that required a lot of hacking around. Here we go!
ICLRMetaHost *pMetaHost = NULL;
HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost,
IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
if(hr == S_OK)
{
WCHAR version[100];
DWORD size;
hr == pMetaHost->GetVersionFromFile(MyGetApplicationExecutablePath().c_str(), (LPWSTR) &version, &size);
if(hr == S_OK)
{
LPWSTR assemblyVer = version;
ICLRRuntimeInfo *pRuntimInfo = NULL;
hr = pMetaHost->GetRuntime(assemblyVer, IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimInfo);
if (hr == S_OK)
{
ICLRStrongName *pStrongName = NULL;
hr = pRuntimInfo->GetInterface(CLSID_CLRStrongName, IID_ICLRStrongName, (LPVOID*)&pStrongName);
if(hr == S_OK)
{
pStrongName->StrongNameTokenFromAssembly(MyGetApplicationExecutablePath().c_str(), &token, &len);
DWORD verified = 0;
BOOLEAN sigVerified = pStrongName->StrongNameSignatureVerification(MyGetApplicationExecutablePath().c_str(), SN_INFLAG_FORCE_VER , &verified);
if (!verified)
{
//Do something nasty here if the Signature verification failed
}
pStrongName->StrongNameFreeBuffer(token);
}
}
}
}