📄 h264.cpp
字号:
return E_FAIL;
} else
{
//Success buffer written to decoder, tell decoder to process this buffer so we can release it
int eReadResult = DIU_STATUS_OK;
unsigned char *pbuf = NULL;
unsigned int flags = 0;
LONGLONG pts = 0;
unsigned int size = 0;
eReadResult = DIUComp_GetBuffer(m_hDecoder, pbuf, &size, &pts, &flags);
if (eReadResult!=DIU_STATUS_OK && eReadResult!=DIU_STATUS_NEEDMOREINPUT)
{
DP_ERROR((TEXT("ProcessInput DIUComp_GetBuffer(m_hDecoder) Send Header failed: 0x%08X"), eReadResult));
return E_FAIL;
}
DP_INFO((TEXT("ProcessInput Send Header complete(%d)"), ulHeaderSize));
}
MoFreeMediaType(&mtInput);
}
else if (mtInput.formattype == FORMAT_VideoInfo)
{
VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)mtInput.pbFormat;
unsigned long ulHeaderSize = sizeof(VIDEOINFOHEADER);
unsigned char *pHeaderBuf = (unsigned char*)pvih;
unsigned int dwHeaderFlags = DIU_FLAG_NEWFORMAT | DIU_FLAG_FRAMEEND;
#ifdef DUMP_STANDALONE_FILE
if (s_TestFile)
{
STANDALONE_FILE_HEADER FileHdr;
memset(&FileHdr, 0, sizeof(STANDALONE_FILE_HEADER));
char* Padding[3] = {00,00,00};
unsigned int nPad = 0;
FileHdr.fileID[0] = 'S';
FileHdr.fileID[1] = 'A';
FileHdr.fileID[2] = 'D';
FileHdr.fileID[3] = 'H';
FileHdr.format[0] = 'H';
FileHdr.format[1] = '2';
FileHdr.format[2] = '6';
FileHdr.format[3] = '4';
FileHdr.flags = dwHeaderFlags;
FileHdr.width = pvih->bmiHeader.biWidth;
FileHdr.height = pvih->bmiHeader.biHeight;
//align to 4 byte boundary
FileHdr.nHeaderSize = (sizeof(STANDALONE_FILE_HEADER) + ulHeaderSize)+3 &~3;
FileHdr.nPayloadSize = ulHeaderSize;
//write file header structure
fwrite(&FileHdr, 1, sizeof(STANDALONE_FILE_HEADER), s_TestFile);
//write actual decoder header data
fwrite(pHeaderBuf, 1, ulHeaderSize, s_TestFile);
//write the padding bytes
nPad = FileHdr.nHeaderSize - (sizeof(STANDALONE_FILE_HEADER) + ulHeaderSize);
fwrite(Padding, 1, nPad, s_TestFile);
}
#endif
eWriteResult = DIUComp_PutBuffer(m_hDecoder, pHeaderBuf, ulHeaderSize, 0, dwHeaderFlags, 0);
if (eWriteResult!=DIU_STATUS_OK)
{
DP_ERROR((TEXT("Process DIUComp_PutBuffer(m_hDecoder) Send Header failed: 0x%08X"), eWriteResult));
return E_FAIL;
} else
{
//Success buffer written to decoder, tell decoder to process this buffer so we can release it
int eReadResult = DIU_STATUS_OK;
unsigned char *pbuf = NULL;
unsigned int flags = 0;
LONGLONG pts = 0;
unsigned int size = 0;
eReadResult = DIUComp_GetBuffer(m_hDecoder, pbuf, &size, &pts, &flags);
if (eReadResult!=DIU_STATUS_OK && eReadResult!=DIU_STATUS_NEEDMOREINPUT)
{
DP_ERROR((TEXT("ProcessInput DIUComp_GetBuffer(m_hDecoder) Send Header failed: 0x%08X"), eReadResult));
return E_FAIL;
}
DP_INFO((TEXT("ProcessInput Send Header complete(%d)"), ulHeaderSize));
}
MoFreeMediaType(&mtInput);
}
else
{
DP_ERROR((TEXT("GetInputCurrentType() returned unsupported format")));
DP_INFO((TEXT(" formattype {%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X}"), mtInput.formattype.Data1, mtInput.formattype.Data2, mtInput.formattype.Data3, mtInput.formattype.Data4[0],
mtInput.formattype.Data4[1], mtInput.formattype.Data4[2], mtInput.formattype.Data4[3], mtInput.formattype.Data4[4], mtInput.formattype.Data4[5], mtInput.formattype.Data4[6], mtInput.formattype.Data4[7]));
MoFreeMediaType(&mtInput);
return E_FAIL;
}
}
m_bSentHeader = true;
}
if (dwDMOFlags & DMO_INPUT_DATA_BUFFERF_TIME)
{
//Codecs expect time stamps to be in milliseconds instead of 100ns units of dshow
tStartMS = (LONGLONG)(rtTimestamp/10000);
dwFlags |= DIU_FLAG_PTS;
}
hr = pBuffer->GetBufferAndLength(&pInBuf, &ulDataSize);
if (FAILED(hr))
{
DP_ERROR((TEXT("InternalProcessInput GetBufferAndLength FAILED (0x%08X)"), hr));
return hr;
}
hr = pBuffer->GetMaxLength(&ulMaxSize);
if (FAILED(hr))
{
DP_ERROR((TEXT("InternalProcessInput GetMaxLength FAILED (0x%08X)"), hr));
return hr;
}
//Hold the pointer to the buffer
m_pBuffer = pBuffer;
if (ulDataSize < ulMaxSize)
{
//here we set frame ending if less than max size
// If it is equal (will never be greater) to max size then we have 2 outcomes
// 1- we broke up a frame so don't send the frame end flag (it will be sent on
// next time through when it is less than max size) or
// 2- the frame is exactly the size of the buffer (unlikely) in which case we won't
// set the frame end which is okay will just delay the decode to next frame until
// the next frame end flag. It is highly improbable to have more than one frame
// in a row equal to max size
dwFlags |= DIU_FLAG_FRAMEEND;
}
if (m_bDiscontinuity)
{
//this is first new sample after discountinuity
dwFlags |= DIU_FLAG_DATADISCON;
m_bDiscontinuity = false;
DP_INFO((TEXT("InternalProcessInput DATADISCON")));
}
#ifdef DUMP_FILE
fwrite(pInBuf, 1, ulDataSize, s_InDataFile);
#endif
#ifdef DUMP_STANDALONE_FILE
if (s_TestFile)
{
STANDALONE_FRAME_HEADER FrameHdr;
memset(&FrameHdr, 0, sizeof(STANDALONE_FRAME_HEADER));
char* Padding[3] = {00,00,00};
unsigned int nPad = 0;
FrameHdr.frameID[0] = 'S';
FrameHdr.frameID[1] = 'A';
FrameHdr.frameID[2] = 'D';
FrameHdr.frameID[3] = 'F';
FrameHdr.flags = dwFlags;
FrameHdr.pts = tStartMS;
//align to 4 byte boundary
FrameHdr.nFrameSize = (sizeof(STANDALONE_FRAME_HEADER) + ulDataSize)+3 &~3;
FrameHdr.nPayloadSize = ulDataSize;
//write frame header structure
fwrite(&FrameHdr, 1, sizeof(STANDALONE_FRAME_HEADER), s_TestFile);
//write actual frame data
fwrite(pInBuf, 1, ulDataSize, s_TestFile);
//write the padding bytes
nPad = FrameHdr.nFrameSize - (sizeof(STANDALONE_FRAME_HEADER) + ulDataSize);
fwrite(Padding, 1, nPad, s_TestFile);
}
#endif
if ((dwDMOFlags&DMO_INPUT_DATA_BUFFERF_TIME) == DMO_INPUT_DATA_BUFFERF_TIME)
{
DP_DATA((TEXT("InternalProcessInput Calling DIUComp_PutBuffer(%d) pts(%d)"), ulDataSize, (DWORD)tStartMS));
}else
{
DP_DATA((TEXT("InternalProcessInput Calling DIUComp_PutBuffer(%d) no pts"), ulDataSize));
}
eWriteResult = DIUComp_PutBuffer(m_hDecoder, pInBuf, ulDataSize, tStartMS, dwFlags, dwDMOFlags);
if (eWriteResult != DIU_STATUS_OK)
{
DP_ERROR((TEXT("InternalProcessInput DIUComp_PutBuffer(m_hDecoder) failed: 0x%08X"), eWriteResult));
hr = E_FAIL;
} else
{
if ((dwDMOFlags&DMO_INPUT_DATA_BUFFERF_TIME) == DMO_INPUT_DATA_BUFFERF_TIME)
{
DP_DATA((TEXT("InternalProcessInput DIUComp_PutBuffer(%d) pts(%d) complete"), ulDataSize, (DWORD)tStartMS));
}else
{
DP_DATA((TEXT("InternalProcessInput DIUComp_PutBuffer(%d) no pts complete"), ulDataSize));
}
//Success buffer written to decoder
hr = S_OK;
}
DP_INFO((TEXT("InternalProcessInput: returned 0x%X"), hr));
return hr;
}
HRESULT CH264Dmo::InternalProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, DMO_OUTPUT_DATA_BUFFER *pOutputBuffers, DWORD *pdwStatus)
{
int eReadResult = DIU_STATUS_OK;
PBYTE pbData = NULL;
DWORD cbMaxSize = 0;
DWORD cbCurrentSize = 0;
pOutputBuffers->dwStatus = 0;
unsigned char *pbuf = NULL;
unsigned int flags = 0;
LONGLONG pts = 0;
unsigned int size = 0;
DP_FUNC((TEXT("InternalProcessOutput(count=%d) enter"), cOutputBufferCount));
//this is to initialize the stop time since there is an error in the framework where the stop
// position may not get initialized and could be some very large value delaying EOS processing
pOutputBuffers->rtTimelength = 1;
pOutputBuffers->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH;
HRESULT hr = pOutputBuffers->pBuffer->GetBufferAndLength(&pbData, &cbCurrentSize);
if (FAILED(hr))
{
DP_ERROR((TEXT("InternalProcessOutput GetBufferAndLength failed: hr=0x%X"), hr));
return hr;
}
hr = pOutputBuffers->pBuffer->GetMaxLength(&cbMaxSize);
if (FAILED(hr))
{
DP_ERROR((TEXT("InternalProcessOutput GetMaxLength failed: hr=0x%X"), hr));
return hr;
}
m_bFrame = FALSE;
pbuf = pbData;
size = cbMaxSize;
DP_DATA((TEXT("InternalProcessOutput Calling DIUComp_GetBuffer")));
eReadResult = DIUComp_GetBuffer(m_hDecoder, pbuf, &size, &pts, &flags);
if (eReadResult == DIU_STATUS_OK || eReadResult == DIU_STATUS_NEEDMOREINPUT)
{
DP_INFO((TEXT("DIUComp_GetBuffer output %d flags %x pts %u"), size, flags, (unsigned int)pts));
if (flags & DIU_FLAG_NEWFORMAT) /* check for format data */
{
DIUMediaType_s *pMT = (DIUMediaType_s *)pbuf;
DP_INFO((TEXT("Process() New Format: DataSize=%d"), size));
if (pMT->eMType == DIU_MTYPE_VIDEO)
{
DIUMediaTypeVideo_t *pVideoInfo=(DIUMediaTypeVideo_t *)pbuf;
DP_DATA((TEXT(" Video Format: subtype=0x%X size=%d x %d"), pVideoInfo->MediaTypeInfo.eMSubtype,
pVideoInfo->uiFinalWidth, pVideoInfo->uiFinalHeight));
}
}
else if (size > 0) /* must be decoded data, so we can pass to renderer */
{
//we will get buffers of size 1 since its going to hardware
m_bFrame = true;
#ifdef DUMP_FILE
fwrite(pbuf, 1, size, s_OutDataFile);
#endif
/* update the length of the buffer */
hr = pOutputBuffers->pBuffer->SetLength(size);
if ((flags&DMO_OUTPUT_DATA_BUFFERF_TIME) == DMO_OUTPUT_DATA_BUFFERF_TIME)
{
DP_DATA((TEXT("InternalProcessOutput Output(%d) timestamp(%d)"), size, (DWORD)pts));
pOutputBuffers->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_TIME;
pOutputBuffers->rtTimestamp = pts * 10000; /* Convert codec millisec timestamps back to dshow time */
} else
{
DP_DATA((TEXT("InternalProcessOutput Output(%d) no timestamp"), size));
}
}
if (eReadResult == DIU_STATUS_OK)
{
//processed a buffer but still have input data left, signal another call to process output
pOutputBuffers->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE;
} else
{
//We used up all the data in the write buffer release the input buffer
DP_DATA((TEXT("DIUComp_ReadBuffer() NEEDMOREINPUT")));
pOutputBuffers->dwStatus &= ~DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE;
m_pBuffer = NULL;
}
}
else
{
if (eReadResult == DIU_STATUS_UNSUPPORTEDFORMAT || eReadResult == DIU_STATUS_OPENERROR)
{
//don't output error statement on unsupported formats or when newpred is detected
DP_INFO((TEXT("Process DIUComp_GetBuffer(m_hDecoder) failed: 0x%08X"), eReadResult));
} else
{
DP_ERROR((TEXT("Process DIUComp_GetBuffer(m_hDecoder) failed: 0x%08X"), eReadResult));
}
return E_FAIL;
}
return m_bFrame ? S_OK : S_FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -