7 #include "Vision/AxisCamera.h"
10 #include "NetworkCommunication/UsageReporting.h"
11 #include "Synchronized.h"
12 #include "Vision/PCVideoServer.h"
13 #include "WPIErrors.h"
16 IMAQ_FUNC
int Priv_ReadJPEGString_C(Image* _image,
const unsigned char* _string, uint32_t _stringLength);
19 #define kMaxPacketSize 1536
20 #define kImageBufferAllocationIncrement 1000
27 AxisCamera::AxisCamera(
const char *ipAddress)
29 , m_cameraSocket(ERROR)
30 , m_protectedImageBuffer(NULL)
31 , m_protectedImageBufferLength(0)
32 , m_protectedImageSize(0)
33 , m_protectedImageSem(NULL)
35 , m_imageStreamTask(
"cameraTask", (FUNCPTR)s_ImageStreamTaskFunction)
38 m_protectedImageSem = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
40 #if JAVA_CAMERA_LIB != 1
41 nUsageReporting::report(nUsageReporting::kResourceType_AxisCamera, ipAddress == NULL ? 1 : 2);
45 m_imageStreamTask.Start((
int)
this);
56 m_imageStreamTask.
Stop();
57 close(m_cameraSocket);
59 SemSet_t::iterator it = m_newImageSemSet.begin();
60 SemSet_t::iterator end = m_newImageSemSet.end();
61 for (;it != end; it++)
65 m_newImageSemSet.clear();
67 semDelete(m_protectedImageSem);
77 if (NULL == _instance)
115 SEM_ID sem = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY);
116 m_newImageSemSet.insert(sem);
128 if (m_protectedImageBuffer == NULL)
131 Priv_ReadJPEGString_C(imaqImage,
132 (
unsigned char*)m_protectedImageBuffer, m_protectedImageSize);
133 m_freshImage =
false;
137 #if JAVA_CAMERA_LIB != 1
175 if (destImage == NULL)
176 wpi_setWPIErrorWithContext(NullParameter,
"destImage must not be NULL");
178 if (m_protectedImageBuffer == NULL || m_protectedImageSize <= 0)
181 if (destImageBufferSize < m_protectedImageSize)
183 if (*destImage != NULL)
delete [] *destImage;
184 destImageBufferSize = m_protectedImageSize + kImageBufferAllocationIncrement;
185 *destImage =
new char[destImageBufferSize];
186 if (*destImage == NULL)
return 0;
189 if (*destImage == NULL)
191 wpi_setWPIErrorWithContext(NullParameter,
"*destImage must not be NULL");
194 memcpy(*destImage, m_protectedImageBuffer, m_protectedImageSize);
195 destImageSize = m_protectedImageSize;
203 int AxisCamera::s_ImageStreamTaskFunction(
AxisCamera *thisPtr)
205 return thisPtr->ImageStreamTaskFunction();
213 int AxisCamera::ImageStreamTaskFunction()
219 const char *requestString =
"GET /mjpg/video.mjpg HTTP/1.1\n\
220 User-Agent: HTTPStreamClient\n\
221 Connection: Keep-Alive\n\
222 Cache-Control: no-cache\n\
223 Authorization: Basic RlJDOkZSQw==\n\n";
224 semTake(m_socketPossessionSem, WAIT_FOREVER);
225 m_cameraSocket = CreateCameraSocket(requestString);
226 if (m_cameraSocket == ERROR)
229 semGive(m_socketPossessionSem);
234 ReadImagesFromCamera();
243 int AxisCamera::ReadImagesFromCamera()
245 char *imgBuffer = NULL;
246 int imgBufferLength = 0;
257 char initialReadBuffer[kMaxPacketSize] =
"";
258 char intermediateBuffer[1];
259 char *trailingPtr = initialReadBuffer;
260 int trailingCounter = 0;
264 if(recv(m_cameraSocket, intermediateBuffer, 1, 0) == ERROR)
266 wpi_setErrnoErrorWithContext(
"Failed to read image header");
267 close (m_cameraSocket);
270 strncat(initialReadBuffer, intermediateBuffer, 1);
274 if (NULL != strstr(trailingPtr,
"\r\n\r\n"))
278 if (++trailingCounter >= 4)
284 char *contentLength = strstr(initialReadBuffer,
"Content-Length: ");
285 if (contentLength == NULL)
287 wpi_setWPIErrorWithContext(IncompatibleMode,
"No content-length token found in packet");
288 close(m_cameraSocket);
291 contentLength = contentLength + 16;
292 int readLength = atol(contentLength);
295 if (imgBufferLength < readLength)
297 if (imgBuffer)
delete[] imgBuffer;
298 imgBufferLength = readLength + kImageBufferAllocationIncrement;
299 imgBuffer =
new char[imgBufferLength];
300 if (imgBuffer == NULL)
309 int remaining = readLength;
310 while(bytesRead < readLength)
312 int bytesThisRecv = recv(m_cameraSocket, &imgBuffer[bytesRead], remaining, 0);
313 bytesRead += bytesThisRecv;
314 remaining -= bytesThisRecv;
317 UpdatePublicImageFromCamera(imgBuffer, readLength);
318 if (semTake(m_paramChangedSem, NO_WAIT) == OK)
321 close(m_cameraSocket);
322 semGive(m_socketPossessionSem);
333 void AxisCamera::UpdatePublicImageFromCamera(
char *imgBuffer,
int imgSize)
339 if (m_protectedImageBufferLength < imgSize)
341 if (m_protectedImageBuffer != NULL)
delete [] m_protectedImageBuffer;
342 m_protectedImageBufferLength = imgSize + kImageBufferAllocationIncrement;
343 m_protectedImageBuffer =
new char[m_protectedImageBufferLength];
344 if (m_protectedImageBuffer == NULL)
346 m_protectedImageBufferLength = 0;
351 memcpy(m_protectedImageBuffer, imgBuffer, imgSize);
352 m_protectedImageSize = imgSize;
357 SemSet_t::iterator it = m_newImageSemSet.begin();
358 SemSet_t::iterator end = m_newImageSemSet.end();
359 for (;it != end; it++)
368 void AxisCamera::RestartCameraTask()
370 m_imageStreamTask.
Stop();
371 m_imageStreamTask.
Start((
int)
this);
374 #if JAVA_CAMERA_LIB == 1
379 void AxisCameraStart(
const char *IPAddress)
384 printf(
"JavaCameraLib was compiled from SVN revision %s\n", SVN_REV);
388 printf(
"JavaCameraLib was compiled from a location that is not source controlled.\n");
391 printf(
"JavaCameraLib was compiled without -D'SVN_REV=nnnn'\n");
396 int AxisCameraGetImage (Image* image)
401 void AxisCameraWriteBrightness(
int brightness)
406 int AxisCameraGetBrightness()
411 void AxisCameraWriteWhiteBalance(AxisCameraParams::WhiteBalance_t whiteBalance)
416 AxisCameraParams::WhiteBalance_t AxisCameraGetWhiteBalance()
421 void AxisCameraWriteColorLevel(
int colorLevel)
426 int AxisCameraGetColorLevel()
431 void AxisCameraWriteExposureControl(AxisCameraParams::Exposure_t exposure)
436 AxisCameraParams::Exposure_t AxisCameraGetExposureControl()
441 void AxisCameraWriteExposurePriority(
int exposure)
446 int AxisCameraGetExposurePriority()
451 void AxisCameraWriteMaxFPS(
int maxFPS)
456 int AxisCameraGetMaxFPS()
461 void AxisCameraWriteResolution(AxisCameraParams::Resolution_t resolution)
466 AxisCameraParams::Resolution_t AxisCameraGetResolution()
471 void AxisCameraWriteCompression(
int compression)
476 int AxisCameraGetCompression()
481 void AxisCameraWriteRotation(AxisCameraParams::Rotation_t rotation)
486 AxisCameraParams::Rotation_t AxisCameraGetRotation()
491 void AxisCameraDeleteInstance()
496 int AxisCameraFreshImage()
501 #endif // JAVA_CAMERA_LIB == 1
void WriteExposurePriority(int)
int CopyJPEG(char **destImage, int &destImageSize, int &destImageBufferSize)
int GetImage(Image *imaqImage)
bool Start(uint32_t arg0=0, uint32_t arg1=0, uint32_t arg2=0, uint32_t arg3=0, uint32_t arg4=0, uint32_t arg5=0, uint32_t arg6=0, uint32_t arg7=0, uint32_t arg8=0, uint32_t arg9=0)
void WriteCompression(int)
Resolution_t GetResolution()
void WriteBrightness(int)
static void DeleteInstance()
void WriteExposureControl(Exposure_t)
Exposure_t GetExposureControl()
WhiteBalance_t GetWhiteBalance()
void WriteResolution(Resolution_t)
void WriteWhiteBalance(WhiteBalance_t whiteBalance)
void WriteColorLevel(int)
static AxisCamera & GetInstance(const char *cameraIP=NULL)
void WriteRotation(Rotation_t)