searchborder.hh
来自「Motion JPEG编解码器源代码」· HH 代码 · 共 2,118 行 · 第 1/5 页
HH
2,118 行
{ for (itActive = m_setBorderRegions.Begin(); itActive != m_setBorderRegions.End(); itActive = itNextActive) { // Get the next item, since we may remove the current item. itNextActive = itActive; ++itNextActive; // If this region reference came from the last-border, get // rid of it. if ((*itActive).m_tnLine == m_tnY - 1) m_setBorderRegions.Erase (itActive); } } // The old last-border is gone, and we have a new current-border. // So move all our startpoint/endpoint iterators back one, and // create a new one for the new current-border. for (i = 1; i <= m_tnPGH; ++i) { m_paitBorderStartpoints[i-1] = m_paitBorderStartpoints[i]; m_paitBorderEndpoints[i-1] = m_paitBorderEndpoints[i]; } m_paitBorderStartpoints[m_tnPGH] = m_setBorderStartpoints.End(); m_paitBorderEndpoints[m_tnPGH] = m_setBorderEndpoints.End(); // Any region with (if m_tnX == 0) a last-border startpoint at // m_tnPGW or (if m_tnX == m_tnWidth - m_tnPGW) a last-border // endpoint of m_tnX will no longer be contiguous with the current // pixel-group, but they will be the next time the search border // moves left/right. // (But not if we're past the bottom line. This happens when we're // called by FinishFrame().) if (m_tnY < m_tnHeight - m_tnPGH) { typename IntersectingRegionsSet::Iterator itRemove; // An item being removed from the possibly-intersecting set. if (m_tnX == 0) { // Get the iterator we'll be using. typename BorderExtentBoundarySet::ConstIterator &ritBorder = m_paitBorderStartpoints[0]; #ifndef NDEBUG // Make sure it's right where we want to be. { typename BorderExtentBoundarySet::ConstIterator itPrev = ritBorder; --itPrev; assert (ritBorder == m_setBorderStartpoints.End() || (*ritBorder).m_tnLine > m_tnY || ((*ritBorder).m_tnLine == m_tnY && ((*ritBorder).m_tnIndex > m_tnPGW && (itPrev == m_setBorderStartpoints.End() || (*itPrev).m_tnLine < m_tnY || ((*itPrev).m_tnLine == m_tnY && (*itPrev).m_tnIndex <= m_tnPGW))))); }#endif // NDEBUG // Remove all active regions that have startpoints at this // index. while ((--ritBorder) != m_setBorderStartpoints.End() && (*ritBorder).m_tnLine == m_tnY && (*ritBorder).m_tnIndex == m_tnPGW) {#ifdef PRINT_SEARCHBORDER if (frame == 61) fprintf (stderr, "Moving down a line, remove " "active-border region (%d,%d), " "motion vector (%d,%d)\n", (*ritBorder).m_tnIndex, (*ritBorder).m_tnLine, (*ritBorder).m_tnMotionX, (*ritBorder).m_tnMotionY);#endif itRemove = m_setBorderRegions.Find (*ritBorder); #ifdef PRINT_SEARCHBORDER if (frame == 61 && itRemove == m_setBorderRegions.End()) { fprintf (stderr, "NOT FOUND!\n" "Here's what was found:\n"); for (itRemove = m_setBorderRegions.Begin(); itRemove != m_setBorderRegions.End(); ++itRemove) { fprintf (stderr, "\t(%d,%d), " "motion vector (%d,%d)\n", (*itRemove).m_tnIndex, (*itRemove).m_tnLine, (*itRemove).m_tnMotionX, (*itRemove).m_tnMotionY); } }#endif assert (itRemove != m_setBorderRegions.End()); m_setBorderRegions.Erase (itRemove); } ++ritBorder; } else { assert (m_tnX == m_tnWidth - m_tnPGW); // Get the iterator we'll be using. typename BorderExtentBoundarySet::ConstIterator &ritBorder = m_paitBorderEndpoints[0]; #ifndef NDEBUG // Make sure it's right where we expect it to be. { typename BorderExtentBoundarySet::ConstIterator itPrev = ritBorder; --itPrev; assert (ritBorder == m_setBorderEndpoints.End() || (*ritBorder).m_tnLine > m_tnY || ((*ritBorder).m_tnLine == m_tnY && (*ritBorder).m_tnIndex >= m_tnX && (itPrev == m_setBorderEndpoints.End() || (*itPrev).m_tnLine < m_tnY || ((*itPrev).m_tnLine == m_tnY && (*itPrev).m_tnIndex < m_tnX)))); }#endif // NDEBUG // Remove all active regions that have endpoints at this // index. while (ritBorder != m_setBorderEndpoints.End() && (*ritBorder).m_tnLine == m_tnY && (*ritBorder).m_tnIndex == m_tnX) { // Move to the corresponding startpoint. const BorderExtentBoundary &rHere = *((*ritBorder).m_pCounterpart);#ifdef PRINT_SEARCHBORDER if (frame == 61) fprintf (stderr, "Moving down a line, remove " "active-border region (%d,%d), " "motion vector (%d,%d)\n", rHere.m_tnIndex, rHere.m_tnLine, rHere.m_tnMotionX, rHere.m_tnMotionY);#endif itRemove = m_setBorderRegions.Find (rHere); #ifdef PRINT_SEARCHBORDER if (frame == 61 && itRemove == m_setBorderRegions.End()) { fprintf (stderr, "NOT FOUND!\n" "Here's what was found:\n"); for (itRemove = m_setBorderRegions.Begin(); itRemove != m_setBorderRegions.End(); ++itRemove) { fprintf (stderr, "\t(%d,%d), " "motion vector (%d,%d)\n", (*itRemove).m_tnIndex, (*itRemove).m_tnLine, (*itRemove).m_tnMotionX, (*itRemove).m_tnMotionY); } }#endif assert (itRemove != m_setBorderRegions.End()); m_setBorderRegions.Erase (itRemove); ++ritBorder; } } // Finally, move one step down, and prepare to move the other // direction across the window. (But not if we're past the // bottom line, i.e. being called by FinishFrame().) ++m_tnY; m_tnStepX = -m_tnStepX; }}// Return the number of regions that would intersect with the// current pixel-group.template <class PIXELINDEX, class FRAMESIZE>inline FRAMESIZESearchBorder<PIXELINDEX,FRAMESIZE>::NumberOfActiveRegions (void) const{ // Easy enough. return m_setBorderRegions.Size();}// Accept a new match for a pixel-group, with the given motion-vector.template <class PIXELINDEX, class FRAMESIZE>FRAMESIZESearchBorder<PIXELINDEX,FRAMESIZE>::AddNewMatch (Status_t &a_reStatus, PIXELINDEX a_tnMotionX, PIXELINDEX a_tnMotionY){ PIXELINDEX tnI, tnJ; // Used to loop through things. typename IntersectingRegionsSet::Iterator itHere; // The range of regions that are contiguous with the newly-added // pixel-group. bool bLastBorderExtentFound; // true if the current pixel-group merged with a region that // had an extent on the last-boundary. MovedRegion *pRegionMergedTo; RegionUnderConstruction *pRegionUnderConstructionMergedTo; // The region that receives the new pixel-group, as well as any // other region that's now contiguous with it. // May be a brand-new region. BorderExtentBoundary *aStart, *aEnd; // Used to search for the range of regions contiguous with the // new pixel-group, as well as to set up the new startpoints and // endpoints for the current-border and last-border. typename BorderExtentBoundarySet::Iterator *aitCurrentStarts, *aitCurrentEnds; // Where the startpoints/endpoints gets hooked into the // current-boundary/last-boundary. typename IntersectingRegionsSet::Iterator *aitCurrentRegions; // Where the new/merged region gets hooked into the // possibly-intersecting list of regions. // Allocate memory for our temporary arrays. aStart = (BorderExtentBoundary *) alloca (ARRAYSIZE (BorderExtentBoundary, m_tnPGH + 1)); aEnd = (BorderExtentBoundary *) alloca (ARRAYSIZE (BorderExtentBoundary, m_tnPGH + 1)); aitCurrentStarts = (typename BorderExtentBoundarySet::Iterator *) alloca (ARRAYSIZE (typename BorderExtentBoundarySet::Iterator, m_tnPGH + 1)); aitCurrentEnds = (typename BorderExtentBoundarySet::Iterator *) alloca (ARRAYSIZE (typename BorderExtentBoundarySet::Iterator, m_tnPGH + 1)); aitCurrentRegions = (typename IntersectingRegionsSet::Iterator *) alloca (ARRAYSIZE (typename IntersectingRegionsSet::Iterator, m_tnPGH + 1));#if 0 // (Why isn't this working??? It's not strictly necessary, but I // like to be clean.) // Construct the objects in our temporary arrays. for (tnI = 0; tnI < m_tnPGH + 1; ++tnI) { typedef typename BorderExtentBoundarySet::Iterator BorderExtentBoundarySetIterator; typedef typename IntersectingRegionsSet::Iterator IntersectingRegionsSetIterator; aStart[tnI].BorderExtentBoundary(); aEnd[tnI].BorderExtentBoundary(); aitCurrentStarts[tnI].BorderExtentBoundarySetIterator(); aitCurrentEnds[tnI].BorderExtentBoundarySetIterator(); aitCurrentRegions[tnI].IntersectingRegionsSetIterator(); }#endif // m_setBorderRegions contains all the regions that would intersect // with a pixel-group match at the current location, so we just // search for the subset with the same motion-vector. aStart[0].m_tnMotionX = a_tnMotionX; aStart[0].m_tnMotionY = a_tnMotionY; aStart[0].m_bIsEnding = false; itHere = m_setBorderRegions.LowerBound (aStart[0]); // Create the initial startpoint/endpoint for the current-border // and last-border. If we find any regions that intersect with the // new pixel-group, these will get adjusted. for (tnI = 0; tnI <= m_tnPGH; ++tnI) { aStart[tnI].m_tnMotionX = aEnd[tnI].m_tnMotionX = a_tnMotionX; aStart[tnI].m_tnMotionY = aEnd[tnI].m_tnMotionY = a_tnMotionY; aStart[tnI].m_bIsEnding = false; aEnd[tnI].m_bIsEnding = true; aStart[tnI].m_tnIndex = m_tnX; aEnd[tnI].m_tnIndex = m_tnX + m_tnPGW; aStart[tnI].m_tnLine = aEnd[tnI].m_tnLine = m_tnY + tnI - PIXELINDEX (1); } // We only add a last-border extent if the current pixel-group // got merged with a region that had a last-border extent (since the // current pixel-group doesn't have a last-border extent itself). // Set up to detect that. bLastBorderExtentFound = false; aStart[0].m_tnIndex = Limits<PIXELINDEX>::Max; aEnd[0].m_tnIndex = Limits<PIXELINDEX>::Min; // Do any existing regions intersect with the new pixel-group? if (itHere == m_setBorderRegions.End() || (*itHere).m_tnMotionX != aStart[0].m_tnMotionX || (*itHere).m_tnMotionY != aStart[0].m_tnMotionY) {#ifdef PRINT_SEARCHBORDER if (frame == 61) fprintf (stderr, "Create a new region for the match.\n");#endif // No. Create a new region. pRegionMergedTo = new MovedRegion (a_reStatus); if (pRegionMergedTo == NULL) goto cleanup0; if (a_reStatus != g_kNoError) goto cleanup1; // Set its motion vector. pRegionMergedTo->SetMotionVector (a_tnMotionX, a_tnMotionY); // Create something to manage the region as it's being // constructed. pRegionUnderConstructionMergedTo = new RegionUnderConstruction; if (pRegionUnderConstructionMergedTo == NULL) goto cleanup1; pRegionUnderConstructionMergedTo->m_pRegion = pRegionMergedTo; // Regions under construction form a circular list with all // other under-construction regions that it gets merged with. // So start the circular list. pRegionUnderConstructionMergedTo->m_pForward = pRegionUnderConstructionMergedTo->m_pBackward = pRegionUnderConstructionMergedTo; } // Some existing regions intersect with the current pixel-group. else {#ifdef PRINT_SEARCHBORDER if (frame == 61) fprintf (stderr, "This match is contiguous with an existing " "region!\n");#endif // Get the first region that's contiguous with the new // pixel-group. pRegionUnderConstructionMergedTo = (*itHere).m_pRegion; pRegionMergedTo = pRegionUnderConstructionMergedTo->m_pRegion;#ifdef PRINT_SEARCHBORDER if (frame == 61) { fprintf (stderr, "Region to merge to:\n"); PrintRegion (*pRegionMergedTo); fprintf (stderr, "\n"); }#endif // Now loop through all the regions that'll get merged with the // current pixel-group (including the first one that we already // looked at). Incorporate the startpoint/endpoint associated // with that region into our new startpoint/endpoint. Then, if // it's a different region than the first one we looked at, // merge it into that first one. Finally, remove the found // startpoints/endpoints -- they'll be superseded by the // merged-region's startpoints/endpoints. while (itHere != m_setBorderRegions.End() && (*itHere).m_tnMotionX == aStart[0].m_tnMotionX && (*itHere).m_tnMotionY == aStart[0].m_tnMotionY) { typename IntersectingRegionsSet::Iterator itNext; // The next item in the possibly-intersecting-region // set. Needed because we remove the current item. PIXELINDEX tnBorderIndex; // Which current-border it's on. Ranges from 0 (the // last-border) to 1 (the first current-border) to // m_tnPGH (the last current-border). MovedRegion *pRegionMergedFrom; RegionUnderConstruction *pRegionUnderConstructionMergedFrom; // The latest region that's contiguous with the new // pixel-group. typename BorderExtentBoundarySet::Iterator itStart, itEnd; // The location of the startpoint/endpoint of the latest // region that's contiguous with the new pixel-group. // (And they all lived in the house that Jack built, so // NYAAAH!) // Before we have a chance to remove the current item, // remember the next item, so that we can move to it later. itNext = itHere; ++itNext; // Figure out which border this new region is on. tnBorderIndex = (*itHere).m_tnLine - m_tnY + 1; // (Sanity check: there should be no last-border regions // if there is no last-border.) assert (tnBorderIndex > 0 || m_tnY > 0);#ifdef PRINT_SEARCHBORDER if (frame == 61) fprintf (stderr, "Search for startpoint (%d,%d)\n", (*itHere).m_tnIndex, (*itHere).m_tnLine);#endif // Find the startpoint/endpoint. itStart = m_setBorderStartpoints.Find (*itHere); assert (itStart != m_setBorderStartpoints.End()); assert (*itStart == *itHere); itEnd = m_setBorderEndpoints.Find (*((*itStart).m_pCounterpart)); assert (itEnd != m_setBorderEndpoints.End()); // (Sanity check: make sure the endpoint knows it's paired // with this startpoint.) assert ((*itEnd).m_pCounterpart == &(*itStart)); // (Sanity check: make sure they refer to the same region // under construction.) assert ((*itStart).m_pRegion == (*itEnd).m_pRegion); // Remove the merged-from region from the list of // possibly-intersecting regions. assert (m_setBorderRegions.LowerBound (*itHere) // sanity == itHere); m_setBorderRegions.Erase (itHere); // Extend our new startpoint/endpoint by this region's // startpoint/endpoint. aStart[tnBorderIndex].m_tnIndex = Min (aStart[tnBorderIndex].m_tnIndex, (*itStart).m_tnIndex); aEnd[tnBorderIndex].m_tnIndex = Max (aEnd[tnBorderIndex].m_tnIndex, (*itEnd).m_tnIndex); // (If that was on the last-border, remember that.)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?