⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chenvideo.cpp

📁 LDPC码的实现,包括编码器和解码器,使用了DCT.
💻 CPP
字号:
// ChenVideo.cpp

#include <ChenVideo.h>

#ifdef _USEIPP
#include <ippi.h>
#endif


int ChenVideo_loadYUVVideo(const char* pVideoFileName, Resolution resolution, const int nStartFrame, const int nEndFrame, short**& pFramesY, short**& pFramesU, short**& pFramesV)
{

#ifdef _USEIPP

	bool bSuccess = true;

	// Determine dimensions
	int nWidth, nHeight;
	if (resolution == QCIF) {
		nWidth = QCIF_WIDTH;
		nHeight = QCIF_HEIGHT;
	}
	else if (resolution == CIF) {
		nWidth = CIF_WIDTH;
		nHeight = CIF_HEIGHT;
	}
	else if (resolution == FOURCIF) {
		nWidth = FOURCIF_WIDTH;
		nHeight = FOURCIF_HEIGHT;
	}
	else if (resolution == SIXTEENCIF) {
		nWidth = SIXTEENCIF_WIDTH;
		nHeight = SIXTEENCIF_HEIGHT;
	}
	int nPixelsPerChannel = nWidth * nHeight;
	
	// Allocate space
	int nFrames = nEndFrame - nStartFrame + 1;
	if (nFrames <= 0) {
		fprintf(stderr, "Invalid frame bounds: %d %d\n", nStartFrame, nEndFrame);
		return BAD_RETURN;
	}
	pFramesY = new short*[nFrames];
	pFramesU = new short*[nFrames];
	pFramesV = new short*[nFrames];
	for (int nFrame = 0; nFrame < nFrames; nFrame++) {
		pFramesY[nFrame] = new short[nPixelsPerChannel];
		pFramesU[nFrame] = new short[nPixelsPerChannel];
		pFramesV[nFrame] = new short[nPixelsPerChannel];
	}
	uchar* pBufferY = new uchar[nPixelsPerChannel];
	uchar* pBufferU = new uchar[nPixelsPerChannel/4];
	uchar* pBufferV = new uchar[nPixelsPerChannel/4];

	// Skip frames before start of subsequence
	FILE* pFile = fopen(pVideoFileName, "rb");
	if (pFile == NULL) {
		fprintf(stderr, "Video file cannot be opened: %s\n", pVideoFileName);
		return BAD_RETURN;
	}
	for (int nFrame = 1; nFrame < nStartFrame; nFrame++) {
		// Read Y frame
		size_t nRead = fread(pBufferY, 1, nPixelsPerChannel, pFile);
		// Read U frame
		nRead = fread(pBufferU, 1, nPixelsPerChannel/4, pFile);
		// Read V frame
		nRead = fread(pBufferV, 1, nPixelsPerChannel/4, pFile);
	} // end nFrame

	// Process frames of subsequence
	for (int nFrame = nStartFrame; nFrame <= nEndFrame; nFrame++) {
		// Read Y frame
		size_t nRead = fread(pBufferY, 1, nPixelsPerChannel, pFile);
		int nSrcStep = nWidth * sizeof(uchar);
		int nDstStep = nWidth * sizeof(short);
		IppiSize roiSize = {nWidth, nHeight};
		RECORD_SUCCESS( ippiConvert_8u16s_C1R((const Ipp8u*)pBufferY, nSrcStep, (Ipp16s*)pFramesY[nFrame-nStartFrame], nDstStep, roiSize), bSuccess );

		// Read U frame
		nRead = fread(pBufferU, 1, nPixelsPerChannel/4, pFile);
		nSrcStep = nWidth/2 * sizeof(uchar);
		nDstStep = nWidth/2 * sizeof(short);
		roiSize.width = nWidth/2;
		roiSize.height = nHeight/2;
		RECORD_SUCCESS( ippiConvert_8u16s_C1R((const Ipp8u*)pBufferU, nSrcStep, (Ipp16s*)pFramesU[nFrame-nStartFrame], nDstStep, roiSize), bSuccess );

		// Read V frame
		nRead = fread(pBufferV, 1, nPixelsPerChannel/4, pFile);
		RECORD_SUCCESS( ippiConvert_8u16s_C1R((const Ipp8u*)pBufferV, nSrcStep, (Ipp16s*)pFramesV[nFrame-nStartFrame], nDstStep, roiSize), bSuccess );
	}
	fclose(pFile);

	delete [] pBufferY;
	delete [] pBufferU;
	delete [] pBufferV;
	return bSuccess ? GOOD_RETURN : BAD_RETURN;

#else

	bool bSuccess = true;

	// Determine dimensions
	int nWidth, nHeight;
	if (resolution == QCIF) {
		nWidth = QCIF_WIDTH;
		nHeight = QCIF_HEIGHT;
	}
	else if (resolution == CIF) {
		nWidth = CIF_WIDTH;
		nHeight = CIF_HEIGHT;
	}
	else if (resolution == FOURCIF) {
		nWidth = FOURCIF_WIDTH;
		nHeight = FOURCIF_HEIGHT;
	}
	else if (resolution == SIXTEENCIF) {
		nWidth = SIXTEENCIF_WIDTH;
		nHeight = SIXTEENCIF_HEIGHT;
	}
	int nPixelsPerChannel = nWidth * nHeight;
	
	// Allocate space
	int nFrames = nEndFrame - nStartFrame + 1;
	if (nFrames <= 0) {
		fprintf(stderr, "Invalid frame bounds: %d %d\n", nStartFrame, nEndFrame);
		return BAD_RETURN;
	}
	pFramesY = new short*[nFrames];
	pFramesU = new short*[nFrames];
	pFramesV = new short*[nFrames];
	for (int nFrame = 0; nFrame < nFrames; nFrame++) {
		pFramesY[nFrame] = new short[nPixelsPerChannel];
		pFramesU[nFrame] = new short[nPixelsPerChannel];
		pFramesV[nFrame] = new short[nPixelsPerChannel];
	}
	uchar* pBufferY = new uchar[nPixelsPerChannel];
	uchar* pBufferU = new uchar[nPixelsPerChannel/4];
	uchar* pBufferV = new uchar[nPixelsPerChannel/4];

	// Skip frames before start of subsequence
	FILE* pFile = fopen(pVideoFileName, "rb");
	if (pFile == NULL) {
		fprintf(stderr, "Video file cannot be opened: %s\n", pVideoFileName);
		return BAD_RETURN;
	}
	for (int nFrame = 1; nFrame < nStartFrame; nFrame++) {
		// Read Y frame
		size_t nRead = fread(pBufferY, 1, nPixelsPerChannel, pFile);
		// Read U frame
		nRead = fread(pBufferU, 1, nPixelsPerChannel/4, pFile);
		// Read V frame
		nRead = fread(pBufferV, 1, nPixelsPerChannel/4, pFile);
	} // end nFrame

	// Process frames of subsequence
	for (int nFrame = nStartFrame; nFrame <= nEndFrame; nFrame++) {
		// Read Y frame
		size_t nRead = fread(pBufferY, 1, nPixelsPerChannel, pFile);
		for (int ii = 0; ii < nPixelsPerChannel; ii++)
		{
			pFramesY[nFrame-nStartFrame][ii] = pBufferY[ii];
		}
		// Read U frame
		nRead = fread(pBufferU, 1, nPixelsPerChannel/4, pFile);		
		for (int ii = 0; ii < nPixelsPerChannel/4; ii++)
		{
			pFramesU[nFrame-nStartFrame][ii] = pBufferU[ii];
		}
		// Read V frame
		nRead = fread(pBufferV, 1, nPixelsPerChannel/4, pFile);		
		for (int ii = 0; ii < nPixelsPerChannel/4; ii++)
		{
			pFramesV[nFrame-nStartFrame][ii] = pBufferV[ii];
		}
	}
	fclose(pFile);

	delete [] pBufferY;
	delete [] pBufferU;
	delete [] pBufferV;
	return bSuccess ? GOOD_RETURN : BAD_RETURN;

#endif

}

