📄 h264.cpp
字号:
if (!InputTypeSet(0))
{
DP_ERROR((TEXT("InternalGetOutputType InputType not set")));
return DMO_E_TYPE_NOT_SET;
}
if (dwTypeIndex != 0)
{
return DMO_E_NO_MORE_ITEMS;
}
// If GetOutputType()'s pmt parameter is NULL, return S_OK if the type exists.
// Return DMO_E_NO_MORE_ITEMS if the type does not exists. See the
// documentation for IMediaObject::GetOutputType() for more information.
if (NULL != pmt)
{
hr = MoInitMediaType(pmt, sizeof(VIDEOINFOHEADER));
if (FAILED(hr))
{
DP_ERROR((TEXT("MoInitMediaType FAILED (%08X)"),hr));
return hr;
} else
{
VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)pmt->pbFormat;
memset(pvih, 0, sizeof(VIDEOINFOHEADER));
DMO_MEDIA_TYPE mtInput;
hr = GetInputCurrentType(0, &mtInput);
if (FAILED(hr))
{
DP_ERROR((TEXT("GetInputCurrentType FAILED (%08X)"), hr));
MoFreeMediaType(pmt);
return hr;
} else
{
if (mtInput.formattype == FORMAT_H264VideoInfo)
{
H264VIDEOINFOHEADER* pInH264Vih = (H264VIDEOINFOHEADER*)mtInput.pbFormat;
if (pvih)
{
pvih->rcSource = pInH264Vih->rcSource;
pvih->rcTarget = pInH264Vih->rcTarget;
pvih->bmiHeader.biWidth = pInH264Vih->bmiHeader.biWidth;
pvih->bmiHeader.biHeight = pInH264Vih->bmiHeader.biHeight;
pvih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvih->bmiHeader.biPlanes = 1;
pvih->bmiHeader.biBitCount = 8;
pvih->bmiHeader.biCompression = BI_RGB;
pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * pvih->bmiHeader.biBitCount / 8;
}
} else if (mtInput.formattype == FORMAT_VideoInfo)
{
VIDEOINFOHEADER* pInVih = (VIDEOINFOHEADER*)mtInput.pbFormat;
if (pvih)
{
pvih->rcSource = pInVih->rcSource;
pvih->rcTarget = pInVih->rcTarget;
pvih->bmiHeader.biWidth = pInVih->bmiHeader.biWidth;
pvih->bmiHeader.biHeight = pInVih->bmiHeader.biHeight;
pvih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvih->bmiHeader.biPlanes = 1;
pvih->bmiHeader.biBitCount = 8;
pvih->bmiHeader.biCompression = BI_RGB;
pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * pvih->bmiHeader.biBitCount / 8;
}
} else
{
//Set some defaults
DP_INFO((TEXT("VideoInfo not found on Input pin using defaults")));
if (pvih)
{
pvih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvih->bmiHeader.biWidth = 720;
pvih->bmiHeader.biHeight = 480;
pvih->bmiHeader.biPlanes = 1;
pvih->bmiHeader.biBitCount = 8;
pvih->bmiHeader.biCompression = BI_RGB;
pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * pvih->bmiHeader.biBitCount / 8;
}
}
MoFreeMediaType(&mtInput);
}
pmt->majortype = MEDIATYPE_Video;
pmt->subtype = MEDIASUBTYPE_Overlay;
pmt->bFixedSizeSamples = FALSE;
pmt->bTemporalCompression = FALSE;
pmt->formattype = FORMAT_VideoInfo;
pmt->lSampleSize = pvih->bmiHeader.biSizeImage;
pmt->cbFormat = sizeof(VIDEOINFOHEADER);
return S_OK;
}
}
DP_ERROR((TEXT("GetInputCurrentType FAILED to get valid media type)")));
return E_FAIL;
}
HRESULT CH264Dmo::InternalGetInputSizeInfo(DWORD dwInputStreamIndex, DWORD *pcbSize,
DWORD *pcbMaxLookahead, DWORD *pcbAlignment)
{
DP_FUNC((TEXT("InternalGetInputSizeInfo")));
*pcbSize = 1;
*pcbMaxLookahead = 0;
*pcbAlignment = 1;
return S_OK;
}
HRESULT CH264Dmo::InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
DWORD *pcbAlignment)
{
DP_FUNC((TEXT("InternalGetOutputSizeInfo")));
*pcbAlignment = 1;
*pcbSize = OUTPUT_BUFFER_SIZE;
return S_OK;
}
HRESULT CH264Dmo::InternalGetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency)
{
DP_FUNC((TEXT("InternalGetInputMaxLatency")));
return E_NOTIMPL;
}
HRESULT CH264Dmo::InternalSetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency)
{
DP_FUNC((TEXT("InternalSetInputMaxLatency")));
return E_NOTIMPL;
}
HRESULT CH264Dmo::InternalFlush()
{
DP_INFO((TEXT("InternalFlush")));
#ifdef DUMP_FILE
//close the dump files on flush
if (s_InDataFile)
{
fclose(s_InDataFile);
s_InDataFile = NULL;
}
if (s_OutDataFile)
{
fclose(s_OutDataFile);
s_OutDataFile = NULL;
}
//open new dump file
_tcscat(g_szInDataFile, TEXT("+"));
_tcscat(g_szOutDataFile, TEXT("+"));
s_InDataFile = _tfopen(g_szInDataFile, TEXT("wb"));
s_OutDataFile = _tfopen(g_szOutDataFile, TEXT("wb"));
#endif
#ifdef DUMP_STANDALONE_FILE
if (s_TestFile)
{
DP_ERROR((TEXT("Standalone test file %s complete!"), TEST_FILENAME));
fclose(s_TestFile);
s_TestFile = NULL;
}
#endif
DIUComp_Empty(m_hDecoder);
m_rtNow = m_rtOld = 0;
m_pBuffer = NULL;
m_bFrame = false;
return S_OK;
}
HRESULT CH264Dmo::InternalDiscontinuity(DWORD dwInputStreamIndex)
{
DP_INFO((TEXT("InternalDiscontinuity")));
m_bDiscontinuity = true;
return S_OK;
}
HRESULT CH264Dmo::InternalAllocateStreamingResources()
{
DP_FUNC((TEXT("InternalAllocateStreamingResources")));
//TODO allocate memory here
return S_OK;
}
HRESULT CH264Dmo::InternalFreeStreamingResources()
{
DP_FUNC((TEXT("InternalFreeStreamingResources")));
//TODO release allocated memory here
return S_OK;
}
HRESULT CH264Dmo::InternalAcceptingInput(DWORD dwInputStreamIndex)
{
HRESULT hr = (m_pBuffer == NULL) ? S_OK : S_FALSE;
DP_FUNC((TEXT("InternalAcceptingInput() hr=0x%08X"), hr));
return hr;
}
// IDMOQualityControl function
STDMETHODIMP CH264Dmo::SetNow(REFERENCE_TIME rtNow)
{
// Remember SetNow values even if quality control is not currently enabled
CDMOAutoLock l(&m_cs);
if (m_bQualityControlEnabled)
{
m_rtNow = rtNow;
DP_INFO((TEXT("m_rtNow(ms)=%d : LastUpdate(ms)=%d"), (DWORD)(m_rtNow/10000), (DWORD)(m_rtOld/10000)));
#ifdef DMO_QC_PROCESS
// only update if its been atleast 100ms since last update
if (m_rtNow>=(m_rtOld+1000000))
{
DWORD dwCurrentTime = (DWORD)(m_rtNow/10000);
m_rtOld = m_rtNow;
DP_INFO((TEXT("QC Time(ms): %d"), dwCurrentTime));
DIUComp_UpdateSync(m_hDecoder, dwCurrentTime);
}
#endif //DMO_QC_PROCESS
}
return NOERROR;
}
// IDMOQualityControl function
STDMETHODIMP CH264Dmo::SetStatus(DWORD dwFlags)
{
// Any point in grabbing the object lock here ?
if (dwFlags & DMO_QUALITY_STATUS_ENABLED) {
DP_INFO((TEXT("QC enabled")));
m_bQualityControlEnabled = TRUE;
}
else {
DP_INFO((TEXT("QC disabled")));
m_bQualityControlEnabled = FALSE;
}
return NOERROR;
}
HRESULT CH264Dmo::InternalProcessInput(DWORD dwInputStreamIndex, IMediaBuffer *pBuffer,
DWORD dwDMOFlags, REFERENCE_TIME rtTimestamp,
REFERENCE_TIME rtTimelength)
{
DP_FUNC((TEXT("InternalProcessInput")));
// Check parameters
_ASSERTE(m_pBuffer == NULL);
unsigned long ulDataSize = 0;
unsigned char *pInBuf;
unsigned long ulMaxSize = 0;
LONGLONG tStartMS = 0;
int eWriteResult = DIU_STATUS_OK;
HRESULT hr = S_OK;
unsigned int dwFlags = 0;
DP_INFO((TEXT("ProcessInput Current sample Timestamp(ms): %d"), (DWORD)(rtTimestamp/10000)));
if (!m_bSentHeader)
{
DP_INFO((TEXT("InternalProcessInput Sending Header to decoder")));
DMO_MEDIA_TYPE mtInput;
hr = GetInputCurrentType(0, &mtInput);
if (FAILED(hr))
{
DP_ERROR((TEXT("GetInputCurrentType FAILED (%08X)")));
return hr;
} else
{
if (mtInput.formattype == FORMAT_H264VideoInfo)
{
H264VIDEOINFOHEADER* pvih = (H264VIDEOINFOHEADER*)mtInput.pbFormat;
unsigned long ulHeaderSize = pvih->vihSize - sizeof(H264VIDEOINFOHEADER);
unsigned char *pHeaderBuf = (unsigned char*)pvih + sizeof(H264VIDEOINFOHEADER);
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("ProcessInput DIUComp_PutBuffer(m_hDecoder) Send Header failed: 0x%08X"), eWriteResult));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -