📄 pxjpgrnd.cpp
字号:
}HX_RESULT CJPEGRenderer::RMASurfaceUpdate2(IHXSubRectVideoSurface* pSurface, HXxRect* pExtents, HXxBoxRegion* pDirtyRegion){ MLOG_MISC(m_pErrorMessages, "0x%08x:CJPEGRenderer::RMASurfaceUpdate2()\n"); HX_RESULT retVal = HXR_OK; // Make sure we have valid argument and valid // buffer to display if (pSurface && pDirtyRegion && m_pImage && m_pImage->GetImageBuffer() && m_bPastDisplayTime && m_pSite) { // Get the size of the site HXxSize size; m_pSite->GetSize(size); // Scale dirty rects to current display size float fx = 1.0; float fy = 1.0; if (size.cx > 0 && size.cy > 0) { fx = (float) m_pImage->GetWidth() / (float) size.cx; fy = (float) m_pImage->GetHeight() / (float) size.cy; } // Go through each rect in the dirty region and scale it to // generate the src rects. if (pDirtyRegion->numRects > 0) { // Create an array to hold the scaled subrects HXBOX* pSrcRects = new HXBOX[pDirtyRegion->numRects]; for(INT32 i = 0; i < pDirtyRegion->numRects; i++) { pSrcRects[i].x1 = (float) pDirtyRegion->rects[i].x1 * fx + 0.5; pSrcRects[i].x2 = (float) pDirtyRegion->rects[i].x2 * fx + 0.5; pSrcRects[i].y1 = (float) pDirtyRegion->rects[i].y1 * fy + 0.5; pSrcRects[i].y2 = (float) pDirtyRegion->rects[i].y2 * fy + 0.5; } // Set up Src region. HXxBoxRegion srcRegion; srcRegion.numRects = pDirtyRegion->numRects; srcRegion.rects = pSrcRects; // Set up the bitmap info header HXBitmapInfoHeader cHeader; cHeader.biSize = 40; cHeader.biWidth = (INT32) m_pImage->GetWidth(); cHeader.biHeight = (INT32) m_pImage->GetHeight(); cHeader.biPlanes = 1; cHeader.biBitCount = 32; cHeader.biCompression = (m_bUsesAlphaChannel ? HX_ARGB : HX_RGB); cHeader.biSizeImage = 0; cHeader.biXPelsPerMeter = 0; cHeader.biYPelsPerMeter = 0; cHeader.biClrUsed = 0; cHeader.biClrImportant = 0; cHeader.rcolor = 0; cHeader.gcolor = 0; cHeader.bcolor = 0; // Get the image store BYTE* pBits = m_pImage->GetImageBuffer(); if (pBits) { MLOG_MISC(m_pErrorMessages, "\t\tnumRects=%ld\n", srcRegion.numRects); for (INT32 i = 0; i < srcRegion.numRects; i++) { MLOG_MISC(m_pErrorMessages, "\t\t\trect[%ld] = (%d,%d,%d,%d)\n", i, srcRegion.rects[i].x1, srcRegion.rects[i].y1, srcRegion.rects[i].x2, srcRegion.rects[i].y2); } // Blit to the video surface pSurface->BltSubRects(pBits, &cHeader, pDirtyRegion, &srcRegion, 1.0/fx, 1.0/fy); } // Delete the array of scaled subrects HX_VECTOR_DELETE(pSrcRects); } } else { retVal = HXR_FAIL; } return retVal;}void CJPEGRenderer::_AttachSite(){ if (m_pSite) { // Sign up to receive sub rect messages IHXSubRectSite* pSubRectSite = NULL; m_pSite->QueryInterface(IID_IHXSubRectSite, (void**) &pSubRectSite); if(pSubRectSite) { // If so, since IHXSubRectSite inherits from IHXSite, lets // just swap the pointers and sign up for the service. HX_RELEASE(m_pSite); m_pSite = pSubRectSite; pSubRectSite->SendSubRectMessages(TRUE); } }}HX_RESULT CJPEGRenderer::InsertDummyData(CIJGLibraryWrapper *pWrap, IHXBuffer *pCurrentBuffer){ // Get the last buffer appended to the library's decompression buffer list IHXBuffer *pLastBuffer = NULL; pWrap->GetLastPacketBuffer(&pLastBuffer); if (pLastBuffer == NULL) { pWrap->SetValid(FALSE); return HXR_UNEXPECTED; } // Compute the number of lost packets BYTE *pCurBuf = pCurrentBuffer->GetBuffer() + 8; BYTE *pLstBuf = pLastBuffer->GetBuffer() + 8; UINT32 ulCurrSeqNum; UnPack32(pCurBuf, ulCurrSeqNum); UINT32 ulLastSeqNum; UnPack32(pLstBuf, ulLastSeqNum); UINT32 ulNumLostPackets = ulCurrSeqNum - ulLastSeqNum - 1; // This image has restart markers. So we need to first find out the // value of the last restart marker. We know, because we parsed the image, // that the last two bytes of a packet will be 0xFF 0xDq where q = [0,7]. // If the last two bytes are NOT that, then this is the first data packet. BYTE *pData = pLastBuffer->GetBuffer() + 16; UINT32 ulLen = pLastBuffer->GetSize(); UINT32 ulLastByte = pData[ulLen - 1]; UINT16 usTmp; UnPack16(pData, usTmp); UINT32 ulLastStartBlock = usTmp; UnPack16(pData, usTmp); UINT32 ulLastBlockCount = usTmp; // Compute the next marker UINT32 ulNextMarker; if (ulLastSeqNum > 0) { // The last packet received was not the header packet. Therefore, we // should be able to look at the last two bytes of the last packet ulNextMarker = ulLastByte + 1; if (ulNextMarker == 0xD8) { ulNextMarker = 0xD0; } } else { // The last packet received was the header packet. Therefore, // the first restart marker is 0xD0 ulNextMarker = 0xD0; } // Get the current starting block index pData = pCurrentBuffer->GetBuffer() + 16; UnPack16(pData, usTmp); UINT32 ulCurStartBlock = usTmp; // Compute the number of blocks to fill in and the size of the dummy buffer UINT32 ulNumBlocksToFill = ulCurStartBlock - ulLastStartBlock - ulLastBlockCount; if (ulNumBlocksToFill < ulNumLostPackets) { return HXR_FAILED; } // What we will do is put 1 block per lost packet up until the last lost packet, // where we will fill in the rest of the lost blocks for (UINT32 i = 0; i < ulNumLostPackets; i++) { UINT32 ulNumBlocksInThisPacket = 0; if (i == ulNumLostPackets - 1) { // We're doing the last lost packet, so we fill // in the rest of the lost blocks in this packet ulNumBlocksInThisPacket = ulNumBlocksToFill - (ulNumLostPackets - 1); } else { // We fill in only 1 block in this packet ulNumBlocksInThisPacket = 1; } // Compute the size of the opaque data of this packet UINT32 ulDummySize = kJPEGPacketOverhead + ulNumBlocksInThisPacket * 6; // Create an IHXBuffer IHXBuffer *pDummy = NULL; HX_RESULT retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void **) &pDummy); if (retVal != HXR_OK || pDummy == NULL) { return HXR_FAILED; } // Set the size retVal = pDummy->SetSize(kJPEGPacketOverhead + ulNumBlocksInThisPacket * 6); if (retVal != HXR_OK) { return retVal; } // Loop through the blocks to fill in dummy data pData = pDummy->GetBuffer() + kJPEGPacketOverhead; for (UINT32 j = ulNumBlocksInThisPacket; j; j--) { // Set this block pData[0] = (BYTE) 0; pData[1] = (BYTE) 0; pData[2] = (BYTE) 0; pData[3] = (BYTE) 0; pData[4] = (BYTE) 0xFF; pData[5] = (BYTE) ulNextMarker; // Increment the buffer pointer pData += 6; // Modulo-8 increment the marker ulNextMarker++; if (ulNextMarker == 0xD8) { ulNextMarker = 0xD0; } } // Now append this to the buffer list pWrap->AppendBuffer(pDummy); // Now we can release the buffer, since the wrapper AddRef's it HX_RELEASE(pDummy); } return HXR_OK;}void CJPEGRenderer::DrawToRMASurface(IHXVideoSurface *pVideoSurface, UINT32 ulX, UINT32 ulY, const HXxSize &size){ if (m_pImage) { HXxRect rDestRect = { 0, 0, size.cx, size.cy}; HXxRect rSrcRect = { 0, 0, m_pImage->GetWidth(), m_pImage->GetHeight() }; HXBitmapInfoHeader cHeader; cHeader.biSize = 40; cHeader.biWidth = (INT32) m_pImage->GetWidth(); cHeader.biHeight = (INT32) m_pImage->GetHeight(); cHeader.biPlanes = 1; cHeader.biBitCount = 32; cHeader.biCompression = (m_bUsesAlphaChannel ? HX_ARGB : HX_RGB); cHeader.biSizeImage = 0; cHeader.biXPelsPerMeter = 0; cHeader.biYPelsPerMeter = 0; cHeader.biClrUsed = 0; cHeader.biClrImportant = 0; MLOG_MISC(m_pErrorMessages, "\tDrawToRMASurface()\n" "\t\tsrc: (%ld,%ld,%ld,%ld)\n" "\t\tdst: (%ld,%ld,%ld,%ld)\n", rSrcRect.left, rSrcRect.top, rSrcRect.right, rSrcRect.bottom, rDestRect.left, rDestRect.top, rDestRect.right, rDestRect.bottom); pVideoSurface->Blt(m_pImage->GetImageBuffer(), &cHeader, rDestRect, rSrcRect); }}void CJPEGRenderer::AdjustTransparency(BYTE* pBuffer, UINT32 ulNumPix, BOOL bMediaOpacitySpecified, UINT32 ulMediaOpacity, BOOL bMediaChromaKeySpecified, UINT32 ulMediaChromaKey, UINT32 ulMediaChromaKeyTolerance, UINT32 ulMediaChromaKeyOpacity, REF(BOOL) rbUsesAlphaChannel){ // Make sure have some work to do if (pBuffer && ulNumPix && (bMediaOpacitySpecified || bMediaChromaKeySpecified)) { // Clip the opacity values if (ulMediaOpacity > 255) ulMediaOpacity = 255; if (ulMediaChromaKeyOpacity > 255) ulMediaChromaKeyOpacity = 255; // Get a 32bit pointer UINT32* pPix = (UINT32*) pBuffer; // Check to see what we need to do. We will // break these out, since they will optimize // best if there is not unused code in each loop if (bMediaOpacitySpecified && !bMediaChromaKeySpecified) { // If we are forcing any other opacity less // than 255, then we KNOW we will be using // the alpha channel rbUsesAlphaChannel = (ulMediaOpacity < 255 ? TRUE : FALSE); // Compute the media alpha UINT32 ulMediaAlpha = (255 - ulMediaOpacity) << 24; // Run through the pixels, forcing this alpha while (ulNumPix--) { *pPix++ = (*pPix & 0x00FFFFFF) | ulMediaAlpha; } } else if (!bMediaOpacitySpecified && bMediaChromaKeySpecified) { // If the chroma key opacity is less than 255, then // we MAY be using the alpha channel, depending on // whether there are any pixels which match the chroma key BOOL bNeedAlpha = (ulMediaChromaKeyOpacity < 255 ? TRUE : FALSE); // Initially set the flag to FALSE rbUsesAlphaChannel = FALSE; // Compute the chroma key alpha UINT32 ulChromaAlpha = (255 - ulMediaChromaKeyOpacity) << 24; // Run through the pixels while (ulNumPix--) { if (DoesChromaKeyMatch(*pPix, ulMediaChromaKey, ulMediaChromaKeyTolerance)) { *pPix = (*pPix & 0x00FFFFFF) | ulChromaAlpha; rbUsesAlphaChannel = bNeedAlpha; } pPix++; } } else if (bMediaOpacitySpecified && bMediaChromaKeySpecified) { // If we are forcing any other opacity less // than 255, then we KNOW we will be using // the alpha channel rbUsesAlphaChannel = (ulMediaOpacity < 255 ? TRUE : FALSE); // If the chroma key opacity is less than 255, then // we MAY be using the alpha channel, depending on // whether there are any pixels which match the chroma key BOOL bNeedAlpha = (ulMediaOpacity < 255 || ulMediaChromaKeyOpacity < 255 ? TRUE : FALSE); // If the pixel is a chroma key match, then we // will be replacing it with the chroma key opacity // SCALED by the media opacity. If not, then we simply // force the media opacity UINT32 ulScaledChromaOpacity = ulMediaChromaKeyOpacity * ulMediaOpacity / 255; UINT32 ulChromaAlpha = (255 - ulScaledChromaOpacity) << 24; UINT32 ulMediaAlpha = (255 - ulMediaOpacity) << 24; // Run through the pixels while (ulNumPix--) { // Check the chroma key if (DoesChromaKeyMatch(*pPix, ulMediaChromaKey, ulMediaChromaKeyTolerance)) { *pPix++ = (*pPix & 0x00FFFFFF) | ulChromaAlpha; rbUsesAlphaChannel = bNeedAlpha; } else { *pPix++ = (*pPix & 0x00FFFFFF) | ulMediaAlpha; } } } }}STDMETHODIMP CJPEGRenderer::GetName(REF(const char*) rpszName){ rpszName = (const char*) m_pszName; return HXR_OK;}STDMETHODIMP CJPEGRenderer::GetDescription(REF(const char*) rpszDescription){ rpszDescription = (const char*) m_pszDescription; return HXR_OK;}STDMETHODIMP CJPEGRenderer::GetMimeTypes(REF(const char**) rppszMimeType){ rppszMimeType = (const char**) m_ppszMimeType; return HXR_OK;}STDMETHODIMP_(UINT32) CJPEGRenderer::GetPluginVersion(){ return TARVER_ULONG32_VERSION;}STDMETHODIMP_(UINT32) CJPEGRenderer::GetInitialGranularity(){ return 100;}STDMETHODIMP_(UINT32) CJPEGRenderer::GetHighestSupportedStreamVersion(){ return HX_ENCODE_PROD_VERSION(0, 1, 0, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -