MSMF can’t determine correct format when self-compiling vs using prebuilt binaries

System information (version)
  • OpenCV => 4.2, 8808aac
  • Operating System / Platform => Windows 10 64 Bit
  • Compiler => Visual Studio 2019
Detailed description

A simple test program to display a video feed that worked at 4de7015 no longer works at 8808aac:

[ WARN:0] global D:\lib\opencv\modules\videoio\src\cap_msmf.cpp (686) CvCapture_MSMF::initStream Failed to set mediaType (stream 0, (0x0 @ 1) (HRESULT -2147024809)
OpenCV(4.2.0-dev) Error: Assertion failed (!_src.empty()) in cv::cvtColor, file D:\lib\opencv\modules\imgproc\src\color.cpp, line 182

In CvCapture_MSMF::configureOutput, I get bestMatch = ({stream=0 media=0 }, {width=0 height=0 stride=0 ...}) which causes the assertion later on in the program. Previously with prebuilt libraries, the format was:

    +		cv::IVideoCapture	{...}	opencv_world420d.dll!cv::IVideoCapture
    		MF	{...}	opencv_world420d.dll!`anonymous-namespace'::Media_Foundation &
    +		filename	""	opencv_world420d.dll!std::string
    		camid	0	int
    		captureMode	MODE_HW (1)	opencv_world420d.dll!CvCapture_MSMF::MSMFCapture_Mode
    +		D3DDev	{p={0x000001e71836e9f8 <Information not available, no symbols loaded for d3d11.dll>} }	opencv_world420d.dll!`anonymous-namespace'::ComPtr<ID3D11Device>
    +		D3DMgr	{p={0x000001e717eca580 <Information not available, no symbols loaded for mfplat.dll>} }	opencv_world420d.dll!`anonymous-namespace'::ComPtr<IMFDXGIDeviceManager>
    +		videoFileSource	{p={0x000001e71c56d260 <Information not available, no symbols loaded for mfreadwrite.dll>} }	opencv_world420d.dll!`anonymous-namespace'::ComPtr<IMFSourceReader>
    		dwStreamIndex	0	unsigned long
    +		nativeFormat	{MF_MT_FRAME_SIZE=1280000 height=800 width=1600 ...}	opencv_world420d.dll!`anonymous-namespace'::MediaType
    +		captureFormat	{MF_MT_FRAME_SIZE=1280000 height=800 width=1600 ...}	opencv_world420d.dll!`anonymous-namespace'::MediaType
    		outputFormat	861030210	unsigned int
    		requestedWidth	640	unsigned int
    		requestedHeight	480	unsigned int
    		convertFormat	true	bool
    		aspectN	1	unsigned int
    		aspectD	1	unsigned int
    		duration	0	__int64
    		frameStep	166666	__int64
    +		videoSample	{p={0x000001e71c58c1f0 <Information not available, no symbols loaded for mfplat.dll>} }	opencv_world420d.dll!`anonymous-namespace'::ComPtr<IMFSample>
    		sampleTime	0	__int64
    		isOpen	true	bool
    +		readCallback	{p={0x000001e7165c3130 {m_nRefCount=4 m_mutex=unlocked m_hEvent=0x00000000000007d8 ...}} }	opencv_world420d.dll!`anonymous-namespace'::ComPtr<IMFSourceReaderCallback>
Steps to reproduce
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp>
#include <iostream>
#include <thread>


static void read_config(const char* filename, cv::Mat &cameraMatrix, cv::Mat &distCoeffs)
{
    cv::FileStorage fs(filename, cv::FileStorage::READ);
    if (!fs.isOpened())
    {
        std::cout << "Could not open the configuration file: \"" << filename << "\"" << std::endl;
        return;
    }

    fs["camera_matrix"] >> cameraMatrix;
    fs["distortion_coefficients"] >> distCoeffs;
}

int main(int argc, char** argv)
{
    cv::VideoCapture video(0);

    cv::Mat frame;
    cv::Mat temp;

    cv::Mat cameraMatrix_L, distCoeffs_L;
    read_config("index_left_cropped.xml", cameraMatrix_L, distCoeffs_L);

    cv::Mat cameraMatrix_R, distCoeffs_R;
    read_config("index_right_cropped.xml", cameraMatrix_R, distCoeffs_R);
    
    cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE); // Create a window for display.
    while (true)
    {
        if (!video.read(frame))
            continue;

        /*
        cv::undistort(frame(cv::Rect(0, 0, 800, 800)), temp, cameraMatrix_L, distCoeffs_L);
        temp.copyTo(frame(cv::Rect(0, 0, 800, 800)));

        cv::undistort(frame(cv::Rect(800, 0, 800, 800)), temp, cameraMatrix_R, distCoeffs_R);
        temp.copyTo(frame(cv::Rect(800, 0, 800, 800)));
        */

        cv::imshow("Display window", frame); // Show our image inside it.
        char c = (char)cv::waitKey(16); // Wait for a keystroke in the window
        if (c == 27)
            break;
    }
    

    
    return 0;
}

1 possible answer(s) on “MSMF can’t determine correct format when self-compiling vs using prebuilt binaries