Implemented close method for CvCapture

Sometimes it is useful to release a resource BEFORE the garbage collection starts
This commit is contained in:
Dávid Halász 2016-04-08 13:35:40 +02:00
parent b90bd2dec4
commit 6fb0f00285
3 changed files with 50 additions and 6 deletions

View File

@ -27,8 +27,12 @@ rb_class()
void void
cvcapture_free(void *ptr) cvcapture_free(void *ptr)
{ {
if (ptr) if (ptr) {
cvReleaseCapture((CvCapture**)&ptr); sCvCapture* scap = (sCvCapture*)ptr;
if (scap->opened)
cvReleaseCapture(&scap->ptr);
delete scap;
}
} }
/* /*
@ -49,6 +53,7 @@ rb_open(int argc, VALUE *argv, VALUE self)
VALUE device; VALUE device;
rb_scan_args(argc, argv, "01", &device); rb_scan_args(argc, argv, "01", &device);
CvCapture *capture = 0; CvCapture *capture = 0;
sCvCapture *scap = new sCvCapture();
try { try {
switch (TYPE(device)) { switch (TYPE(device)) {
case T_STRING: case T_STRING:
@ -74,7 +79,27 @@ rb_open(int argc, VALUE *argv, VALUE self)
} }
if (!capture) if (!capture)
rb_raise(rb_eStandardError, "Invalid capture format."); rb_raise(rb_eStandardError, "Invalid capture format.");
return Data_Wrap_Struct(rb_klass, 0, cvcapture_free, capture); scap->ptr = capture;
scap->opened = true;
return Data_Wrap_Struct(rb_klass, 0, cvcapture_free, scap);
}
/*
* Releases an opened video file or a capturing device
* @return [boolean] False if the device was already closed
*/
VALUE
rb_close(VALUE self)
{
sCvCapture *scap;
Data_Get_Struct(self, sCvCapture, scap);
if (scap->opened) {
scap->opened = false;
cvReleaseCapture(&scap->ptr);
return true;
} else
return false;
} }
/* /*
@ -570,6 +595,7 @@ init_ruby_class()
rb_hash_aset(video_interface, ID2SYM(rb_intern("quicktime")), INT2FIX(CV_CAP_QT)); rb_hash_aset(video_interface, ID2SYM(rb_intern("quicktime")), INT2FIX(CV_CAP_QT));
rb_define_singleton_method(rb_klass, "open", RUBY_METHOD_FUNC(rb_open), -1); rb_define_singleton_method(rb_klass, "open", RUBY_METHOD_FUNC(rb_open), -1);
rb_define_method(rb_klass, "close", RUBY_METHOD_FUNC(rb_close), 0);
rb_define_method(rb_klass, "grab", RUBY_METHOD_FUNC(rb_grab), 0); rb_define_method(rb_klass, "grab", RUBY_METHOD_FUNC(rb_grab), 0);
rb_define_method(rb_klass, "retrieve", RUBY_METHOD_FUNC(rb_retrieve), 0); rb_define_method(rb_klass, "retrieve", RUBY_METHOD_FUNC(rb_retrieve), 0);

View File

@ -16,6 +16,12 @@
#define __NAMESPACE_END_CVCAPTURE } #define __NAMESPACE_END_CVCAPTURE }
__NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_OPENCV
typedef struct {
CvCapture* ptr;
bool opened;
} sCvCapture;
__NAMESPACE_BEGIN_CVCAPTURE __NAMESPACE_BEGIN_CVCAPTURE
@ -26,6 +32,8 @@ void init_ruby_class();
void cvcapture_free(void *ptr); void cvcapture_free(void *ptr);
VALUE rb_open(int argc, VALUE *argv, VALUE klass); VALUE rb_open(int argc, VALUE *argv, VALUE klass);
VALUE rb_close(VALUE self);
VALUE rb_grab(VALUE self); VALUE rb_grab(VALUE self);
VALUE rb_retrieve(VALUE self); VALUE rb_retrieve(VALUE self);
VALUE rb_query(VALUE self); VALUE rb_query(VALUE self);
@ -62,9 +70,11 @@ __NAMESPACE_END_CVCAPTURE
inline CvCapture* inline CvCapture*
CVCAPTURE(VALUE object) { CVCAPTURE(VALUE object) {
CvCapture *ptr; sCvCapture *scap;
Data_Get_Struct(object, CvCapture, ptr); Data_Get_Struct(object, sCvCapture, scap);
return ptr; if (!scap->opened)
rb_raise(rb_eIOError, "Resource is not available!");
return scap->ptr;
} }
__NAMESPACE_END_OPENCV __NAMESPACE_END_OPENCV

View File

@ -50,6 +50,14 @@ class TestCvCapture < OpenCVTestCase
# } # }
end end
def test_close
cap1 = CvCapture.open(AVI_SAMPLE)
cap1.close
assert_raise(IOError) do
cap1.query
end
end
def test_grab def test_grab
assert(@cap.grab) assert(@cap.grab)
end end