From eb981cc7d7011f60a7a8dd03b9db9cd2dcdd8596 Mon Sep 17 00:00:00 2001 From: wanghanmin Date: Fri, 26 Oct 2018 00:41:37 +0800 Subject: [PATCH] Merge pull request #12138 from wanghanmin:wanghanmin-patch-videoio_crossbarsetting-1 * Update videoio.hpp add VideoCapturePropertie for clossbar input pin setting * Update cap_dshow.cpp For some kind of capture card, such as "avermedia cv710 " , it use SerialDigital as input pin and so it can not work. Here added new PhysicalConnectorType enumeration: PhysConn_Video_YRYBY and PhysConn_Video_SerialDigital to support it. And also provide new property parameter CAP_CROSSBAR_INPIN_TYPE to set the crossbar input pin type which will be used in videoInput::start(int deviceID, videoDevice *VD): " if(VD->useCrossbar) { DebugPrintOut("SETUP: Checking crossbar\n"); routeCrossbar(&VD->pCaptureGraph, &VD->pVideoInputFilter, VD->connection, CAPTURE_MODE); } " And at last ,fixed one issue for function setSizeAndSubtype, added code pVih->rcSource.top = pVih->rcSource.left = pVih->rcTarget.top =pVih->rcTarget.left=0; pVih->rcSource.right = pVih->rcTarget.right= attemptWidth; pVih->rcSource.bottom = pVih->rcTarget.bottom = attemptHeight; without these code , rcSource and rcTarget will keeping use default resolution and cause fail in hr = VD->streamConf->SetFormat(VD->pAmMediaType) and cannot find suitable MediaType. Tested with python3 and mfc (Avermedia cv710) Python3 code: import cv2 print("test cv") cap=cv2.VideoCapture(0) cap.set(5,60) cap.set(3,1920) cap.set(4,1080) cap.set(31,6) ret,img=cap.read() cv2.namedWindow("cap",cv2.WINDOW_NORMAL) cv2.resizeWindow("cap",960,640); while True: ret,img=cap.read() if ret==False: continue cv2.imshow("cap",img) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() MFC code: void CcvtestDlg::OnBnClickedButton1() { VideoCapture cap(0); cap.set(CAP_PROP_FRAME_WIDTH, 1920); cap.set(CAP_PROP_FRAME_HEIGHT, 1080); cap.set(CAP_CROSSBAR_INPIN_TYPE , 6); Mat img; namedWindow("test", WINDOW_NORMAL); resizeWindow("test", 960, 640); while (1) { if (cap.read(img)) { imshow("test", img); if ('q' ==waitKey(1)) break; } } destroyAllWindows(); cap.release(); } * Update cap_dshow.cpp * Update videoio.hpp move enum value of CAP_CROSSBAR_INPIN_TYPE to the end of list * Update videoio.hpp * Update cap_dshow.cpp removed trailing whitespace * Update test_camera.cpp Add test for capture device using PhysConn_Video_SerialDigital as crossbar input pin * Update test_camera.cpp Correction of misunderstanding about how to add test case. --- modules/videoio/include/opencv2/videoio.hpp | 1 + modules/videoio/src/cap_dshow.cpp | 17 ++++++++++++ modules/videoio/test/test_camera.cpp | 29 +++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/modules/videoio/include/opencv2/videoio.hpp b/modules/videoio/include/opencv2/videoio.hpp index 54f42fd9a8..d0ec8a7c82 100644 --- a/modules/videoio/include/opencv2/videoio.hpp +++ b/modules/videoio/include/opencv2/videoio.hpp @@ -170,6 +170,7 @@ enum VideoCaptureProperties { CAP_PROP_SAR_NUM =40, //!< Sample aspect ratio: num/den (num) CAP_PROP_SAR_DEN =41, //!< Sample aspect ratio: num/den (den) CAP_PROP_BACKEND =42, //!< current backend (enum VideoCaptureAPIs). Read-only property + CAP_CROSSBAR_INPIN_TYPE =43, //!connection = PhysConn_Video_1394; break; + case 5: + VDList[id]->connection = PhysConn_Video_YRYBY; + break; + case 6: + VDList[id]->connection = PhysConn_Video_SerialDigital; + break; default: return; //if it is not these types don't set crossbar break; @@ -2449,6 +2455,9 @@ static bool setSizeAndSubtype(videoDevice * VD, int attemptWidth, int attemptHei //width and height HEADER(pVih)->biWidth = attemptWidth; HEADER(pVih)->biHeight = attemptHeight; + pVih->rcSource.top = pVih->rcSource.left = pVih->rcTarget.top =pVih->rcTarget.left=0; + pVih->rcSource.right = pVih->rcTarget.right= attemptWidth; + pVih->rcSource.bottom = pVih->rcTarget.bottom = attemptHeight; VD->pAmMediaType->formattype = FORMAT_VideoInfo; VD->pAmMediaType->majortype = MEDIATYPE_Video; @@ -3269,6 +3278,14 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal) handled = true; break; + case CAP_CROSSBAR_INPIN_TYPE: + + if (cvFloor(propVal) < 0) + break; + g_VI.stopDevice(m_index); + g_VI.setupDevice(m_index, cvFloor(propVal)); + break; + case CV_CAP_PROP_FPS: { int fps = cvRound(propVal); diff --git a/modules/videoio/test/test_camera.cpp b/modules/videoio/test/test_camera.cpp index 9a7e266846..ef66dca8d9 100644 --- a/modules/videoio/test/test_camera.cpp +++ b/modules/videoio/test/test_camera.cpp @@ -38,4 +38,33 @@ TEST(DISABLED_VideoIO_Camera, basic) capture.release(); } +//Following test if for capture device using PhysConn_Video_SerialDigital as crossbar input pin +TEST(DISABLED_VideoIO_Camera, dshow_avermedia_capture) +{ + VideoCapture capture(0); + ASSERT_TRUE(capture.isOpened()); + capture.set(CAP_CROSSBAR_INPIN_TYPE, 6); + std::cout << "Camera 0 via " << capture.getBackendName() << " backend" << std::endl; + std::cout << "Frame width: " << capture.get(CAP_PROP_FRAME_WIDTH) << std::endl; + std::cout << " height: " << capture.get(CAP_PROP_FRAME_HEIGHT) << std::endl; + std::cout << "Capturing FPS: " << capture.get(CAP_PROP_FPS) << std::endl; + + const int N = 100; + Mat frame; + int64 time0 = cv::getTickCount(); + for (int i = 0; i < N; i++) + { + SCOPED_TRACE(cv::format("frame=%d", i)); + + capture >> frame; + ASSERT_FALSE(frame.empty()); + + EXPECT_GT(cvtest::norm(frame, NORM_INF), 0) << "Complete black image has been received"; + } + int64 time1 = cv::getTickCount(); + printf("Processed %d frames on %.2f FPS\n", N, (N * cv::getTickFrequency()) / (time1 - time0 + 1)); + + capture.release(); +} + }} // namespace