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

📄 videosource.cpp

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					pp2[10] = 2;
				
			} else {

				memcpy(lpBuffer, (char *)mjpeg_reorder_buffer+lOffset, lLength);

				// 通过APP0标记在MJPEG头打补丁

				// FFD8 FFE0 0010 'AVI1' 极性

				if (((short *)lpBuffer)[1]==(short)0xE0FF)
					((char *)lpBuffer)[10] = 0;
			}

			return AVIERR_OK;
		} else {
			if (lSamplesRead)
				*lSamplesRead = 1;
			if (lBytesRead)
				*lBytesRead = lLength;

			return AVIERR_OK;
		}

	} else
		return pSource->Read(lStart, lCount, lpBuffer, cbBuffer, lBytesRead, lSamplesRead);
}

BOOL VideoSourceAVI::_isKey(LONG samp) {
	if ((mjpeg_mode & -2) == IFMODE_SPLIT1)
		samp = lSampleFirst + (samp - lSampleFirst)/2;

	if (key_flags) {
		samp -= lSampleFirst;

		return !!(key_flags[samp>>3] & (1<<(samp&7)));
	} else
		return pAVIStream->IsKeyFrame(samp);
}

LONG VideoSourceAVI::nearestKey(LONG lSample) {
	if (key_flags) {
		if (lSample < lSampleFirst || lSample >= lSampleLast)
			return -1;

		if (_isKey(lSample)) return lSample;

		return prevKey(lSample);
	}

//	if (lNear == -1)
//		throw MyError("VideoSourceAVI: error getting previous key frame");

	if ((mjpeg_mode & -2) == IFMODE_SPLIT1) {
		return pAVIStream->NearestKeyFrame(lSampleFirst + (lSample-lSampleFirst)/2)*2-lSampleFirst;
	} else {
		return pAVIStream->NearestKeyFrame(lSample);
	}
}

LONG VideoSourceAVI::prevKey(LONG lSample) {
	if ((mjpeg_mode & -2) == IFMODE_SPLIT1) {
		lSample = lSampleFirst + (lSample - lSampleFirst)/2;

		if (key_flags) {
			if (lSample >= lSampleLast) return -1;

			while(--lSample >= lSampleFirst)
				if (_isKey(lSample)) return lSample*2-lSampleFirst;

			return -1;
		} else
			return pAVIStream->PrevKeyFrame(lSample)*2-lSampleFirst;
	} else {
		if (key_flags) {
			if (lSample >= lSampleLast) return -1;

			while(--lSample >= lSampleFirst)
				if (_isKey(lSample)) return lSample;

			return -1;
		} else
			return pAVIStream->PrevKeyFrame(lSample);
	}
}

LONG VideoSourceAVI::nextKey(LONG lSample) {
	if ((mjpeg_mode & -2) == IFMODE_SPLIT1) {
		lSample = lSampleFirst + (lSample - lSampleFirst)/2;

		if (key_flags) {
			if (lSample < lSampleFirst) return -1;

			while(++lSample < lSampleLast)
				if (_isKey(lSample)) return lSample*2 - lSampleFirst;

			return -1;
		} else
			return pAVIStream->NextKeyFrame(lSample)*2 - lSampleFirst;

	} else {

		if (key_flags) {
			if (lSample < lSampleFirst) return -1;

			while(++lSample < lSampleLast)
				if (_isKey(lSample)) return lSample;

			return -1;
		} else
			return pAVIStream->NextKeyFrame(lSample);

	}
}

__int64 VideoSourceAVI::sampleOffset(LONG lSample)
{
	return pAVIStream->FramePos(lSample);
}

bool VideoSourceAVI::setDecompressedFormat(int depth) {
	VideoSource::setDecompressedFormat(depth);

	if (fUseGDI) {
		void *pv;
		HDC hdc;

		if (depth != 24 && depth != 32 && depth != 16)
			return false;

		if (hbmLame)
			DeleteObject(hbmLame);

		hbmLame = NULL;

		if (hdc = CreateCompatibleDC(NULL)) {
			hbmLame = CreateDIBSection(hdc, (BITMAPINFO *)bmihDecompressedFormat, DIB_RGB_COLORS, &pv, hBufferObject, 0);
			DeleteDC(hdc);
		}

		return true;

	} else if (mdec)
		return depth == 32 || depth == 16;
	else if (hicDecomp)
		return ICERR_OK == ICDecompressQuery(hicDecomp, getImageFormat(), bmihDecompressedFormat);
	else if (getImageFormat()->biCompression == '024I')
		return depth == 32;
	else
		return depth == 32 || depth == 24 || depth == 16;
}

