我正在尝试调用ProcessOutput
从解码器中获取解码数据,并收到以下错误:
E_INVALIDARG
一个或多个参数无效。
由于ProcessOutput
有许多论据,我试图找出错误可能是什么。 Documentation for ProcessOutput
未提及E_INVALIDARG
。但是,documentation for MFT_OUTPUT_DATA_BUFFER
(其中一个参数的数据类型)在其备注部分中提到:
任何其他组合均无效,导致
ProcessOutput
返回E_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
所以任何人对我做错了什么或者如何进一步调试都有任何想法?
答案 0 :(得分:2)
ProcessOutput
需要一个有效的指针作为最后一个参数,所以这不起作用:
DWORD *pdwStatus = NULL;
pDecoder->lpVtbl->ProcessOutput(..., pdwStatus);
这没关系:
DWORD dwStatus;
pDecoder->lpVtbl->ProcessOutput(..., &dwStatus);
关于进一步E_FAIL
- 您的上述发现总的来说看起来不错。并不是我看到了明显的东西,而且错误代码也没有暗示问题与MFT数据流有关。也许它可能是不匹配媒体类型集的坏数据或数据。