Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
4ac2c227
Commit
4ac2c227
authored
Aug 21, 2012
by
Andrey Kamaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix buffer allocation in Android camera
parent
a21df069
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
66 additions
and
68 deletions
+66
-68
cap_android.cpp
modules/highgui/src/cap_android.cpp
+66
-68
No files found.
modules/highgui/src/cap_android.cpp
View file @
4ac2c227
...
@@ -48,12 +48,15 @@
...
@@ -48,12 +48,15 @@
#include <android/log.h>
#include <android/log.h>
#include <camera_activity.hpp>
#include <camera_activity.hpp>
#if !defined(LOGD) && !defined(LOGI) && !defined(LOGE)
//#if !defined(LOGD) && !defined(LOGI) && !defined(LOGE)
#undef LOGD
#undef LOGE
#undef LOGI
#define LOG_TAG "CV_CAP"
#define LOG_TAG "CV_CAP"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#endif
//
#endif
class
HighguiAndroidCameraActivity
;
class
HighguiAndroidCameraActivity
;
...
@@ -86,8 +89,8 @@ protected:
...
@@ -86,8 +89,8 @@ protected:
//raw from camera
//raw from camera
int
m_width
;
int
m_width
;
int
m_height
;
int
m_height
;
unsigned
char
*
m_frameYUV420
;
cv
::
Mat
m_frameYUV420
;
unsigned
char
*
m_frameYUV420next
;
cv
::
Mat
m_frameYUV420next
;
enum
YUVformat
enum
YUVformat
{
{
...
@@ -115,9 +118,9 @@ private:
...
@@ -115,9 +118,9 @@ private:
bool
m_hasColor
;
bool
m_hasColor
;
enum
CvCapture_Android_DataState
{
enum
CvCapture_Android_DataState
{
CVCAPTURE_ANDROID_STATE_NO_FRAME
=
0
,
CVCAPTURE_ANDROID_STATE_NO_FRAME
=
0
,
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED
,
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED
,
CVCAPTURE_ANDROID_STATE_HAS_FRAME_GRABBED
CVCAPTURE_ANDROID_STATE_HAS_FRAME_GRABBED
};
};
volatile
CvCapture_Android_DataState
m_dataState
;
volatile
CvCapture_Android_DataState
m_dataState
;
...
@@ -189,8 +192,8 @@ CvCapture_Android::CvCapture_Android(int cameraId)
...
@@ -189,8 +192,8 @@ CvCapture_Android::CvCapture_Android(int cameraId)
m_height
=
0
;
m_height
=
0
;
m_activity
=
0
;
m_activity
=
0
;
m_isOpened
=
false
;
m_isOpened
=
false
;
m_frameYUV420
=
0
;
//
m_frameYUV420 = 0;
m_frameYUV420next
=
0
;
//
m_frameYUV420next = 0;
m_hasGray
=
false
;
m_hasGray
=
false
;
m_hasColor
=
false
;
m_hasColor
=
false
;
m_dataState
=
CVCAPTURE_ANDROID_STATE_NO_FRAME
;
m_dataState
=
CVCAPTURE_ANDROID_STATE_NO_FRAME
;
...
@@ -231,20 +234,19 @@ CvCapture_Android::~CvCapture_Android()
...
@@ -231,20 +234,19 @@ CvCapture_Android::~CvCapture_Android()
{
{
((
HighguiAndroidCameraActivity
*
)
m_activity
)
->
LogFramesRate
();
((
HighguiAndroidCameraActivity
*
)
m_activity
)
->
LogFramesRate
();
pthread_mutex_lock
(
&
m_nextFrameMutex
);
pthread_mutex_lock
(
&
m_nextFrameMutex
);
// unsigned char *tmp1=m_frameYUV420;
// unsigned char *tmp2=m_frameYUV420next;
unsigned
char
*
tmp1
=
m_frameYUV420
;
// m_frameYUV420 = 0;
unsigned
char
*
tmp2
=
m_frameYUV420next
;
// m_frameYUV420next = 0;
m_frameYUV420
=
0
;
// delete tmp1;
m_frameYUV420next
=
0
;
// delete tmp2;
delete
tmp1
;
delete
tmp2
;
m_dataState
=
CVCAPTURE_ANDROID_STATE_NO_FRAME
;
m_dataState
=
CVCAPTURE_ANDROID_STATE_NO_FRAME
;
pthread_cond_broadcast
(
&
m_nextFrameCond
);
pthread_cond_broadcast
(
&
m_nextFrameCond
);
pthread_mutex_unlock
(
&
m_nextFrameMutex
);
pthread_mutex_unlock
(
&
m_nextFrameMutex
);
//m_activity->disconnect() will be automatically called inside destructor;
//m_activity->disconnect() will be automatically called inside destructor;
delete
m_activity
;
delete
m_activity
;
...
@@ -257,7 +259,7 @@ CvCapture_Android::~CvCapture_Android()
...
@@ -257,7 +259,7 @@ CvCapture_Android::~CvCapture_Android()
double
CvCapture_Android
::
getProperty
(
int
propIdx
)
double
CvCapture_Android
::
getProperty
(
int
propIdx
)
{
{
switch
(
propIdx
)
switch
(
propIdx
)
{
{
case
CV_CAP_PROP_FRAME_WIDTH
:
case
CV_CAP_PROP_FRAME_WIDTH
:
return
(
double
)
m_activity
->
getFrameWidth
();
return
(
double
)
m_activity
->
getFrameWidth
();
...
@@ -308,7 +310,7 @@ bool CvCapture_Android::setProperty( int propIdx, double propValue )
...
@@ -308,7 +310,7 @@ bool CvCapture_Android::setProperty( int propIdx, double propValue )
m_activity
->
setProperty
(
ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT
,
propValue
);
m_activity
->
setProperty
(
ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT
,
propValue
);
break
;
break
;
case
CV_CAP_PROP_AUTOGRAB
:
case
CV_CAP_PROP_AUTOGRAB
:
m_shouldAutoGrab
=
(
propValue
!=
0
);
m_shouldAutoGrab
=
(
propValue
!=
0
);
break
;
break
;
case
CV_CAP_PROP_EXPOSURE
:
case
CV_CAP_PROP_EXPOSURE
:
m_activity
->
setProperty
(
ANDROID_CAMERA_PROPERTY_EXPOSURE
,
propValue
);
m_activity
->
setProperty
(
ANDROID_CAMERA_PROPERTY_EXPOSURE
,
propValue
);
...
@@ -327,13 +329,13 @@ bool CvCapture_Android::setProperty( int propIdx, double propValue )
...
@@ -327,13 +329,13 @@ bool CvCapture_Android::setProperty( int propIdx, double propValue )
break
;
break
;
default
:
default
:
CV_Error
(
CV_StsOutOfRange
,
"Failed attempt to SET unsupported camera property."
);
CV_Error
(
CV_StsOutOfRange
,
"Failed attempt to SET unsupported camera property."
);
return
false
;
return
false
;
}
}
if
(
propIdx
!=
CV_CAP_PROP_AUTOGRAB
)
{
// property for highgui class CvCapture_Android only
if
(
propIdx
!=
CV_CAP_PROP_AUTOGRAB
)
{
// property for highgui class CvCapture_Android only
m_CameraParamsChanged
=
true
;
m_CameraParamsChanged
=
true
;
}
}
res
=
true
;
res
=
true
;
}
}
return
res
;
return
res
;
...
@@ -342,8 +344,8 @@ bool CvCapture_Android::setProperty( int propIdx, double propValue )
...
@@ -342,8 +344,8 @@ bool CvCapture_Android::setProperty( int propIdx, double propValue )
bool
CvCapture_Android
::
grabFrame
()
bool
CvCapture_Android
::
grabFrame
()
{
{
if
(
!
isOpened
()
)
{
if
(
!
isOpened
()
)
{
LOGE
(
"CvCapture_Android::grabFrame(): camera is not opened"
);
LOGE
(
"CvCapture_Android::grabFrame(): camera is not opened"
);
return
false
;
return
false
;
}
}
bool
res
=
false
;
bool
res
=
false
;
...
@@ -352,38 +354,38 @@ bool CvCapture_Android::grabFrame()
...
@@ -352,38 +354,38 @@ bool CvCapture_Android::grabFrame()
{
{
m_activity
->
applyProperties
();
m_activity
->
applyProperties
();
m_CameraParamsChanged
=
false
;
m_CameraParamsChanged
=
false
;
m_dataState
=
CVCAPTURE_ANDROID_STATE_NO_FRAME
;
//we will wait new frame
m_dataState
=
CVCAPTURE_ANDROID_STATE_NO_FRAME
;
//we will wait new frame
}
}
if
(
m_dataState
!=
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED
)
{
if
(
m_dataState
!=
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED
)
m_waitingNextFrame
=
true
;
{
pthread_cond_wait
(
&
m_nextFrameCond
,
&
m_nextFrameMutex
);
m_waitingNextFrame
=
true
;
pthread_cond_wait
(
&
m_nextFrameCond
,
&
m_nextFrameMutex
);
}
}
if
(
m_dataState
==
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED
)
{
if
(
m_dataState
==
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED
)
//LOGD("CvCapture_Android::grabFrame: get new frame");
{
//swap current and new frames
//LOGD("CvCapture_Android::grabFrame: get new frame");
unsigned
char
*
tmp
=
m_frameYUV420
;
//swap current and new frames
m_frameYUV420
=
m_frameYUV420next
;
cv
::
swap
(
m_frameYUV420
,
m_frameYUV420next
);
m_frameYUV420next
=
tmp
;
//discard cached frames
//discard cached frames
m_hasGray
=
false
;
m_hasGray
=
false
;
m_hasColor
=
false
;
m_hasColor
=
false
;
m_dataState
=
CVCAPTURE_ANDROID_STATE_HAS_FRAME_GRABBED
;
m_dataState
=
CVCAPTURE_ANDROID_STATE_HAS_FRAME_GRABBED
;
m_framesGrabbed
++
;
m_framesGrabbed
++
;
res
=
true
;
res
=
true
;
}
else
{
}
else
{
LOGE
(
"CvCapture_Android::grabFrame: NO new frame"
);
LOGE
(
"CvCapture_Android::grabFrame: NO new frame"
);
}
}
int
res_unlock
=
pthread_mutex_unlock
(
&
m_nextFrameMutex
);
int
res_unlock
=
pthread_mutex_unlock
(
&
m_nextFrameMutex
);
if
(
res_unlock
)
{
if
(
res_unlock
)
{
LOGE
(
"Error in CvCapture_Android::grabFrame: pthread_mutex_unlock returned %d --- probably, this object has been destroyed"
,
res_unlock
);
LOGE
(
"Error in CvCapture_Android::grabFrame: pthread_mutex_unlock returned %d --- probably, this object has been destroyed"
,
res_unlock
);
return
false
;
return
false
;
}
}
return
res
;
return
res
;
...
@@ -393,7 +395,8 @@ IplImage* CvCapture_Android::retrieveFrame( int outputType )
...
@@ -393,7 +395,8 @@ IplImage* CvCapture_Android::retrieveFrame( int outputType )
{
{
IplImage
*
image
=
NULL
;
IplImage
*
image
=
NULL
;
unsigned
char
*
current_frameYUV420
=
m_frameYUV420
;
cv
::
Mat
m_frameYUV420_ref
=
m_frameYUV420
;
unsigned
char
*
current_frameYUV420
=
m_frameYUV420_ref
.
ptr
();
//Attention! all the operations in this function below should occupy less time than the period between two frames from camera
//Attention! all the operations in this function below should occupy less time than the period between two frames from camera
if
(
NULL
!=
current_frameYUV420
)
if
(
NULL
!=
current_frameYUV420
)
{
{
...
@@ -456,19 +459,9 @@ void CvCapture_Android::setFrame(const void* buffer, int bufferSize)
...
@@ -456,19 +459,9 @@ void CvCapture_Android::setFrame(const void* buffer, int bufferSize)
prepareCacheForYUV
(
width
,
height
);
prepareCacheForYUV
(
width
,
height
);
//copy data
//copy data
memcpy
(
m_frameYUV420next
,
buffer
,
bufferSize
);
cv
::
Mat
m_frameYUV420next_ref
=
m_frameYUV420next
;
//LOGD("CvCapture_Android::setFrame -- memcpy is done");
memcpy
(
m_frameYUV420next_ref
.
ptr
(),
buffer
,
bufferSize
);
LOGD
(
"CvCapture_Android::setFrame -- memcpy is done"
);
#if 0 //moved this part of code into grabFrame
//swap current and new frames
unsigned char* tmp = m_frameYUV420;
m_frameYUV420 = m_frameYUV420next;
m_frameYUV420next = tmp;
//discard cached frames
m_hasGray = false;
m_hasColor = false;
#endif
m_dataState
=
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED
;
m_dataState
=
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED
;
m_waitingNextFrame
=
false
;
//set flag that no more frames required at this moment
m_waitingNextFrame
=
false
;
//set flag that no more frames required at this moment
...
@@ -482,17 +475,22 @@ void CvCapture_Android::prepareCacheForYUV(int width, int height)
...
@@ -482,17 +475,22 @@ void CvCapture_Android::prepareCacheForYUV(int width, int height)
LOGD
(
"CvCapture_Android::prepareCacheForYUV: Changing size of buffers: from width=%d height=%d to width=%d height=%d"
,
m_width
,
m_height
,
width
,
height
);
LOGD
(
"CvCapture_Android::prepareCacheForYUV: Changing size of buffers: from width=%d height=%d to width=%d height=%d"
,
m_width
,
m_height
,
width
,
height
);
m_width
=
width
;
m_width
=
width
;
m_height
=
height
;
m_height
=
height
;
/*
unsigned char *tmp = m_frameYUV420next;
unsigned char *tmp = m_frameYUV420next;
m_frameYUV420next = new unsigned char [width * height * 3 / 2];
m_frameYUV420next = new unsigned char [width * height * 3 / 2];
if
(
tmp
!=
NULL
)
{
if (tmp != NULL)
delete
[]
tmp
;
{
}
delete[] tmp;
}
tmp = m_frameYUV420;
tmp = m_frameYUV420;
m_frameYUV420 = new unsigned char [width * height * 3 / 2];
m_frameYUV420 = new unsigned char [width * height * 3 / 2];
if
(
tmp
!=
NULL
)
{
if (tmp != NULL)
delete
[]
tmp
;
{
}
delete[] tmp;
}*/
m_frameYUV420
.
create
(
height
*
3
/
2
,
width
,
CV_8UC1
);
m_frameYUV420next
.
create
(
height
*
3
/
2
,
width
,
CV_8UC1
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment