Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

CvCapture_MSMF::initStream Failed to set mediaType after switching to CUDA build of OpenCV

Yesterday I got set up with OpenCV (precompiled libraries for windows) and everything was working great! I had a little program that would read a video feed from my Valve Index, undistort each lens, and then display it back. It was super slow though, so I looked into using CUDA to speed it up and found that the precompiled libraries didn't include CUDA support. So I followed the tutorial for CMake and git-bash, and used this slightly modified build script:

#!/bin/bash -e
myRepo=$(pwd)
CMAKE_CONFIG_GENERATOR="Visual Studio 16 2019"
if [  ! -d "$myRepo/opencv"  ]; then
    echo "cloning opencv"
    git clone https://github.com/opencv/opencv.git
    mkdir -p Build/opencv
    mkdir -p Install/opencv
else
    cd opencv
    git pull --rebase
    cd ..
fi
if [  ! -d "$myRepo/opencv_contrib"  ]; then
    echo "cloning opencv_contrib"
    git clone https://github.com/opencv/opencv_contrib.git
    mkdir -p Build/opencv_contrib
else
    cd opencv_contrib
    git pull --rebase
    cd ..
fi
RepoSource=opencv
pushd Build/$RepoSource
CMAKE_OPTIONS='-DBUILD_PERF_TESTS:BOOL=OFF -DBUILD_TESTS:BOOL=OFF -DBUILD_DOCS:BOOL=OFF  -DWITH_CUDA:BOOL=ON -DBUILD_EXAMPLES:BOOL=OFF -DINSTALL_CREATE_DISTRIB=ON'
cmake -A "x64" -G"$CMAKE_CONFIG_GENERATOR" $CMAKE_OPTIONS -DOPENCV_EXTRA_MODULES_PATH="$myRepo"/opencv_contrib/modules -DCMAKE_INSTALL_PREFIX="$myRepo"/install/"$RepoSource" "$myRepo/$RepoSource"
echo "************************* $Source_DIR -->debug"
cmake --build .  --config debug
echo "************************* $Source_DIR -->release"
cmake --build .  --config release
cmake --build .  --target install --config release
cmake --build .  --target install --config debug
popd

Things I modified: I changed the config generator to Visual Studio 16 2019, I added -A x64 to build on that architecture, and I changed -DWITH_CUDA:BOOL=OFF to -DWITH_CUDA:BOOL=ON.

It took over 6 hours (guess it was only using one thread) but I finally got everything set up and switched my OPENCV_DIR over. But now my simple program no longer works! Working output with precompiled libaries:

[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\videoio_registry.cpp (187) cv::`anonymous-namespace'::VideoBackendRegistry::VideoBackendRegistry VIDEOIO: Enabled backends(7, sorted by priority): FFMPEG(1000); GSTREAMER(990); INTEL_MFX(980); MSMF(970); DSHOW(960); CV_IMAGES(950); CV_MJPEG(940)
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (353) cv::impl::getPluginCandidates Found 2 plugin(s) for GSTREAMER
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load D:\opencv\build\x64\vc15\bin\opencv_videoio_gstreamer420_64.dll => FAILED
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load opencv_videoio_gstreamer420_64.dll => FAILED

Output with self-compiled CUDA libaries:

[ INFO:0] global D:\lib\opencv\modules\videoio\src\videoio_registry.cpp (187) cv::`anonymous-namespace'::VideoBackendRegistry::VideoBackendRegistry VIDEOIO: Enabled backends(7, sorted by priority): FFMPEG(1000); GSTREAMER(990); INTEL_MFX(980); MSMF(970); DSHOW(960); CV_IMAGES(950); CV_MJPEG(940)
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (353) cv::impl::getPluginCandidates Found 2 plugin(s) for GSTREAMER
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load D:\lib\Install\opencv\x64\vc16\bin\opencv_videoio_gstreamer420_64.dll => FAILED
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load opencv_videoio_gstreamer420_64.dll => FAILED
[ 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

The video source can't be read, so the dimensions are set to 0x0 which triggers an assert later on. Debugging the video capture initialization, it looks like it's only considering 3 backends: GSTREAMER, MSMF, and DSHOW. I don't have DLLs for GSTREAMER so I assume that won't work. MSMF passed the test, but not before issuing the initStream warning. It looks like CvCapture_MSMF::configureOutput is the culprit, formats.findBest returns the 0x0 invalid format.

Here's my test program:

#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;
}

Is MSMF just not compatibile with my video source? Is there a way I can get it to use FFmpeg (preferably without going through the 6+ hour recompile)?

CvCapture_MSMF::initStream Failed to set mediaType after switching to CUDA build of OpenCV

Yesterday I got set up with OpenCV (precompiled libraries for windows) and everything was working great! I had a little program that would read a video feed from my Valve Index, undistort each lens, and then display it back. It was super slow though, so I looked into using CUDA to speed it up and found that the precompiled libraries didn't include CUDA support. So I followed the tutorial for CMake and git-bash, and used this slightly modified build script:

#!/bin/bash -e
myRepo=$(pwd)
CMAKE_CONFIG_GENERATOR="Visual Studio 16 2019"
if [  ! -d "$myRepo/opencv"  ]; then
    echo "cloning opencv"
    git clone https://github.com/opencv/opencv.git
    mkdir -p Build/opencv
    mkdir -p Install/opencv
else
    cd opencv
    git pull --rebase
    cd ..
fi
if [  ! -d "$myRepo/opencv_contrib"  ]; then
    echo "cloning opencv_contrib"
    git clone https://github.com/opencv/opencv_contrib.git
    mkdir -p Build/opencv_contrib
else
    cd opencv_contrib
    git pull --rebase
    cd ..
fi
RepoSource=opencv
pushd Build/$RepoSource
CMAKE_OPTIONS='-DBUILD_PERF_TESTS:BOOL=OFF -DBUILD_TESTS:BOOL=OFF -DBUILD_DOCS:BOOL=OFF  -DWITH_CUDA:BOOL=ON -DBUILD_EXAMPLES:BOOL=OFF -DINSTALL_CREATE_DISTRIB=ON'
cmake -A "x64" -G"$CMAKE_CONFIG_GENERATOR" $CMAKE_OPTIONS -DOPENCV_EXTRA_MODULES_PATH="$myRepo"/opencv_contrib/modules -DCMAKE_INSTALL_PREFIX="$myRepo"/install/"$RepoSource" "$myRepo/$RepoSource"
echo "************************* $Source_DIR -->debug"
cmake --build .  --config debug
echo "************************* $Source_DIR -->release"
cmake --build .  --config release
cmake --build .  --target install --config release
cmake --build .  --target install --config debug
popd

Things I modified: I changed the config generator to Visual Studio 16 2019, I added -A x64 to build on that architecture, and I changed -DWITH_CUDA:BOOL=OFF to -DWITH_CUDA:BOOL=ON.

It took over 6 hours (guess it was only using one thread) but I finally got everything set up and switched my OPENCV_DIR over. But now my simple program no longer works! Working output with precompiled libaries:

[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\videoio_registry.cpp (187) cv::`anonymous-namespace'::VideoBackendRegistry::VideoBackendRegistry VIDEOIO: Enabled backends(7, sorted by priority): FFMPEG(1000); GSTREAMER(990); INTEL_MFX(980); MSMF(970); DSHOW(960); CV_IMAGES(950); CV_MJPEG(940)
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (353) cv::impl::getPluginCandidates Found 2 plugin(s) for GSTREAMER
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load D:\opencv\build\x64\vc15\bin\opencv_videoio_gstreamer420_64.dll => FAILED
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load opencv_videoio_gstreamer420_64.dll => FAILED

Output with self-compiled CUDA libaries:

[ INFO:0] global D:\lib\opencv\modules\videoio\src\videoio_registry.cpp (187) cv::`anonymous-namespace'::VideoBackendRegistry::VideoBackendRegistry VIDEOIO: Enabled backends(7, sorted by priority): FFMPEG(1000); GSTREAMER(990); INTEL_MFX(980); MSMF(970); DSHOW(960); CV_IMAGES(950); CV_MJPEG(940)
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (353) cv::impl::getPluginCandidates Found 2 plugin(s) for GSTREAMER
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load D:\lib\Install\opencv\x64\vc16\bin\opencv_videoio_gstreamer420_64.dll => FAILED
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load opencv_videoio_gstreamer420_64.dll => FAILED
[ 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

The video source can't be read, so the dimensions are set to 0x0 which triggers an assert later on. Debugging the video capture initialization, it looks like it's only considering 3 backends: GSTREAMER, MSMF, and DSHOW. I don't have DLLs for GSTREAMER so I assume that won't work. MSMF passed the test, but not before issuing the initStream warning. It looks like CvCapture_MSMF::configureOutput is the culprit, formats.findBest returns the 0x0 invalid format.

Here's my test program:Upon closer inspection, the precompiled libraries also use MSMF, so it's not that I don't have FFmpeg or anything. The CvCapture instance is as such:

#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 +       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 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 available, no symbols loaded 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 d3d11.dll>} }  opencv_world420d.dll!`anonymous-namespace'::ComPtr<ID3D11Device>
+       D3DMgr  {p={0x000001e717eca580 <Information not available, no symbols loaded for a keystroke in the window
        if (c == 27)
            break;
    }



    return 0;
}
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>

Is So somewhere along the way MSMF just not compatibile with my video source? Is there a way I can get it lost the ability to use FFmpeg (preferably without going through the 6+ hour recompile)?determine the correct format.

CvCapture_MSMF::initStream Failed to set mediaType after switching to CUDA build of OpenCV

Yesterday I got set up with OpenCV (precompiled libraries for windows) and everything was working great! I had a little program that would read a video feed from my Valve Index, undistort each lens, and then display it back. It was super slow though, so I looked into using CUDA to speed it up and found that the precompiled libraries didn't include CUDA support. So I followed the tutorial for CMake and git-bash, and used this slightly modified build script:

#!/bin/bash -e
myRepo=$(pwd)
CMAKE_CONFIG_GENERATOR="Visual Studio 16 2019"
if [  ! -d "$myRepo/opencv"  ]; then
    echo "cloning opencv"
    git clone https://github.com/opencv/opencv.git
    mkdir -p Build/opencv
    mkdir -p Install/opencv
else
    cd opencv
    git pull --rebase
    cd ..
fi
if [  ! -d "$myRepo/opencv_contrib"  ]; then
    echo "cloning opencv_contrib"
    git clone https://github.com/opencv/opencv_contrib.git
    mkdir -p Build/opencv_contrib
else
    cd opencv_contrib
    git pull --rebase
    cd ..
fi
RepoSource=opencv
pushd Build/$RepoSource
CMAKE_OPTIONS='-DBUILD_PERF_TESTS:BOOL=OFF -DBUILD_TESTS:BOOL=OFF -DBUILD_DOCS:BOOL=OFF  -DWITH_CUDA:BOOL=ON -DBUILD_EXAMPLES:BOOL=OFF -DINSTALL_CREATE_DISTRIB=ON'
cmake -A "x64" -G"$CMAKE_CONFIG_GENERATOR" $CMAKE_OPTIONS -DOPENCV_EXTRA_MODULES_PATH="$myRepo"/opencv_contrib/modules -DCMAKE_INSTALL_PREFIX="$myRepo"/install/"$RepoSource" "$myRepo/$RepoSource"
echo "************************* $Source_DIR -->debug"
cmake --build .  --config debug
echo "************************* $Source_DIR -->release"
cmake --build .  --config release
cmake --build .  --target install --config release
cmake --build .  --target install --config debug
popd

Things I modified: I changed the config generator to Visual Studio 16 2019, I added -A x64 to build on that architecture, and I changed -DWITH_CUDA:BOOL=OFF to -DWITH_CUDA:BOOL=ON.

It took over 6 hours (guess it was only using one thread) but I finally got everything set up and switched my OPENCV_DIR over. But now my simple program no longer works! Working output with precompiled libaries:works!

[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\videoio_registry.cpp (187) cv::`anonymous-namespace'::VideoBackendRegistry::VideoBackendRegistry VIDEOIO: Enabled backends(7, sorted by priority): FFMPEG(1000); GSTREAMER(990); INTEL_MFX(980); MSMF(970); DSHOW(960); CV_IMAGES(950); CV_MJPEG(940)
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (353) cv::impl::getPluginCandidates Found 2 plugin(s) for GSTREAMER
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load D:\opencv\build\x64\vc15\bin\opencv_videoio_gstreamer420_64.dll => FAILED
[ INFO:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load opencv_videoio_gstreamer420_64.dll => FAILED

Output with self-compiled CUDA libaries:

[ INFO:0] global D:\lib\opencv\modules\videoio\src\videoio_registry.cpp (187) cv::`anonymous-namespace'::VideoBackendRegistry::VideoBackendRegistry VIDEOIO: Enabled backends(7, sorted by priority): FFMPEG(1000); GSTREAMER(990); INTEL_MFX(980); MSMF(970); DSHOW(960); CV_IMAGES(950); CV_MJPEG(940)
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (353) cv::impl::getPluginCandidates Found 2 plugin(s) for GSTREAMER
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load D:\lib\Install\opencv\x64\vc16\bin\opencv_videoio_gstreamer420_64.dll => FAILED
[ INFO:0] global D:\lib\opencv\modules\videoio\src\backend_plugin.cpp (172) cv::impl::DynamicLib::libraryLoad load opencv_videoio_gstreamer420_64.dll => FAILED
[ 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

The video source can't be read, so the dimensions are set to 0x0 which triggers an assert later on. Debugging the video capture initialization, it looks like it's only considering 3 backends: GSTREAMER, MSMF, and DSHOW. I don't have DLLs for GSTREAMER so I assume that won't work. MSMF passed the test, but not before issuing the initStream warning. It looks like CvCapture_MSMF::configureOutput is the culprit, formats.findBest returns the 0x0 invalid format.

Upon closer inspection, inspection it looks like the precompiled libraries also use MSMF, so it's not that I don't have FFmpeg or anything. The CvCapture instance is as such:and it reads the format correctly:

+       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>

So somewhere along the way way, MSMF lost the its ability to determine the correct format.format for my video source. Does anybody know what went wrong?

CvCapture_MSMF::initStream Failed to set mediaType after switching to CUDA build of OpenCV

Yesterday I got set up with OpenCV (precompiled libraries for windows) and everything was working great! I had a little program that would read a video feed from my Valve Index, undistort each lens, and then display it back. It was super slow though, so I looked into using CUDA to speed it up and found that the precompiled libraries didn't include CUDA support. So I followed the tutorial for CMake and git-bash, and used this slightly modified build script:

#!/bin/bash -e
myRepo=$(pwd)
CMAKE_CONFIG_GENERATOR="Visual Studio 16 2019"
if [  ! -d "$myRepo/opencv"  ]; then
    echo "cloning opencv"
    git clone https://github.com/opencv/opencv.git
    mkdir -p Build/opencv
    mkdir -p Install/opencv
else
    cd opencv
    git pull --rebase
    cd ..
fi
if [  ! -d "$myRepo/opencv_contrib"  ]; then
    echo "cloning opencv_contrib"
    git clone https://github.com/opencv/opencv_contrib.git
    mkdir -p Build/opencv_contrib
else
    cd opencv_contrib
    git pull --rebase
    cd ..
fi
RepoSource=opencv
pushd Build/$RepoSource
CMAKE_OPTIONS='-DBUILD_PERF_TESTS:BOOL=OFF -DBUILD_TESTS:BOOL=OFF -DBUILD_DOCS:BOOL=OFF  -DWITH_CUDA:BOOL=ON -DBUILD_EXAMPLES:BOOL=OFF -DINSTALL_CREATE_DISTRIB=ON'
cmake -A "x64" -G"$CMAKE_CONFIG_GENERATOR" $CMAKE_OPTIONS -DOPENCV_EXTRA_MODULES_PATH="$myRepo"/opencv_contrib/modules -DCMAKE_INSTALL_PREFIX="$myRepo"/install/"$RepoSource" "$myRepo/$RepoSource"
echo "************************* $Source_DIR -->debug"
cmake --build .  --config debug
echo "************************* $Source_DIR -->release"
cmake --build .  --config release
cmake --build .  --target install --config release
cmake --build .  --target install --config debug
popd

Things I modified: I changed the config generator to Visual Studio 16 2019, I added -A x64 to build on that architecture, and I changed -DWITH_CUDA:BOOL=OFF to -DWITH_CUDA:BOOL=ON.

It took over 6 hours (guess it was only using one thread) but I finally got everything set up and switched my OPENCV_DIR over. But now my simple program no longer works!

[ 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

The video source can't be read, so the dimensions are set to 0x0 which triggers an assert later on. Debugging the video capture initialization, it looks like it's only considering 3 backends: GSTREAMER, MSMF, and DSHOW. I don't have DLLs for GSTREAMER so I assume that won't work. MSMF passed the test, but not before issuing the initStream warning. It looks like CvCapture_MSMF::configureOutput is the culprit, formats.findBest returns the 0x0 invalid format.

Upon closer inspection it looks like the precompiled libraries also use MSMF, and it reads the format correctly:

+       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>

So somewhere along the way, MSMF lost its ability to determine the correct format for my video source. Does anybody know what went wrong?

CvCapture_MSMF::initStream Failed to set mediaType after switching to CUDA build of OpenCV

Yesterday I got set up with OpenCV (precompiled libraries for windows) and everything was working great! I had a little program that would read a video feed from my Valve Index, undistort each lens, and then display it back. It was super slow though, so I looked into using CUDA to speed it up and found that the precompiled libraries didn't include CUDA support. So I followed the tutorial for CMake and git-bash, and used this slightly modified build script:

#!/bin/bash -e
myRepo=$(pwd)
CMAKE_CONFIG_GENERATOR="Visual Studio 16 2019"
if [  ! -d "$myRepo/opencv"  ]; then
    echo "cloning opencv"
    git clone https://github.com/opencv/opencv.git
    mkdir -p Build/opencv
    mkdir -p Install/opencv
else
    cd opencv
    git pull --rebase
    cd ..
fi
if [  ! -d "$myRepo/opencv_contrib"  ]; then
    echo "cloning opencv_contrib"
    git clone https://github.com/opencv/opencv_contrib.git
    mkdir -p Build/opencv_contrib
else
    cd opencv_contrib
    git pull --rebase
    cd ..
fi
RepoSource=opencv
pushd Build/$RepoSource
CMAKE_OPTIONS='-DBUILD_PERF_TESTS:BOOL=OFF -DBUILD_TESTS:BOOL=OFF -DBUILD_DOCS:BOOL=OFF  -DWITH_CUDA:BOOL=ON -DBUILD_EXAMPLES:BOOL=OFF -DINSTALL_CREATE_DISTRIB=ON'
cmake -A "x64" -G"$CMAKE_CONFIG_GENERATOR" $CMAKE_OPTIONS -DOPENCV_EXTRA_MODULES_PATH="$myRepo"/opencv_contrib/modules -DCMAKE_INSTALL_PREFIX="$myRepo"/install/"$RepoSource" "$myRepo/$RepoSource"
echo "************************* $Source_DIR -->debug"
cmake --build .  --config debug
echo "************************* $Source_DIR -->release"
cmake --build .  --config release
cmake --build .  --target install --config release
cmake --build .  --target install --config debug
popd

Things I modified: I changed the config generator to Visual Studio 16 2019, I added -A x64 to build on that architecture, and I changed -DWITH_CUDA:BOOL=OFF to -DWITH_CUDA:BOOL=ON.

It took over 6 hours (guess it was only using one thread) but I finally got everything set up and switched my OPENCV_DIR over. But now my simple program no longer works!

[ 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

The video source can't be read, so the dimensions are set to 0x0 which triggers an assert later on. Debugging the video capture initialization, it looks like it's only considering 3 backends: GSTREAMER, MSMF, and DSHOW. I don't have DLLs for GSTREAMER so I assume that won't work. MSMF passed the test, but not before issuing the initStream warning. It looks like CvCapture_MSMF::configureOutput is the culprit, formats.findBest returns the 0x0 invalid format.

Upon closer inspection it looks like the precompiled libraries also use MSMF, and it reads the format correctly:

+       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>

So somewhere along the way, MSMF lost its ability to determine the correct format for my video source. Does anybody know what went wrong?