bool VideoSourceAVI::setDecompressedFormat(BITMAPINFOHEADER *pbih) {
	if (pbih->biCompression == BI_RGB)
		return setDecompressedFormat(pbih->biBitCount);

	if (mdec)
		return false;

	if (hicDecomp && ICERR_OK == ICDecompressQuery(hicDecomp, getImageFormat(), pbih)) {
		memcpy(bmihDecompressedFormat, pbih, sizeof(BITMAPINFOHEADER));

		invalidateFrameBuffer();
		return true;
	}

	return false;
}

////////////////////////////////////////////////

void DIBconvert(void *src0, BITMAPINFOHEADER *srcfmt, void *dst0, BITMAPINFOHEADER *dstfmt) {
	if (srcfmt->biCompression == '2YUY')
//		VBitmap(dst0, dstfmt).BitBltFromYUY2(0, 0, &VBitmap(src0, srcfmt), 0, 0, -1, -1);
;
	else if (srcfmt->biCompression == '024I')
//		VBitmap(dst0, dstfmt).BitBltFromI420(0, 0, &VBitmap(src0, srcfmt), 0, 0, -1, -1);
;
	else
//		VBitmap(dst0, dstfmt).BitBlt(0, 0, &VBitmap(src0, srcfmt), 0, 0, -1, -1);
;
}

////////////////////////////////////////////////

void VideoSourceAVI::invalidateFrameBuffer() {
	if (lLastFrame != -1 && hicDecomp)
		ICDecompressEnd(hicDecomp);
	lLastFrame = -1;
}

BOOL VideoSourceAVI::isFrameBufferValid() {
	return lLastFrame != -1;
}

char VideoSourceAVI::getFrameTypeChar(long lFrameNum) {
	if (lFrameNum<lSampleFirst || lFrameNum >= lSampleLast)
		return ' ';

	if (_isKey(lFrameNum))
		return 'K';

	long lBytes, lSamples;
	int err = _read(lFrameNum, 1, NULL, 0, &lBytes, &lSamples);

	if (err != AVIERR_OK)
		return ' ';

	return lBytes ? ' ' : 'D';
}

bool VideoSourceAVI::isStreaming() {
	return pAVIStream->isStreaming();
}

bool VideoSourceAVI::isKeyframeOnly() {
   return pAVIStream->isKeyframeOnly();
}

bool VideoSourceAVI::isType1() {
   return bIsType1;
}

void VideoSourceAVI::streamBegin(bool fRealTime) {
	DWORD err;

	stream_current_frame	= -1;

	pAVIStream->BeginStreaming(lSampleFirst, lSampleLast, fRealTime ? 1000 : 2000);

	use_ICDecompressEx = FALSE;

	if (hicDecomp) {
		BITMAPINFOHEADER *bih_src = bmihTemp;
		BITMAPINFOHEADER *bih_dst = getDecompressedFormat();

		if (ICERR_OK != (err = ICDecompressBegin(
					hicDecomp,
					getImageFormat(),
					getDecompressedFormat()
					)))

			if (err == ICERR_UNSUPPORTED) {
				use_ICDecompressEx = TRUE;

				err = ICDecompressExBegin(
						hicDecomp,
						0,
						bih_src,
						NULL,
						0,0,
						bih_src->biWidth,bih_src->biHeight,
						bih_dst,
						lpvBuffer,
						0,0,
						bih_dst->biWidth,bih_dst->biHeight
						);
				
			}

			if (ICERR_UNSUPPORTED != err && ICERR_OK != err)
				throw MyICError("VideoSourceAVI", err);
	}
}

