- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试调用 ProcessOutput
以从我的解码器获取解码数据并出现以下错误:
E_INVALIDARG
One or more arguments are invalid.
由于 ProcessOutput
有很多参数,我试图查明可能是什么错误。 Documentation for ProcessOutput
没有提到 E_INVALIDARG
。然而,documentation for MFT_OUTPUT_DATA_BUFFER
,其中一个参数的数据类型,在其备注部分中提到:
Any other combinations are invalid and cause
ProcessOutput
to returnE_INVALIDARG
它谈论的是如何设置 MFT_OUTPUT_DATA_BUFFER
结构。因此,错误设置 MFT_OUTPUT_DATA_BUFFER
可能会导致该错误。但是,我已尝试正确设置它。
通过调用 GetOutputStreamInfo,我发现我需要分配发送到 ProcessOutput 的样本,这正是我所做的。我使用的方法与用于 ProcessInput 的方法几乎相同,所以我不知道我在这里做错了什么。
我还尝试确保其他参数,逻辑上也应该能够导致 E_INVALIDARG
。它们对我来说看起来不错,但我无法找到任何其他线索来说明我对 ProcessOutput
的哪些参数可能无效。
我试图只发布下面代码的相关部分。为了简洁起见,我删除或缩短了许多错误检查。请注意,我使用的是纯 C。
...
hr = pDecoder->lpVtbl->SetOutputType(pDecoder, dwOutputStreamID, pMediaOut, dwFlags);
...
// Send input to decoder
hr = pDecoder->lpVtbl->ProcessInput(pDecoder, dwInputStreamID, pSample, dwFlags);
if (FAILED(hr)) { /* did not fail */ }
所以在下面有趣的代码之前,我已经成功地设置了一些东西(我希望如此)并将它们发送到没有失败的 ProcessInput。我有 1 个输入流和 1 个输出流,AAC 输入,PCM 输出。
// Input has now been sent to the decoder
// To extract a sample from the decoder we need to create a strucure to hold the output
// First we ask the OutputStream for what type of output sample it will produce and who should allocate it
// Then we create both the sample in question (if we should allocate it that is) and the MFT_OUTPUT_DATA_BUFFER
// which holds the sample and some other information that the decoder will fill in.
#define SAMPLES_PER_BUFFER 1 // hardcoded here, should depend on GetStreamIDs results, which right now is 1
MFT_OUTPUT_DATA_BUFFER pOutputSamples[SAMPLES_PER_BUFFER];
DWORD *pdwStatus = NULL;
// There are different allocation models, find out which one is required here.
MFT_OUTPUT_STREAM_INFO streamInfo = { 0,0,0 };
MFT_OUTPUT_STREAM_INFO *pStreamInfo = &streamInfo;
hr = pDecoder->lpVtbl->GetOutputStreamInfo(pDecoder, dwOutputStreamID, pStreamInfo);
if (FAILED(hr)) { ... }
if (pStreamInfo->dwFlags == MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) { ... }
else if (pStreamInfo->dwFlags == MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES) { ... }
else {
// default, the client must allocate the output samples for the stream
IMFSample *pOutSample = NULL;
DWORD minimumSizeOfBuffer = pStreamInfo->cbSize;
IMFMediaBuffer *pBuffer = NULL;
// CreateMediaSample is explained further down.
hr = CreateMediaSample(minimumSizeOfBuffer, sampleDuration, &pBuffer, &pOutSample);
if (FAILED(hr)) {
BGLOG_ERROR("error");
}
pOutputSamples[0].pSample = pOutSample;
}
// since GetStreamIDs return E_NOTIMPL then dwStreamID does not matter
// but its recomended that it is set to the array index, 0 in this case.
// dwOutputStreamID will be 0 when E_NOTIMPL is returned by GetStremIDs
pOutputSamples[0].dwStreamID = dwOutputStreamID; // = 0
pOutputSamples[0].dwStatus = 0;
pOutputSamples[0].pEvents = NULL; // have tried init this myself, but MFT_OUTPUT_DATA_BUFFER documentation says not to.
hr = pDecoder->lpVtbl->ProcessOutput(pDecoder, dwFlags, outputStreamCount, pOutputSamples, pdwStatus);
if (FAILED(hr)) {
// here E_INVALIDARG is found.
}
代码中使用的 CreateMediaSample 派生自 an example来自官方文档,但修改为调用 SetSampleDuration 和 SetSampleTime。虽然我没有设置这两个,但我得到了同样的错误,所以它应该是导致问题的其他原因。
如果我可能遗漏了一些从实际数据中很容易看出的东西:
hr = pDecoder->lpVtbl->ProcessOutput(
pDecoder, // my decoder
dwFlags, // 0
outputStreamCount, // 1 (from GetStreamCount)
pOutputSamples, // se comment below
pdwStatus // NULL
);
// pOutputSamples[0] holds this struct:
// dwStreamID = 0,
// pSample = SampleDefinedBelow
// dwStatus = 0,
// pEvents = NULL
// SampleDefinedBelow:
// time = 0
// duration = 0.9523..
// buffer = with max length set correctly
// attributes[] = NULL
所以有人对我做错了什么或我如何进一步调试有任何想法吗?
最佳答案
ProcessOutput
需要一个有效的指针作为最后一个参数,所以这不起作用:
DWORD *pdwStatus = NULL;
pDecoder->lpVtbl->ProcessOutput(..., pdwStatus);
没关系:
DWORD dwStatus;
pDecoder->lpVtbl->ProcessOutput(..., &dwStatus);
关于 E_FAIL
- 总的来说,您上面的发现看起来不错。这不是我看到的明显的东西,而且错误代码也不表明问题出在 MFT 数据流上。也许它可能是错误的数据或与媒体类型集不匹配的数据。
关于c - IMFTransform::ProcessOutput 返回 E_INVALIDARG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41983374/
我注意到,正如显然记录的那样,重采样器的 IMFTransform::ProcessOutput() 每次调用只能输出一个样本!我想它更面向大帧大小的视频编码。鉴于我一直在查看的所有代码作为相关音频播
我正在尝试在 Windows 7 上使用 WASAPI 共享模式和媒体基础 IMFSourceReader 播放 MP3(和类似的音频文件)。据我了解,我必须在 IMFSourceReader 解码和
问题 我正在尝试调用 ProcessOutput 以从我的解码器获取解码数据并出现以下错误: E_INVALIDARG One or more arguments are invalid. 我尝试过的
我正在尝试使用Media Foundation Transforms将HE-AAC音频流(由live555,RTP库接收)转换为PCM(通过waveOutXxx Win32 API播放)。但是,目前我
我有一个关于 IMFTransform *pEncoder 的指针。如果 IMFTransform::GetAttributes 返回 E_NOTIMPL,我如何从该指针获取 GUID 编码器? 最佳
能否实现IMFTransform 接口(interface)来编码或解码 H264 或 AAC 数据,或者我应该使用 FFmpeg或 OpenH264 . 最佳答案 当您编码或解码媒体时,IMFTra
我正在尝试使用 IMFTransform 将纹理编码为 H264。我可以使用 SinkWriter 将纹理写入和编码到文件中,并且可以播放视频和所有内容,效果很好。但我正在尝试学习如何使用 IMFTr
我正在使用 SinkWriter 以使用媒体基础对视频进行编码。 在初始化 SinkWriter 之后,我想获取它使用的底层编码器,并打印出它的名称,这样我就可以看到它使用的是什么编码器。 (在我的例
我正在尝试使用 Windows Media Foundation 类解码 mp4 视频并将帧转换为 DirectX 着色器可用于渲染的 2D 纹理。我已经能够使用 MFCreateSourceRead
我正在尝试使用 Color Converter DMO ( http://msdn.microsoft.com/en-us/library/windows/desktop/ff819079(v=vs.
我是一名优秀的程序员,十分优秀!