VideoCapture: add exception error mode similar to fstream + test

This commit is contained in:
Pavel Rojtberg 2018-06-12 15:21:33 +02:00
parent 64168fc20a
commit 15bb0b86ce
3 changed files with 59 additions and 7 deletions

View File

@ -782,9 +782,18 @@ public:
*/ */
CV_WRAP String getBackendName() const; CV_WRAP String getBackendName() const;
/** Switches exceptions mode
*
* methods raise exceptions if not successful instead of returning an error code
*/
CV_WRAP void setExceptionMode(bool enable) { throwOnFail = enable; }
/// query if exception mode is active
CV_WRAP bool getExceptionMode() { return throwOnFail; }
protected: protected:
Ptr<CvCapture> cap; Ptr<CvCapture> cap;
Ptr<IVideoCapture> icap; Ptr<IVideoCapture> icap;
bool throwOnFail;
}; };
class IVideoWriter; class IVideoWriter;

View File

@ -55,16 +55,16 @@ void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const { cvReleaseCap
void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const { cvReleaseVideoWriter(&obj); } void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const { cvReleaseVideoWriter(&obj); }
VideoCapture::VideoCapture() VideoCapture::VideoCapture() : throwOnFail(false)
{} {}
VideoCapture::VideoCapture(const String& filename, int apiPreference) VideoCapture::VideoCapture(const String& filename, int apiPreference) : throwOnFail(false)
{ {
CV_TRACE_FUNCTION(); CV_TRACE_FUNCTION();
open(filename, apiPreference); open(filename, apiPreference);
} }
VideoCapture::VideoCapture(int index, int apiPreference) VideoCapture::VideoCapture(int index, int apiPreference) : throwOnFail(false)
{ {
CV_TRACE_FUNCTION(); CV_TRACE_FUNCTION();
open(index, apiPreference); open(index, apiPreference);
@ -112,10 +112,13 @@ bool VideoCapture::open(const String& filename, int apiPreference)
CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create capture", info.name)); CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create capture", info.name));
} }
} catch(const cv::Exception& e) { } catch(const cv::Exception& e) {
if(throwOnFail && apiPreference != CAP_ANY) throw;
CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what())); CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what()));
} catch (const std::exception& e) { } catch (const std::exception& e) {
if(throwOnFail && apiPreference != CAP_ANY) throw;
CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what())); CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what()));
} catch(...) { } catch(...) {
if(throwOnFail && apiPreference != CAP_ANY) throw;
CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name)); CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name));
} }
} }
@ -126,6 +129,10 @@ bool VideoCapture::open(const String& filename, int apiPreference)
} }
} }
} }
if (throwOnFail)
CV_Error_(Error::StsError, ("could not open '%s'", filename.c_str()));
return false; return false;
} }
@ -176,10 +183,13 @@ bool VideoCapture::open(int cameraNum, int apiPreference)
CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create capture", info.name)); CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create capture", info.name));
} }
} catch(const cv::Exception& e) { } catch(const cv::Exception& e) {
if(throwOnFail && apiPreference != CAP_ANY) throw;
CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what())); CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what()));
} catch (const std::exception& e) { } catch (const std::exception& e) {
if(throwOnFail && apiPreference != CAP_ANY) throw;
CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what())); CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what()));
} catch(...) { } catch(...) {
if(throwOnFail && apiPreference != CAP_ANY) throw;
CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name)); CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name));
} }
} }
@ -190,6 +200,10 @@ bool VideoCapture::open(int cameraNum, int apiPreference)
} }
} }
} }
if(throwOnFail)
CV_Error_(Error::StsError, ("could not open camera %d", cameraNum));
return false; return false;
} }
@ -216,15 +230,22 @@ void VideoCapture::release()
bool VideoCapture::grab() bool VideoCapture::grab()
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
return !icap.empty() ? icap->grabFrame() : false; bool ret = !icap.empty() ? icap->grabFrame() : false;
if (!ret && throwOnFail)
CV_Error(Error::StsError, "");
return ret;
} }
bool VideoCapture::retrieve(OutputArray image, int channel) bool VideoCapture::retrieve(OutputArray image, int channel)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
bool ret = false;
if (!icap.empty()) if (!icap.empty())
return icap->retrieveFrame(channel, image); ret = icap->retrieveFrame(channel, image);
return false; if (!ret && throwOnFail)
CV_Error_(Error::StsError, ("could not retrieve channel %d", channel));
return ret;
} }
bool VideoCapture::read(OutputArray image) bool VideoCapture::read(OutputArray image)
@ -277,7 +298,10 @@ VideoCapture& VideoCapture::operator >> (UMat& image)
bool VideoCapture::set(int propId, double value) bool VideoCapture::set(int propId, double value)
{ {
CV_CheckNE(propId, (int)CAP_PROP_BACKEND, "Can't set read-only property"); CV_CheckNE(propId, (int)CAP_PROP_BACKEND, "Can't set read-only property");
return !icap.empty() ? icap->setProperty(propId, value) : false; bool ret = !icap.empty() ? icap->setProperty(propId, value) : false;
if (!ret && throwOnFail)
CV_Error_(Error::StsError, ("could not set prop %d = %f", propId, value));
return ret;
} }
double VideoCapture::get(int propId) const double VideoCapture::get(int propId) const

View File

@ -416,4 +416,23 @@ INSTANTIATE_TEST_CASE_P(videoio, videoio_synthetic,
testing::ValuesIn(all_sizes), testing::ValuesIn(all_sizes),
testing::ValuesIn(synthetic_params))); testing::ValuesIn(synthetic_params)));
TEST(Videoio, exceptions)
{
VideoCapture cap;
Mat mat;
EXPECT_FALSE(cap.grab());
EXPECT_FALSE(cap.retrieve(mat));
EXPECT_FALSE(cap.set(CAP_PROP_POS_FRAMES, 1));
EXPECT_FALSE(cap.open("this_does_not_exist.avi", CAP_OPENCV_MJPEG));
cap.setExceptionMode(true);
EXPECT_THROW(cap.grab(), Exception);
EXPECT_THROW(cap.retrieve(mat), Exception);
EXPECT_THROW(cap.set(CAP_PROP_POS_FRAMES, 1), Exception);
EXPECT_THROW(cap.open("this_does_not_exist.avi", CAP_OPENCV_MJPEG), Exception);
}
} // namespace } // namespace