Media Foundation onReadSample返回样本的大小错误 [英] Media Foundation onReadSample wrong size of returned sample

查看:362
本文介绍了Media Foundation onReadSample返回样本的大小错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力将捕获库从DirectShow转换为MediaFoundation。捕获库似乎运行良好但我在运行Windows 8 32位的平板电脑上遇到集成网络摄像头的问题。

I am working on translating a capture library from DirectShow to MediaFoundation. The capture library seemed to work quite well but I face a problem with an integrated webcam on a tablet running Windows 8 32 bit.

枚举捕获格式时(如 Media Foundation文档 ),我得到了以下支持的相机格式:

When enumerating the capture format (as explained in Media Foundation documentation), I got the following supported format for the camera:


  • 0:MFVideoFormat_NV12,分辨率:448x252,帧率:30000x1001

  • 1:MFVideoFormat_YUY2,分辨率:448x252,帧率:30000x1001

  • 2:MFVideoFormat_NV12,分辨率:640x360,帧率:30000x1001

  • 3:MFVideoFormat_YUY2,分辨率:640x360,帧率:30000x1001

  • 4:MFVideoFormat_NV12,分辨率:640x480,帧率:30000x1001

  • 5:MFVideoFormat_YUY2,分辨率: 640x480,帧率:30000x1001

  • 0 : MFVideoFormat_NV12, resolution : 448x252, framerate : 30000x1001
  • 1 : MFVideoFormat_YUY2, resolution : 448x252, framerate : 30000x1001
  • 2 : MFVideoFormat_NV12, resolution : 640x360, framerate : 30000x1001
  • 3 : MFVideoFormat_YUY2, resolution : 640x360, framerate : 30000x1001
  • 4 : MFVideoFormat_NV12, resolution : 640x480, framerate : 30000x1001
  • 5 : MFVideoFormat_YUY2, resolution : 640x480, framerate : 30000x1001

然后设置捕获格式,在本例中为在索引5处,使用以下函数,如示例中所述:

I then set the capture format, in this case the one at index 5, using the following function, as described in the example:

hr = pHandler->SetCurrentMediaType(pType);      

执行此函数时没有错误。因此,摄像机应配置为在YUY2中捕获,分辨率为640 * 480.

This function executed without error. The camera should thus be configured to capture in YUY2 with a resolution of 640*480.

In the onReadSample callback, I should receive a sample with a buffer of size :

640 * 480 * sizeof(unsigned char) * 2 =  614400 //YUY2 is encoded on 2 bytes

但是,我得到了一个大小为169344的缓冲区示例。下面是回调函数的一部分。

However, I got a sample with a buffer of size 169344. Here below is a part of the callback function.