void *VideoSourceAVI::streamGetFrame(void *inputBuffer, LONG data_len, BOOL is_key, BOOL is_preroll, long frame_num) {
	DWORD err;

	if (!data_len) return getFrameBuffer();

	if (fUseGDI) {
		if (!hbmLame)
			throw MyError("Insufficient GDI resources to convert frame.");

		SetDIBits(NULL, hbmLame, 0, getDecompressedFormat()->biHeight, inputBuffer, (BITMAPINFO *)getFormat(),
			DIB_RGB_COLORS);
		GdiFlush();

	} else if (hicDecomp) {
		// Asus ASV1 crashes with zero byte frames!!!

		if (data_len) {
			BITMAPINFOHEADER *bih_src = bmihTemp;
			BITMAPINFOHEADER *bih_dst = getDecompressedFormat();

			bmihTemp->biSizeImage = data_len;

//			VDCHECKPOINT;
			if (use_ICDecompressEx)
				err = 	ICDecompressEx(
							hicDecomp,
	//						  (is_preroll ? ICDECOMPRESS_PREROLL : 0) |
	//						  | (data_len ? 0 : ICDECOMPRESS_NULLFRAME)
							  (is_key ? 0 : ICDECOMPRESS_NOTKEYFRAME),
							bih_src,
							inputBuffer,
							0,0,
							bih_src->biWidth, bih_src->biHeight,
							bih_dst,
							lpvBuffer,
							0,0,
							bih_dst->biWidth, bih_dst->biHeight
							);

			else
				err = 	ICDecompress(
							hicDecomp,
	//						  (is_preroll ? ICDECOMPRESS_PREROLL : 0) |
	//						  | (data_len ? 0 : ICDECOMPRESS_NULLFRAME)
							  (is_key ? 0 : ICDECOMPRESS_NOTKEYFRAME),
							bih_src,
							inputBuffer,
							bih_dst,
							lpvBuffer
							);
//			VDCHECKPOINT;

			if (ICERR_OK != err)
				throw MyICError(use_ICDecompressEx ? "VideoSourceAVI [ICDecompressEx]" : "VideoSourceAVI [ICDecompress]", err);
		}

	} else if (mdec) {

/*		try {
			if (getDecompressedFormat()->biBitCount == 32)
				mdec->decodeFrame32((unsigned long *)getFrameBuffer(), (unsigned char *)inputBuffer, data_len);
			else
				mdec->decodeFrame16((unsigned long *)getFrameBuffer(), (unsigned char *)inputBuffer, data_len);
		} catch(char *s) {
			throw MyError(s);
		}
*/
   } else {
      if (data_len < getImageFormat()->biSizeImage)
         throw MyError("VideoSourceAVI: uncompressed frame is short (expected %d bytes, got %d)", getImageFormat()->biSizeImage, data_len);

      DIBconvert(inputBuffer, getImageFormat(), getFrameBuffer(), getDecompressedFormat());
   }
//		memcpy(getFrameBuffer(), inputBuffer, getDecompressedFormat()->biSizeImage);

	return getFrameBuffer();
}

void VideoSourceAVI::streamEnd() {

	// If an error occurs, but no one is there to hear it, was
	// there ever really an error?

	if (hicDecomp) {
		if (use_ICDecompressEx)
			ICDecompressExEnd(hicDecomp);
		else
			ICDecompressEnd(hicDecomp);
	}

	pAVIStream->EndStreaming();

}

