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

📄 motionsearcher.hh

📁 Motion JPEG编解码器源代码
💻 HH
📖 第 1 页 / 共 5 页
字号:
							== (*itHere).m_tnMotionY);						++itNext;#endif // NDEBUG												// Check just that one pixel-group.						PIXELINDEX tnX							= (m_tnX + (*itHere).m_tnMotionX);						PIXELINDEX tnY							= (m_tnY + (*itHere).m_tnMotionY);						if (tnX < 0 || tnX >= m_tnWidth - PGW + 1						|| tnY < 0 || tnY >= m_tnHeight - PGH + 1)							continue;						const SearchWindowCell &rCell							= m_oSearchWindow.GetCell (tnY, tnX);						if (rCell.m_pForward != NULL)						{							assert (rCell.m_tnX								== m_tnX + (*itHere).m_tnMotionX);							assert (rCell.m_tnY								== m_tnY + (*itHere).m_tnMotionY);								if (rCell.IsWithinTolerance (oCurrentGroup,								m_tnTolerance#ifdef THROTTLE_PIXELSORTER_WITH_SAD											 , tnSAD#endif // THROTTLE_PIXELSORTER_WITH_SAD													))							{#ifdef PRINT_SEARCHBORDER								if (frame == 61 && DIM == 2)								fprintf (stderr, "Found match at "									"(%d,%d), motion vector (%d,%d)\n",									int (m_tnX), int (m_tnY),									int (rCell.m_tnX - m_tnX),									int (rCell.m_tnY - m_tnY));#endif#ifndef USE_SEARCH_BORDER	#error Expand-regions code needs the search-border#endif // USE_SEARCH_BORDER								// Add this match to our growing set of								// moved regions.								FRAMESIZE tnThisMatch									= m_oSearchBorder.AddNewMatch										(a_reStatus, rCell);								if (a_reStatus != g_kNoError)									return;									// That's one more match.								++tnMatches;									// Keep track of the smallest/largest								// region.								tnSmallestMatch = Min (tnSmallestMatch,									tnThisMatch);								tnLargestMatch = Max (tnLargestMatch,									tnThisMatch);							}						}					}				}#endif // EXPAND_REGIONS					// If the expanding-regions code couldn't run, or if it				// didn't find any matches, then use the pixel-sorter to				// find matches for the current pixel-group.				if (tnMatches == 0)				{					// HACK					//fprintf (stderr, ", consulting pixel-sorter.\n");	#ifndef THROTTLE_PIXELSORTER_WITH_SAD					PIXELINDEX tnBestMotionX, tnBestMotionY;					FRAMESIZE tnBestMotionXXYY;						// The best match found, and its length.#endif // THROTTLE_PIXELSORTER_WITH_SAD					// Set up the search-window in a radius around the					// current pixel-group.					m_oSearchWindow.PrepareForSearch (a_reStatus, true);					if (a_reStatus != g_kNoError)						return;										// Search for matches for the current pixel-group					// within the search radius.					m_oSearchWindow.StartSearch (itMatch,						oCurrentGroup);#ifdef THROTTLE_PIXELSORTER_WITH_SAD					m_setMatches.Clear();					while (pMatch = m_oSearchWindow.FoundNextMatch						(itMatch, tnSAD), pMatch != NULL)#else // THROTTLE_PIXELSORTER_WITH_SAD					tnBestMotionX = m_tnSearchRadiusX + 1;					tnBestMotionY = m_tnSearchRadiusY + 1;					tnBestMotionXXYY = FRAMESIZE (tnBestMotionX)						* FRAMESIZE (tnBestMotionX)						+ FRAMESIZE (tnBestMotionY)						* FRAMESIZE (tnBestMotionY);					while (pMatch = m_oSearchWindow.FoundNextMatch						(itMatch), pMatch != NULL)#endif // THROTTLE_PIXELSORTER_WITH_SAD					{#ifdef PRINT_SEARCHBORDER						if (frame == 61 && DIM == 2)						fprintf (stderr, "Found match at (%d,%d), "							"motion vector (%d,%d)\n",							int (m_tnX), int (m_tnY),							int (pMatch->m_tnX - m_tnX),							int (pMatch->m_tnY - m_tnY));#endif // PRINT_SEARCHBORDER								// Make sure this match is within the search						// radius.						assert (AbsoluteValue (pMatch->m_tnX - m_tnX)							<= m_tnSearchRadiusX);						assert (AbsoluteValue (pMatch->m_tnY - m_tnY)							<= m_tnSearchRadiusY);		#ifdef THROTTLE_PIXELSORTER_WITH_SAD						// If this match is better than our worst so						// far, get rid of our worst & use the new one						// instead.						if (m_setMatches.Size()							== m_nMatchCountThrottle)						{							typename MatchedPixelGroupSet::Iterator									itWorst;								// The worst match found so far.									// Get the worst match.  (It's at the end of							// the list.)							itWorst = m_setMatches.End();							--itWorst;									// If the new item is better than our worst,							// get rid of our worst to make room for the							// new item.							if (tnSAD < (*itWorst).m_tnSAD)								m_setMatches.Erase (itWorst);						}								// If this match is close enough to the current						// pixel-group, make a note of it.						if (m_setMatches.Size() < m_nMatchCountThrottle)						{							m_setMatches.Insert (a_reStatus,								MatchedPixelGroup (tnSAD, pMatch));							if (a_reStatus != g_kNoError)								return;						}#else // THROTTLE_PIXELSORTER_WITH_SAD#ifdef USE_SEARCH_BORDER						// Add this match to our growing set of moved						// regions.						FRAMESIZE tnThisMatch							= m_oSearchBorder.AddNewMatch (a_reStatus,								*pMatch);						if (a_reStatus != g_kNoError)							return;						// Keep track of the smallest/largest region.						tnSmallestMatch = Min (tnSmallestMatch,							tnThisMatch);						tnLargestMatch = Max (tnLargestMatch,							tnThisMatch);#else // USE_SEARCH_BORDER						PIXELINDEX tnMotionX, tnMotionY;						FRAMESIZE tnMotionXXYY;							// The motion vector of this match.						// Calculate the motion vector of this match.						tnMotionX = pMatch->m_tnX - m_tnX;						tnMotionY = pMatch->m_tnY - m_tnY;						tnMotionXXYY = FRAMESIZE (tnMotionX)							* FRAMESIZE (tnMotionX)							+ FRAMESIZE (tnMotionY)							* FRAMESIZE (tnMotionY);						// If this is the best match so far (i.e. the						// one closest to the origin), use it.  (This						// isn't a great test, but it's the one that						// was accidentally being used for a long time,						// and the results seemed OK, so what the heck.)						if (tnBestMotionXXYY > tnMotionXXYY)						{							tnBestMotionXXYY = tnMotionXXYY;							tnBestMotionX = tnMotionX;							tnBestMotionY = tnMotionY;						}#endif // USE_SEARCH_BORDER							// That's one more match.						++tnMatches;#endif // THROTTLE_PIXELSORTER_WITH_SAD					}		#ifdef THROTTLE_PIXELSORTER_WITH_SAD					// Now loop through all the good matches found,					// flood-fill each one, and use the first one that					// fills a large enough area.					for (itBestMatch = m_setMatches.Begin();						 itBestMatch != m_setMatches.End();						 ++itBestMatch)					{						PIXELINDEX tnMotionX, tnMotionY;							// The motion vector of this match.						// Get the current match.						const MatchedPixelGroup &rMatch = *itBestMatch;						// Calculate its motion vector.						tnMotionX = rMatch.m_pGroup->m_tnX - m_tnX;						tnMotionY = rMatch.m_pGroup->m_tnY - m_tnY;#ifdef USE_SEARCH_BORDER						// Add this match to our growing set of moved						// regions.						FRAMESIZE tnThisMatch							= m_oSearchBorder.AddNewMatch (a_reStatus,								tnMotionX, tnMotionY);						if (a_reStatus != g_kNoError)							return;							// That's one more match.						++tnMatches;							// Keep track of the smallest/largest region.						tnSmallestMatch = Min (tnSmallestMatch,							tnThisMatch);						tnLargestMatch = Max (tnLargestMatch,							tnThisMatch);#else // USE_SEARCH_BORDER						// Set up a region describing the current						// pixel-group.						m_oMatchThrottleRegion.Clear();						{							PIXELINDEX tnY;								// Used to loop through the								// pixel-group's lines.							for (tnY = m_tnY;								 tnY < m_tnY + PGH;								 ++tnY)							{								m_oMatchThrottleRegion.Merge									(a_reStatus, tnY, m_tnX,									m_tnX + PGW);								if (a_reStatus != g_kNoError)									return;							}						}								// Set its motion vector.						m_oMatchThrottleRegion.SetMotionVector							(tnMotionX, tnMotionY);						// Flood-fill this match, so as to get its full						// extent.						m_oMatchThrottleFloodFillControl							.SetupForFloodFill (tnMotionX, tnMotionY);						m_oMatchThrottleRegion.FloodFill (a_reStatus,							m_oMatchThrottleFloodFillControl, false);						if (a_reStatus != g_kNoError)							return;						// Get the size of the flood-filled region.						FRAMESIZE tnThisMatch							= m_oMatchThrottleRegion.NumberOfPoints();						// If this match is big enough, keep it.						if (tnThisMatch							>= m_nMatchSizeThrottle * PGH * PGW)						{							ApplyRegionToNewFrame (a_reStatus,								m_oMatchThrottleRegion);							if (a_reStatus != g_kNoError)								return;									// That's one more match.							++tnMatches;							// That's more pixels found by							// flood-filling.							if (tnMotionX == 0 && tnMotionY == 0)								tnNotMovedFloodedPixels									+= tnThisMatch;							else								tnFloodedPixels += tnThisMatch;									// Stop looking.							break;						}#endif // USE_SEARCH_BORDER					}					// All done with the matches.					m_setMatches.Clear();#else // THROTTLE_PIXELSORTER_WITH_SAD#ifndef USE_SEARCH_BORDER					// Now flood-fill the best match and apply it to					// the new frame.					if (tnMatches > 0)					{						PIXELINDEX tnY;							// Used to loop through the pixel-group							// lines.							// Set up the region with the current						// pixel-group.						m_oMatchThrottleRegion.Clear();						for (tnY = m_tnY;							 tnY < m_tnY + PGH;							 ++tnY)						{							m_oMatchThrottleRegion.Union (a_reStatus,								tnY, m_tnX, m_tnX + PGW);							if (a_reStatus != g_kNoError)								return;						}									// Set its motion vector.						m_oMatchThrottleRegion.SetMotionVector							(tnBestMotionX, tnBestMotionY);							// Flood-fill this match, so as to get its full						// extent.						m_oMatchThrottleFloodFillControl							.SetupForFloodFill (tnBestMotionX,								tnBestMotionY);						m_oMatchThrottleRegion.FloodFill (a_reStatus,							m_oMatchThrottleFloodFillControl, false);						if (a_reStatus != g_kNoError)							return;							// Get the size of the flood-filled region.						FRAMESIZE tnThisMatch							= m_oMatchThrottleRegion.NumberOfPoints();							// Apply the match to the new frame right now.						ApplyRegionToNewFrame (a_reStatus,							m_oMatchThrottleRegion);						if (a_reStatus != g_kNoError)							return;							// That's more pixels found by flood-filling.						if (tnBestMotionX == 0 && tnBestMotionY == 0)							tnNotMovedFloodedPixels += tnThisMatch;						else							tnFloodedPixels += tnThisMatch;					}#endif // !USE_SEARCH_BORDER#endif // THROTTLE_PIXELSORTER_WITH_SAD				}					// If no matches were found for the current pixel-group,				// and there are no active border-regions in the area,				// then we've found new information.				// NOTE: this dramatically speeds up the analysis of				// frames that contain mostly new info, but probably				// impacts quality.  Flood-fills are allowed to override				// the result, though.				if (tnMatches == 0#ifdef USE_SEARCH_BORDER					&& m_oSearchBorder.NumberOfActiveRegions() == 0#endif // USE_SEARCH_BORDER																   )				{					PIXELINDEX tnX, tnY;					for (tnY = m_tnY; tnY < m_tnY + PGH; ++tnY)					{						for (tnX = m_tnX; tnX < m_tnX + PGW; ++tnX)						{							// Allocate a new reference pixel.							ReferencePixel_t *pNewPixel								= m_oPixelPool.Allocate();											// Store the new pixel in the reference							// frame.							m_pNewFrame->SetPixel (tnX, tnY, pNewPixel);											// Give it the value from the new frame.							pNewPixel->AddSample (a_pPixels[tnY								* m_tnWidth + tnX]);						}					}				}#ifdef USE_SEARCH_BORDER				// If it's time to flood-fill, do so.				if (tnMatches >= FRAMESIZE (m_nMatchCountThrottle)					|| tnLargestMatch >= FRAMESIZE						(m_nMatchSizeThrottle * PGH * PGW))				{					FRAMESIZE tnFlooded;					PIXELINDEX tnMotionX, tnMotionY;						// Take the biggest region that the current					// pixel-group matched, flood-fill it, and apply it					// to the new frame now, eliminating all competing					// moved-regions.					tnFlooded = SearchBorder_FloodFill (a_reStatus,						tnMotionX, tnMotionY);					if (a_reStatus != g_kNoError)						return;	#if 0					// HACK					fprintf (stderr, "Match throttle: frame %d, "						"x %03d, y %03d, %03d matches, "

⌨️ 快捷键说明

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