HRESULT SourceReader::OnReadSample(
    HRESULT hrStatus,
    DWORD dwStreamIndex,
    DWORD dwStreamFlags,
    LONGLONG llTimeStamp,
    IMFSample *pSample      // Can be NULL
    )
{
    EnterCriticalSection(&m_critsec);

    if (pSample)
    {
        DWORD expectedBufferSize = 640*480*1*2; // = 614400 (hard code for the example)

        IMFMediaBuffer* buffer = NULL;
        hr = pSample->ConvertToContiguousBuffer(&buffer);
        if (FAILED(hr))
        {
            //...
            goto done;
        }

        DWORD byteLength = 0;
        BYTE* pixels = NULL;
        hr = buffer->Lock(&pixels, NULL, &byteLength);

        //byteLength is 169344 instead of 614400 
        if (byteLength > 0 && byteLength == expectedBufferSize)
        {
            //do someting with the image, but never comes here because byteLength is wrong
        }
        //...

为什么我得到169344号样本的任何建议?

Any advice why I get a sample of size 169344 ?

提前致谢

感谢Mgetz的回答。

Thanks Mgetz for your answer.

我检查了媒体类型的MF_MT_INTERLACE_MODE的值,看来视频流包含渐进帧。 MF_MT_INTERLACE_MODE的值返回MFVideoInterlace_Progressive。

I checked the value of MF_MT_INTERLACE_MODE of the media type and it appears that the video stream contains progressive frames. The value of MF_MT_INTERLACE_MODE returns MFVideoInterlace_Progressive.

hr = pHandler->SetCurrentMediaType(m_pType);
if(FAILED(hr)){
    //
}
else
{
    //get info about interlacing
    UINT32 interlaceFormat = MFVideoInterlace_Unknown;
    m_pType->GetUINT32(MF_MT_INTERLACE_MODE, &interlaceFormat);

    //...

因此视频流不是隔行扫描的。我在onReadSample中再次检查了MFSampleExtension_Interlaced的值,以查看样本是否是隔行扫描,并且看起来样本是隔行扫描的。

So the video stream is not interlaced. I checked again in the onReadSample the value of MFSampleExtension_Interlaced to see if the sample is interlaced or not and it appears that the sample is interlaced.

if (pSample && m_bCapture)
{
    //check if interlaced 
    UINT32 isSampleInterlaced = 0;
    pSample->GetUINT32(MFSampleExtension_Interlaced, &isSampleInterlaced);
    if(isSampleInterlaced)
    {
        //enters here
    }

流如何可能是渐进的并且样本是隔行扫描的?我在onReadSample回调中仔细检查了MF_MT_INTERLACE_MODE的值,它仍然给出了值MFT_INPUT_STREAM_WHOLE_SAMPLES。

How it is possible that the stream is progressive and that the sample is interlaced? I double checked the value of MF_MT_INTERLACE_MODE in the onReadSample callback as well and it still gives me the value MFT_INPUT_STREAM_WHOLE_SAMPLES.

关于你的第一个建议,我没有办法强制输入流上的标志MFT_INPUT_STREAM_WHOLE_SAMPLES。

Concerning your first suggestion, I didn't way to force the flag MFT_INPUT_STREAM_WHOLE_SAMPLES on the input stream.

提前致谢

我仍然面临这个问题我现在正在调查可用的不同流。

I still face the issue and I am now investigating on the different streams available.

根据文档,每个媒体源都提供了一个表示描述符,我们可以从中获取可用的流。要获取表示描述符,我们必须调用:

According to the documentation, each media source provides a presentation descriptor from which we can get the streams available. To get the presentation descriptor, we have to call:

HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);

然后我使用IMFPresentationDescriptor :: GetStreamDescriptorCount函数请求流可用:

I then request the streams available using the IMFPresentationDescriptor::GetStreamDescriptorCount function:

DWORD nbrStream;
pPD->GetStreamDescriptorCount(&nbrStream);

在运行Windows 8的ACER平板电脑上的正面网络摄像头上请求此信息时,我得到了三个流可用。我循环遍历这些流,请求他们的MediaTypeHandler并检查MajorType。这三个流具有主要类型:MFMediaType_Video,因此所有流都是视频流。列出不同流上可用的媒体类型时,我得到所有流支持640x480的捕获。 (某些流有更多可用的媒体类型)。

When requesting this information on the frontal webcam on an ACER tablet running windows 8, I got that three streams are available. I looped over these streams, requested their MediaTypeHandler and checked the MajorType. The three streams have for major type : MFMediaType_Video, so all the streams are video streams. When listing the media type available on the different streams, I got that all the streams support capture at 640x480. (some of the streams have more available media types).

我测试了选择每个不同的流和相应的格式类型(框架没有返回任何错误) ,但我仍然没有在回调函数中收到正确的样本...

I tested to select each of the different streams and the appropriate format type (the framework did not return any error), but I still do not receive the correct sample in the callback function...

有关该问题的进展建议吗?

Any advice to progress on the issue?

最后发现问题:我必须使用SourceReader-> SetCurrentMediaType(..)直接在源阅读器上设置媒体类型。这就行了!

Finally found the issue: I had to set the media type on the source reader directly, using SourceReader->SetCurrentMediaType(..). That did the trick!

感谢您的帮助!

推荐答案

终于找到了问题:我必须使用SourceReader-> SetCurrentMediaType(..)直接在源阅读器上设置媒体类型。这就行了!

Finally found the issue: I had to set the media type on the source reader directly, using SourceReader->SetCurrentMediaType(..). That did the trick!

感谢您的帮助!

这篇关于Media Foundation onReadSample返回样本的大小错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