Skip to content

VideoCapture fails to get frame if I use msmf and mp4 has audio stream.  #17400

@nakamura2000

Description

@nakamura2000
System information (version)
  • OpenCV => 4.3.0
  • Operating System / Platform => Windows 64 Bit
  • Compiler => Visual Studio 2019
Detailed description

if I use mp4 which has no audio stream (audio stream was removed with ffmpeg), no problem.

I used opencv of release windows module(4.3.0).
result of code is as follows.
sample files are attached.

[ 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)
[ WARN:0] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\cap_msmf.cpp (681) CvCapture_MSMF::initStream Failed to set mediaType (stream 0, (0x0 @ 1) MFVideoFormat_RGB32(unsupported media type)
ng
ok
Steps to reproduce
#include <stdio.h>
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
	cv::VideoCapture cap("sample-has-sound.mp4", cv::CAP_MSMF);
	cv::Mat image;
	if (cap.isOpened())
	{
		bool ret = cap.read(image);
		if (ret)
		{
			std::cout << "ok" << std::endl;
		}
		else
		{
			std::cout << "ng" << std::endl;
		}
	}
	cv::VideoCapture cap2("sample-no-sound.mp4", cv::CAP_MSMF);
	if (cap2.isOpened())
	{
		bool ret = cap2.read(image);
		if (ret)
		{
			std::cout << "ok" << std::endl;
		}
		else
		{
			std::cout << "ng" << std::endl;
		}
	}
} 

and I modified the code "cap_msmf.cpp" to pass only video types , it fixed;

   // class FormatStorage

    void read(IMFSourceReader* source)
    {
        HRESULT hr = S_OK;
        MediaID cur;
        GUID majorType;
        while (SUCCEEDED(hr))
        {
            _ComPtr<IMFMediaType> raw_type;
            hr = source->GetNativeMediaType(cur.stream, cur.media, &raw_type);
            if (hr == MF_E_NO_MORE_TYPES)
            {
                hr = S_OK;
                cur.nextStream();
            }
            else if (SUCCEEDED(hr))
            {
                raw_type.Get()->GetMajorType(&majorType);
                if (majorType == MFMediaType_Video)             // add this condition
                {
                    formats[cur] = MediaType(raw_type.Get());
                } 
                cur.nextMedia();
            }
        }
    }

samples.zip

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions