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

📄 invtelec.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		for (i = 0; i < PULLDOWN_HIST_LEN; i++)
		{
			state->pulldownTimeHist[i] = timestamp;
		}
		state->lastRemovedTimestamp = timestamp;
		state->firstFrame = FALSE;
		goto TOO_EARLY;
	}

	// Calculate Sum of Differences for even and odd lines...
	// If we know that the frame is de-interlaced, then the stats
	// for the "odd" lines are invalid.  So just measure "even"
	// lines then copy into "odd" SAD (so the rest of the algorithm
	// will work).
	ll = (pels >> 2);

	if (bDeInterlaced)
	{
		pNew = (LONG32 *)data;
		pOld = (LONG32 *)prevData;
		ll = (pels >> 2);

		for (i = 0; i < lines; i += 2)  //  only do the luma.
		{
			for (j = 0; j < ll; j++)
			{
				temp = (float)((pNew[j]&0xff00) - (pOld[j]&0xFF00));
				sumEven += ((float)(1./(256.*256.)))*(temp*temp);
			}

			pOld += 2*ll;
			pNew += 2*ll;
		}
		sumOdd = sumEven;
	}
	else
	{
		switch (state->impl_id)
		{
#ifdef ALLOW_MMX_INVTELE
		case INVTELE_IMPL_ID_MMX:
			{
				SumSqaredFrameDiff_MMX(
					data, prevData,
					pels, lines, pels,
					&sumEven, &sumOdd);
				sumAll = 0.5f * (sumEven + sumOdd);
			}
			break;
#endif
		case INVTELE_IMPL_ID_C:
		default:
			{
				pNew = (LONG32 *)data;
				pOld = (LONG32 *)prevData;

				for (i = 0; i < lines; i += 2)  //  only do the luma.
				{
					for (j = 0; j < ll; j++)
					{
						temp = (float)((pNew[j]&0xff00) - (pOld[j]&0xFF00));
						sumEven += ((float)(1./(256.*256.)))*(temp*temp);
						temp = (float)((pNew[j+ll]&0xFF00) - (pOld[j+ll]&0xFF00));
						sumOdd += ((float)(1./(256.*256.)))*(temp*temp);
					}

					pOld += 2*ll;
					pNew += 2*ll;
				}
				sumAll = sumEven + sumOdd;
				sumEven /= (ll * (lines>>1));
				sumOdd /= (ll * (lines>>1));
				sumAll /= (ll * lines);
			}
			break;
		}
	}

	sceneChangeFlag = (sumAll > 7500)?(TRUE):(FALSE);
	if (sumEven > 100) sumEven=100;
	if (sumOdd > 100) sumOdd=100;
	if (sumAll > 100) sumAll=100;

#ifdef CODEC_DEBUG_32PULLDOWN
	fprintf(fp_log,"ssd are %f %f at time %d\n",sumEven,sumOdd,timestamp);
#endif

	// Compensate for 30 vs 29.97fps captures.
	if ((sumEven == 0) && (sumOdd == 0) && 
		(state->NTSCTrackingFrameCounter > 500) && (frameRate > 29.98))
	{
		state->pulldownTimeHist[PULLDOWN_HIST_LEN-1] = timestamp;
		state->NTSCTrackingFrameCounter = 0;
 		goto REMOVE_FRAME;
	}
	state->NTSCTrackingFrameCounter++;

	// In case we dropped a frame
	timeSinceLastFrame = CALCULATE_ELAPSED_TICKS(state->pulldownTimeHist[PULLDOWN_HIST_LEN-1], timestamp);

	while(timeSinceLastFrame > 50)
	{
		for(i=0;i<PULLDOWN_HIST_LEN-1;i++)
		{
			state->pulldownSadHistEven[i] = state->pulldownSadHistEven[i+1];
			state->pulldownSadHistOdd[i] = state->pulldownSadHistOdd[i+1];
			state->pulldownSadHistAll[i] = state->pulldownSadHistAll[i+1];
			state->pulldownTimeHist[i] = state->pulldownTimeHist[i+1];
		}

		state->pulldownSadHistEven[i] = MISSING_SAD;
		state->pulldownSadHistOdd[i] = MISSING_SAD;
		state->pulldownSadHistAll[i] = MISSING_SAD;
		state->pulldownTimeHist[i] = timestamp;
		timeSinceLastFrame -= 33;
		state->frameRemovalPattern--;
		if (state->frameRemovalPattern < 0)
			state->frameRemovalPattern = 4;
		state->frameCountMod--;
		if (state->frameCountMod < 0)
			state->frameCountMod = 4;
	}

	//  Update the history 
	for(i = 0; i < PULLDOWN_HIST_LEN - 1; i++)
	{
		state->pulldownSadHistEven[i] = state->pulldownSadHistEven[i+1];
		state->pulldownSadHistOdd[i] = state->pulldownSadHistOdd[i+1];
		state->pulldownSadHistAll[i] = state->pulldownSadHistAll[i+1];
		state->pulldownTimeHist[i] = state->pulldownTimeHist[i+1];
	}
	state->frameRemovalPattern--;
	if (state->frameRemovalPattern < 0)
		state->frameRemovalPattern = 4;
	state->frameCountMod--;
	if (state->frameCountMod < 0)
		state->frameCountMod = 4;

	state->pulldownSadHistEven[i] = sumEven;
	state->pulldownSadHistOdd[i] = sumOdd;
	state->pulldownSadHistAll[i] = sumAll;
	state->pulldownTimeHist[i] = timestamp;

	// If removal on, and we have no pattern established, wait a while.
	if ((state->pulldownSadHistEven[PULLDOWN_HIST_LEN - 5] == UN_INIT_SAD) || 
		(state->pulldownSadHistOdd[PULLDOWN_HIST_LEN - 5] == UN_INIT_SAD) || 
		(state->pulldownSadHistAll[PULLDOWN_HIST_LEN - 5] == UN_INIT_SAD))
	{
#ifdef CODEC_DEBUG_32PULLDOWN
		fprintf(fp_log,"gotoing - too early\n");
#endif
		goto TOO_EARLY;
	}

	histLength = 0;

	while (state->pulldownSadHistAll[histLength] == UN_INIT_SAD)
	{
		histLength += 5;
		if (histLength > PULLDOWN_HIST_LEN - 10)
			goto TOO_EARLY;
	}

	if ((bDeInterlaced) || (state->ulPulldownActiveTimerProg > 90 && state->ulPulldownActiveTimerIntl < 10))
	{
		// Skip interlaced telecine tests
		goto PROGRESSIVE_TESTS;
	}

	// Gather statistics from SAD history
	// Run through tests looking at the last 20, then 15, then 10, then 5 frames
	for (patternStart = histLength; patternStart < PULLDOWN_HIST_LEN; patternStart += 5)
	{
		for (i = 0; i < 5;i++)
		{
			// Stats for "even" lines
			inGroupMeanEven[i]  = 0;
			outGroupMeanEven[i] = 0;
			inGroupStdEven[i]   = 0;
			outGroupStdEven[i]  = 0;
			inGroupCountEven    = 0;
			outGroupCountEven   = 0;
			outMinEven[i] = 255*255;
			inMinEven[i]  = 255*255;
			outMaxEven[i] = 0;
			inMaxEven[i]  = 0;
			for (j = patternStart + i; j < PULLDOWN_HIST_LEN; j++)
			{
				if (state->pulldownSadHistEven[j] == MISSING_SAD ||
					state->pulldownSadHistEven[j] == UN_INIT_SAD)
					continue;

				if (((j - i) % 5) == 0)
				{
					inGroupMeanEven[i] += state->pulldownSadHistEven[j];
					inGroupStdEven[i] += state->pulldownSadHistEven[j]*state->pulldownSadHistEven[j];
					if (inMaxEven[i] < state->pulldownSadHistEven[j])
						inMaxEven[i] = state->pulldownSadHistEven[j];
					if (inMinEven[i] > state->pulldownSadHistOdd[j])
						inMinEven[i] = state->pulldownSadHistOdd[j];
					inGroupCountEven++;
				}
				else
				{
					outGroupMeanEven[i]+= state->pulldownSadHistEven[j];
					outGroupStdEven[i]+= state->pulldownSadHistEven[j]*state->pulldownSadHistEven[j];
					if (outMinEven[i] > state->pulldownSadHistEven[j])
						outMinEven[i] = state->pulldownSadHistEven[j];
					if (outMaxEven[i] < state->pulldownSadHistEven[j])
						outMaxEven[i] = state->pulldownSadHistEven[j];
					outGroupCountEven++;
				}
			}
			// Is there enough valid data to analyze?
			if ((inGroupCountEven > 1) && (outGroupCountEven > 3))
			{
				inGroupMeanEven[i] = inGroupMeanEven[i]/inGroupCountEven;
				if ((inGroupStdEven[i]/inGroupCountEven)-(inGroupMeanEven[i]*inGroupMeanEven[i]) > 0.0f)
					inGroupStdEven[i] = (float)sqrt((inGroupStdEven[i]/inGroupCountEven)-(inGroupMeanEven[i]*inGroupMeanEven[i]));
				else
					inGroupStdEven[i] = 0.0f;

				outGroupMeanEven[i] = outGroupMeanEven[i]/outGroupCountEven;
				if ((outGroupStdEven[i]/outGroupCountEven)-(outGroupMeanEven[i]*outGroupMeanEven[i]) > 0.0f)
					outGroupStdEven[i] = (float)sqrt((outGroupStdEven[i]/outGroupCountEven)-(outGroupMeanEven[i]*outGroupMeanEven[i]));
				else
					outGroupStdEven[i] = 0.0f;

				groupValidFlagEven[i] = TRUE;
			}
			else
			{
				inGroupMeanEven[i] = 0;
				outGroupMeanEven[i] = 0;
				inGroupStdEven[i] = 1;
				outGroupStdEven[i] = 1;
				groupValidFlagEven[i] = FALSE;
			}

			// Stats for "odd" lines
			inGroupMeanOdd[i]  = 0;
			outGroupMeanOdd[i] = 0;
			inGroupStdOdd[i]   = 0;
			outGroupStdOdd[i]  = 0;
			inGroupCountOdd    = 0;
			outGroupCountOdd   = 0;
			outMinOdd[i] = 255*255;
			inMinOdd[i]  = 255*255;
			outMaxOdd[i] = 0;
			inMaxOdd[i]  = 0;
			for (j = patternStart + i; j < PULLDOWN_HIST_LEN; j++)
			{
				if (state->pulldownSadHistOdd[j] == MISSING_SAD ||
					state->pulldownSadHistOdd[j] == UN_INIT_SAD)
					continue;

				if (((j - i) % 5) == 0)
				{
					inGroupMeanOdd[i] += state->pulldownSadHistOdd[j];
					inGroupStdOdd[i] += state->pulldownSadHistOdd[j]*state->pulldownSadHistOdd[j];
					if (inMaxOdd[i] < state->pulldownSadHistOdd[j])
						inMaxOdd[i] = state->pulldownSadHistOdd[j];
					if (inMinOdd[i] > state->pulldownSadHistOdd[j])
						inMinOdd[i] = state->pulldownSadHistOdd[j];
					inGroupCountOdd++;
				}
				else
				{
					outGroupMeanOdd[i] += state->pulldownSadHistOdd[j];
					outGroupStdOdd[i] += state->pulldownSadHistOdd[j]*state->pulldownSadHistOdd[j];
					if (outMinOdd[i] > state->pulldownSadHistOdd[j])
						outMinOdd[i] = state->pulldownSadHistOdd[j];
					if (outMaxOdd[i] < state->pulldownSadHistOdd[j])
						outMaxOdd[i] = state->pulldownSadHistOdd[j];
					outGroupCountOdd++;
				}
			}
			// Is there enough valid data to analyze?
			if ((inGroupCountOdd > 1) && (outGroupCountOdd > 3))
			{
				inGroupMeanOdd[i] = inGroupMeanOdd[i]/inGroupCountOdd;
				if ((inGroupStdOdd[i]/inGroupCountOdd)-(inGroupMeanOdd[i]*inGroupMeanOdd[i]) > 0.0f)
					inGroupStdOdd[i] = (float)sqrt((inGroupStdOdd[i]/inGroupCountOdd)-(inGroupMeanOdd[i]*inGroupMeanOdd[i]));
				else
					inGroupStdOdd[i] = 0.0f;

				outGroupMeanOdd[i] = outGroupMeanOdd[i]/outGroupCountOdd;
				if ((outGroupStdOdd[i]/outGroupCountOdd)-(outGroupMeanOdd[i]*outGroupMeanOdd[i]) > 0.0f)
					outGroupStdOdd[i] = (float)sqrt((outGroupStdOdd[i]/outGroupCountOdd)-(outGroupMeanOdd[i]*outGroupMeanOdd[i]));
				else
					outGroupStdOdd[i] = 0.0f;

				groupValidFlagOdd[i] = TRUE;
			}
			else
			{
				inGroupMeanOdd[i] = 0;
				outGroupMeanOdd[i] = 0;
				inGroupStdOdd[i] = 1;
				outGroupStdOdd[i] = 1;
				groupValidFlagOdd[i] = FALSE;
			}
		}

		// Do we have a clear pattern? Always trust this test.
		for (i = 0; i < 5; i++)
		{
			if (groupValidFlagEven[i] == FALSE)
				continue;
			if (groupValidFlagOdd[i] == FALSE)
				continue;
			if (groupValidFlagEven[(i+2)%5] == FALSE)
				continue;
			if (groupValidFlagOdd[(i+2)%5] == FALSE)
				continue;

			if ((inGroupMeanEven[i]+inThresh[patternStart]*inGroupStdEven[i] < outGroupMeanEven[i] - outThresh[patternStart]*outGroupStdEven[i]) &&
				(inGroupMeanOdd[(i+2)%5]+inThresh[patternStart]*inGroupStdOdd[(i+2)%5] < outGroupMeanOdd[(i+2)%5] - outThresh[patternStart]*outGroupStdOdd[(i+2)%5]) &&
				(inGroupMeanEven[i]+inGroupStdEven[i] < inGroupMeanOdd[i]) &&
				(inGroupMeanOdd[(i+2)%5]+inGroupStdOdd[(i+2)%5] < inGroupMeanEven[(i+2)%5]))
			{
#ifdef CODEC_DEBUG_32PULLDOWN
				fprintf(fp_log,"clear pattern, i is %d, pulldown timer is %d, patternStart is %d\n",i,state->ulPulldownActiveTimerIntl,patternStart);
#endif
				// Set the removal pattern phase
				state->frameRemovalPattern = i;

				// If this is the right frame remove it!
				if (i == (PULLDOWN_HIST_LEN - 1) % 5)
				{
					// Set a counter that goes up if we have a consistent pattern 80+% of the time, down otherwise
					if ((timestamp - state->lastRemovedTimestamp > 145) &&
						(timestamp - state->lastRemovedTimestamp < 175))
					{
						if (state->ulPulldownActiveTimerIntl < 95)
							state->ulPulldownActiveTimerIntl += 5;
						else
						{
							state->ulPulldownActiveTimerIntl = 100;
							state->bInterlacedTelecineSeen = TRUE;
						}

						if (state->ulPulldownActiveTimerProg > 5)
							state->ulPulldownActiveTimerProg -= 5;
						else
							state->ulPulldownActiveTimerProg = 0;
					}
					else if (timestamp - state->lastRemovedTimestamp < 300)
					{
						if (state->ulPulldownActiveTimerIntl > 5)
							state->ulPulldownActiveTimerIntl -= 5;
						else
							state->ulPulldownActiveTimerIntl = 0;
					}
					state->lastRemovedTimestamp = timestamp;

					goto REMOVE_FRAME;
				}
				else if (i == ((PULLDOWN_HIST_LEN - 2) % 5))
				{
					obviousPatternFlag = TRUE;
					goto INTERLEAVE_ODD;
				}
				else 
					goto DO_NOTHING;
			}

			if ((inGroupMeanOdd[i]+inThresh[patternStart]*inGroupStdOdd[i] < outGroupMeanOdd[i] - outThresh[patternStart]*outGroupStdOdd[i]) &&
				(inGroupMeanEven[(i+2)%5]+inThresh[patternStart]*inGroupStdEven[(i+2)%5] < outGroupMeanEven[(i+2)%5] - outThresh[patternStart]*outGroupStdEven[(i+2)%5]) &&
				(inGroupMeanOdd[i]+inGroupStdOdd[i] < inGroupMeanEven[i]) &&
				(inGroupMeanEven[(i+2)%5]+inGroupStdEven[(i+2)%5] < inGroupMeanOdd[(i+2)%5]))
			{
#ifdef CODEC_DEBUG_32PULLDOWN
				fprintf(fp_log,"clear pattern, i is %d, pulldown timer is %d, patternStart is %d\n",i,state->ulPulldownActiveTimerIntl,patternStart);
#endif
				// Set the removal pattern phase
				state->frameRemovalPattern=i;

				// If this is the right frame remove it!
				if (i == (PULLDOWN_HIST_LEN - 1) % 5)
				{
					// Set a counter that goes up if we have a consistent pattern 80+% of the time, down otherwise
					if ((timestamp - state->lastRemovedTimestamp > 145) &&
						(timestamp - state->lastRemovedTimestamp < 175))
					{
						if (state->ulPulldownActiveTimerIntl < 95)
							state->ulPulldownActiveTimerIntl += 5;
						else
						{
							state->ulPulldownActiveTimerIntl = 100;
							state->bInterlacedTelecineSeen = TRUE;
						}

						if (state->ulPulldownActiveTimerProg > 5)
							state->ulPulldownActiveTimerProg -= 5;
						else
							state->ulPulldownActiveTimerProg = 0;
					}
					else if (timestamp - state->lastRemovedTimestamp < 300)
					{
						if (state->ulPulldownActiveTimerIntl > 5)
							state->ulPulldownActiveTimerIntl -= 5;
						else
							state->ulPulldownActiveTimerIntl = 0;
					}
					state->lastRemovedTimestamp = timestamp;

					goto REMOVE_FRAME;
				}
				else if (i == ((PULLDOWN_HIST_LEN - 2) % 5))
				{

⌨️ 快捷键说明

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