int ChenVideo_motionCompensateInterpolate(const int nWidth, const int nHeight, const int nBlockSize, const int nMaxShift, const short* pSrc1, const short* pSrc2, const short* pShiftsX, const short* pShiftsY, short* pDst)
{
	bool bSuccess = true;

	// Set local variables
	int nPixels = nWidth * nHeight;
	int nBlockRows = nHeight / nBlockSize;
	int nBlockCols = nWidth / nBlockSize;
	int nBlocks = nBlockRows * nBlockCols;
	int nBlockPixels = nBlockSize * nBlockSize;
	short* pShiftedImg = new short[nPixels];
	short* pResidual = new short[nPixels];

	// Shift both source images to all possible shift positions
	int nShifts1D = 2*nMaxShift+1;
	int nShifts2D = nShifts1D * nShifts1D;
	short* pShifted = new short[nPixels];
	short* pShiftedStore1 = new short[nPixels * nShifts2D];
	short* pShiftedStore2 = new short[nPixels * nShifts2D];
	for (int nShiftY = -nMaxShift; nShiftY <= nMaxShift; nShiftY++) {
		for (int nShiftX = -nMaxShift; nShiftX <= nMaxShift; nShiftX++) {
			int nShift = (nShiftY+nMaxShift)*nShifts1D + (nShiftX+nMaxShift);

			// Shift source 1
			RECORD_SUCCESS( ChenImage_shiftImage(nWidth, nHeight, pSrc1, nShiftX, nShiftY, pShifted), bSuccess );
			int nStoreStart = nShift*nPixels;
			memcpy(pShiftedStore1+nStoreStart, pShifted, nPixels*sizeof(short));

			// Shift source 2
			RECORD_SUCCESS( ChenImage_shiftImage(nWidth, nHeight, pSrc2, nShiftX, nShiftY, pShifted), bSuccess );
			memcpy(pShiftedStore2+nStoreStart, pShifted, nPixels*sizeof(short));
		} // end nShiftX
	} // end nShiftY

	// Perform blockwise motion-compensated interpolation
	short* pBlock1 = new short[nBlockPixels];
	short* pBlock2 = new short[nBlockPixels];
	for (int nBlockRow = 0; nBlockRow < nBlockRows; nBlockRow++) {
		for (int nBlockCol = 0; nBlockCol < nBlockCols; nBlockCol++) {
			int nBlock = nBlockRow*nBlockCols + nBlockCol;

			// Form half motion vector
			short nShiftX = pShiftsX[nBlock] / 2;
			short nShiftY = pShiftsY[nBlock] / 2;
			int nShift = (nShiftY+nMaxShift)*nShifts1D + (nShiftX+nMaxShift);
			int nShiftStart = nShift*nPixels;

			// Extract block from shifted source 1
			for (int nRow = 0; nRow < nBlockSize; nRow++) {
				for (int nCol = 0; nCol < nBlockSize; nCol++) {
					pBlock1[nRow*nBlockSize + nCol] = pShiftedStore1[nShiftStart + (nBlockRow*nBlockSize + nRow)*nWidth + (nBlockCol*nBlockSize + nCol)];
				}
			}

			// Extract block from shifted source 2
			for (int nRow = 0; nRow < nBlockSize; nRow++) {
				for (int nCol = 0; nCol < nBlockSize; nCol++) {
					pBlock2[nRow*nBlockSize + nCol] = pShiftedStore2[nShiftStart + (nBlockRow*nBlockSize + nRow)*nWidth + (nBlockCol*nBlockSize + nCol)];
				}
			}

			// Average blocks and place in output
			for (int nRow = 0; nRow < nBlockSize; nRow++) {
				for (int nCol = 0; nCol < nBlockSize; nCol++) {
					pBlock1[nRow*nBlockSize + nCol] += pBlock2[nRow*nBlockSize + nCol];
					pBlock1[nRow*nBlockSize + nCol] /= 2;
					pDst[(nBlockRow*nBlockSize + nRow)*nWidth + (nBlockCol*nBlockSize + nCol)] = pBlock1[nRow*nBlockSize + nCol];
				}
			}
		}
	} // end nBlockRow

	delete [] pShiftedImg;
	delete [] pResidual;
	delete [] pShiftsX;
	delete [] pShiftsY;
	delete [] pShifted;
	delete [] pShiftedStore1;
	delete [] pShiftedStore2;
	return bSuccess ? GOOD_RETURN : BAD_RETURN;
}

