Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 媒体基金会设置视频交织和解码_C++_Decoding_Ms Media Foundation_Mov_Interlacing - Fatal编程技术网

C++ 媒体基金会设置视频交织和解码

C++ 媒体基金会设置视频交织和解码,c++,decoding,ms-media-foundation,mov,interlacing,C++,Decoding,Ms Media Foundation,Mov,Interlacing,我有一个MOV文件,我想解码它,并将所有帧作为单独的图像 因此,我尝试以下列方式配置未压缩的媒体类型: // configure the source reader IMFSourceReader* m_pReader; MFCreateSourceReaderFromURL(filePath, NULL, &m_pReader); // get the compressed media type IMFMediaType* pFileVideoMediaType; m_pReader

我有一个MOV文件,我想解码它,并将所有帧作为单独的图像

因此,我尝试以下列方式配置未压缩的媒体类型:

// configure the source reader
IMFSourceReader* m_pReader;
MFCreateSourceReaderFromURL(filePath, NULL, &m_pReader);

// get the compressed media type
IMFMediaType* pFileVideoMediaType;
m_pReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pFileVideoMediaType);

// create new media type for uncompressed type
IMFMediaType* pTypeUncomp;
MFCreateMediaType(&pTypeUncomp);

// copy all settings from compressed to uncompressed type
pFileVideoMediaType->CopyAllItems(pTypeUncomp);

// set the uncompressed video attributes
pTypeUncomp->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB8);
pTypeUncomp->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
pTypeUncomp->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);

// set the new uncompressed type to source reader
m_pReader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, pTypeUncomp);

// get the full uncompressed media type
m_pReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pTypeUncomp);
我注意到,即使我明确地将
MF\u MT\u INTERLACE\u模式
设置为
MFVideoInterlace\u Progressive
最终配置仍然使用旧模式
MFVideoInterlace\u mixedinterlace或Progressive

之后,我循环浏览所有样本并查看它们的大小:

IMFSample* videoSample = nullptr;
IMFMediaBuffer* mbuffer = nullptr;
LONGLONG llTimeStamp;
DWORD streamIndex, flags;

m_pReader->ReadSample(
            MF_SOURCE_READER_FIRST_VIDEO_STREAM,
            0,                               // Flags.
            &streamIndex,                    // Receives the actual stream index. 
            &flags,                          // Receives status flags.
            &llTimeStamp,                    // Receives the time stamp.
            &videoSample)                    // Receives the sample or NULL.

videoSample->ConvertToContiguousBuffer(&mbuffer);

BYTE* videoData = nullptr;
DWORD sampleBufferLength = 0;

mbuffer->Lock(&videoData, nullptr, &sampleBufferLength);
cout << sampleBufferLength << endl;
IMFSample*videoSample=nullptr;
IMFMediaBuffer*mbuffer=nullptr;
隆隆时间戳;
德沃德河流指数,旗帜;
m_pReader->ReadSample(
MF\u源\u读卡器\u第一个\u视频\u流,
0,//标志。
&streamIndex,//接收实际的流索引。
&标志,//接收状态标志。
&llTimeStamp,//接收时间戳。
&videoSample)//接收样本或为空。
视频采样->转换到连续缓冲区(&mbuffer);
字节*videoData=nullptr;
DWORD sampleBufferLength=0;
mbuffer->Lock(&videoData、nullptr和sampleBufferLength);

cout为了使SourceReader将样本转换为RGB,您需要如下创建它:

IMFAttributes* pAttr = NULL;
MFCreateAttributes(&pAttr, 1);
pAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);
pAttr->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE);
    
IMFSourceReader* m_pReader;
throwIfFailed(MFCreateSourceReaderFromURL(filePath, pAttr, &m_pReader), Can't create source reader from url");
pAttr->Release();
稍后,当MF\u SOURCE\u READERF\u CURRENTMEDIATYPECHANGED发生时,您不应该中断循环。现在,您将拥有相同大小的所有样品。
否则,您可以使用MFVideoFormat\u NV12子类型,然后在创建读取器时不需要指定MF\u SOURCE\u READER\u ENABLE\u VIDEO\u PROCESSING属性。

也许您应该尝试先调用GetNativeMediaType,而不是m\u Preder->GetCurrentMediaType(MF\u SOURCE\u READER\u first\u VIDEO\u STREAM,&pFileVideoMediaType);。您是否还检查了每个样本是否交错:pSample->GetUINT32(MFSampleExtension\u交错,&isSampleInterlaced);您可以在此处检查ConfigureDecoder函数:。调用ReadSample时,您还可以在接收状态标志中检查MF\u SOURCE\u READERF\u CURRENTMEDIATYPECHANGED,以查看类型是否已更改。@VuVirt,谢谢您的评论。获取本机媒体类型不会改变任何内容。检查样本的隔行扫描结果出现错误。媒体类型没有改变。你还有别的想法吗?如果你能抽出几分钟来看看我的代码:。非常感谢您的帮助。请尝试不使用ptypeumpc->CopyAllItems。只需使用所有必要的属性手动构建未压缩的视频媒体类型,如本链接所示:您不应该为子类型设置MFVideoFormat_Base。试试MFVideoFormat_RGB32。对我有用。非常感谢。让我再问你一个问题。对于一些文件,我得到的buffersize与图像heightwidth*4完全匹配,并且数据是正确的。对于其他一些文件,我得到的缓冲区大小大于heightwidth*4。你知道这些额外的数据代表什么吗?VuVirt,我看到了你的答案,非常好。正如您所说,我试图将IMFSample锁定为2D数据,但最终出现了一个错误。您还可以分享一段代码,演示如何使用2D正确锁定和访问示例数据吗?谢谢你advance@mbaros什么错误?有些样品不暴露IMF2DBuffer。在这种情况下,您可能需要直接锁定IMFMediaBuffer。或查询D3D纹理。按照另一个答案中的链接,有足够的源代码和解释开始。至于较大的宽度,则称为跨步:。谢谢武维特看。最有可能的情况是,样本不暴露IMF2DBuffer。我确实使用IMFMediaBuffer。我已经测试了3个媒体文件。在所有情况下,步幅=宽度*4。问题是,在某些情况下,样本缓冲区长度大于hw*4。获取第一个hw*4字节的数据会产生错误的输出图像。每当我的缓冲区长度为h*w*4时,数据都是正确的。