void *VideoSourceAVI::getFrame(LONG lFrameDesired) {
	void *dataBuffer = NULL;
	LONG dataBufferSize = 0;
	LONG lFrameKey, lFrameNum, lFrameErr=-1;
	LONG lBytesRead, lSamplesRead;
	DWORD err;
	int aviErr;

	// illegal frame number?

	if (lFrameDesired < lSampleFirst || lFrameDesired >= lSampleLast)
		throw MyError("VideoSourceAVI: bad frame # (%d not within [%d, %d])", lFrameDesired, lSampleFirst, lSampleLast-1);

	// do we already have this frame?

	if (lLastFrame == lFrameDesired)
		return getFrameBuffer();

	if (hicDecomp) {

		// back us off to the last key frame if we need to

		lFrameNum = lFrameKey = nearestKey(lFrameDesired);

		_RPT1(0,"Nearest key frame: %ld\n", lFrameKey);

		if (lLastFrame > lFrameKey && lLastFrame < lFrameDesired)
			lFrameNum = lLastFrame+1;

		// tell VCM we're going to do a little decompression...

		if (lLastFrame == -1) {
			err = ICDecompressBegin(hicDecomp, getImageFormat(), getDecompressedFormat());
			if (err != ICERR_OK) throw MyICError("VideoSourceAVI", err);
		}
	} else {
		lFrameNum = lFrameDesired;
	}

	_RPT2(0,"VideoSourceAVI: obtaining frame %ld, last was %ld\n", lFrameDesired, lLastFrame);

	try {
restart:
		do {
			_RPT1(0,"VideoSourceAVI: decompressing frame %ld\n", lFrameNum);

			for(;;) {
				if (!dataBuffer)
					aviErr = AVIERR_BUFFERTOOSMALL;
				else
					aviErr = read(lFrameNum, 1, dataBuffer, dataBufferSize, &lBytesRead, &lSamplesRead);

				if (aviErr == AVIERR_BUFFERTOOSMALL) {
					void *newDataBuffer;

					aviErr = read(lFrameNum, 1, NULL, 0, &lBytesRead, &lSamplesRead);

					if (aviErr) throw MyAVIError("VideoSourceAVI", aviErr);

					dataBufferSize = (lBytesRead+65535) & -65535;

					if (!(newDataBuffer = reallocmem(dataBuffer, dataBufferSize)))
						throw MyMemoryError();

					dataBuffer = newDataBuffer;

				} else if (aviErr) {
					throw MyAVIError("VideoSourceAVI", aviErr);
				} else {
//					if (hicDecomp || lBytesRead) break;
//					--lFrameNum;
					break;
				}
			};

			if (!lBytesRead) continue;

			if (fUseGDI)
				streamGetFrame(dataBuffer, lBytesRead, TRUE, FALSE, lFrameNum);
			else if (hicDecomp) {
				bmihTemp->biSizeImage = lBytesRead;

				if (lBytesRead) {
#if 0
					if( lFrameErr==lFrameNum ) {
						if( bit>16 ) {
							bit--;
							int byt = bit>>3;
							BYTE mask = 1 << (bit&7);
							BYTE *p = (BYTE*)dataBuffer;
							p[byt] ^= mask;
						} else {
							throw MyICError("VideoSourceAVI", err);
						}
					}
#endif
//					VDCHECKPOINT;
					if (ICERR_OK != (err = 	ICDecompress(
									hicDecomp,
//									  (lFrameNum<lFrameDesired ? ICDECOMPRESS_PREROLL : 0) |
//									  (lBytesRead ? 0 : ICDECOMPRESS_NULLFRAME) |
									  (lFrameNum > lFrameKey ? ICDECOMPRESS_NOTKEYFRAME : 0),
									bmihTemp,
									dataBuffer,
									getDecompressedFormat(),
									lpvBuffer))) {
#if 0
						if( lFrameErr==lFrameNum ) {
							//lFrameNum = lFrameKey;
							goto restart;
						}
						if( lFrameErr<0 ) {
							bit = lBytesRead*8;
							lFrameErr = lFrameNum;
							lFrameNum = lFrameKey;
							goto restart;
						}
#endif
						throw MyICError("VideoSourceAVI", err);
					}
#if 0
					if( lFrameErr>=0 && (lFrameNum==lFrameErr) ) {
						_RPT2(0,"VideoSourceAVI: frame %ld has errors, xoring bit %ld corrects it\n", lFrameNum, bit);
					}
#endif
//					VDCHECKPOINT;
				}
			} else if (mdec) {
/*				try {
					if (getDecompressedFormat()->biBitCount == 32)
						mdec->decodeFrame32((unsigned long *)getFrameBuffer(), (unsigned char *)dataBuffer, lBytesRead);
					else
						mdec->decodeFrame16((unsigned long *)getFrameBuffer(), (unsigned char *)dataBuffer, lBytesRead);
				} catch(char *s) {
					throw MyError(s);
				}
 */        } else {
            if (lBytesRead < getImageFormat()->biSizeImage)
               throw MyError("VideoSourceAVI: uncompressed frame is short (expected %d bytes, got %d)", getImageFormat()->biSizeImage, lBytesRead);

            DIBconvert(dataBuffer, getImageFormat(), getFrameBuffer(), getDecompressedFormat());
         }
//			} else memcpy(getFrameBuffer(), dataBuffer, getDecompressedFormat()->biSizeImage);

		} while(++lFrameNum <= lFrameDesired);

	} catch(MyError e) {
		if (dataBuffer) freemem(dataBuffer);
		ICDecompressEnd(hicDecomp);
		lLastFrame = -1;
		throw e;
	}

	if (dataBuffer) freemem(dataBuffer);
//	if (hicDecomp) ICDecompressEnd(hicDecomp);

	lLastFrame = lFrameDesired; 

	return getFrameBuffer();
}

⌨️ 快捷键说明

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