int ChenVideo_motionCompensateInterpolateYUV(const int nWidth, const int nHeight, const int nBlockSize, const int nMaxShift, const short** pSrc1, const short** pSrc2, short** pDst)
{
	bool bSuccess = true;

	// Set local variables
	int nPixels = nWidth * nHeight;
	int nBlockRows = nHeight / nBlockSize;
	int nBlockCols = nWidth / nBlockSize;
	int nBlocks = nBlockRows * nBlockCols;
	int nBlockPixels = nBlockSize * nBlockSize;

	// Perform block matching between Y components
	short* pShiftsX = new short[nBlocks];
	short* pShiftsY = new short[nBlocks];
	short* pShiftedImg = new short[nPixels];
	short* pResidual = new short[nPixels];
	RECORD_SUCCESS( ChenImage_imageBlockMatch2D(nWidth, nHeight, nBlockSize, nMaxShift, pSrc1[0], pSrc2[0], pShiftedImg, pResidual, pShiftsX, pShiftsY), bSuccess );

	// Motion-compensated interpolation for Y component
	RECORD_SUCCESS( ChenVideo_motionCompensateInterpolate(nWidth, nHeight, nBlockSize, nMaxShift, pSrc1[0], pSrc2[0], pShiftsX, pShiftsY, pDst[0]), bSuccess );

	// Motion-compensated interpolation for U,V components
	for (int nChannel = 1; nChannel <= 2; nChannel++) {
		RECORD_SUCCESS( ChenImage_imageBlockMatch2D(nWidth/2, nHeight/2, nBlockSize, nMaxShift, pSrc1[nChannel], pSrc2[nChannel], pShiftedImg, pResidual, pShiftsX, pShiftsY), bSuccess );
		RECORD_SUCCESS( ChenVideo_motionCompensateInterpolate(nWidth/2, nHeight/2, nBlockSize, nMaxShift, pSrc1[nChannel], pSrc2[nChannel], pShiftsX, pShiftsY, pDst[nChannel]), bSuccess );
	}

	delete [] pShiftsX;
	delete [] pShiftsY;
	delete [] pShiftedImg;
	delete [] pResidual;
	return bSuccess ? GOOD_RETURN : BAD_RETURN;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -