searchborder.hh
来自「Motion JPEG编解码器源代码」· HH 代码 · 共 2,118 行 · 第 1/5 页
HH
2,118 行
if (tnBorderIndex == 0) bLastBorderExtentFound = true; // Get the region that'll be merged from. pRegionUnderConstructionMergedFrom = (*itStart).m_pRegion; pRegionMergedFrom = pRegionUnderConstructionMergedFrom ->m_pRegion; // If this region is different than the first region we // looked at, merge it with that first region. if (pRegionMergedFrom != pRegionMergedTo) { RegionUnderConstruction *pCurrentRUC, *pNextRUC; // The regions under construction that we move to // the merged-to region's circular list.#ifdef PRINT_SEARCHBORDER if (frame == 61) { fprintf (stderr, "Region to merge from:\n"); PrintRegion (*pRegionMergedFrom); fprintf (stderr, "\n"); }#endif // Merge the regions together. (Merge() only works on // regions that don't already intersect, for speed // reasons; the way we manage the border ensures that. // How handy for us.) pRegionMergedTo->Merge (*pRegionMergedFrom); // Run through the circular list of regions under // construction, the ones pointing to the merged-from // region, update each one to point to the merged-to // region, and put each one into the merged-to region's // circular list. pCurrentRUC = pRegionUnderConstructionMergedFrom; for (;;) { // Remember the next region in the circular list. pNextRUC = pCurrentRUC->m_pForward; // (Sanity check: make sure everyone in this // circular list points to the same region.) assert (pCurrentRUC->m_pRegion == pRegionMergedFrom); // Update the region it refers to. pCurrentRUC->m_pRegion = pRegionMergedTo; // Move it into the merged-to region's circular // list. pCurrentRUC->Remove(); pRegionUnderConstructionMergedTo->InsertBefore (pRegionUnderConstructionMergedTo, pCurrentRUC); // If all regions have been removed from this // circular list, stop. if (pCurrentRUC == pNextRUC) break; // Move to the next region in the circular list. pCurrentRUC = pNextRUC; } } // Finally, remove the startpoint/endpoint we found for this // region, adjusting reference counts & cleaning up as // necessary. assert (m_setBorderEndpoints.LowerBound (*itEnd) == itEnd); // sanity for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ) if (m_paitBorderEndpoints[tnJ] == itEnd) ++m_paitBorderEndpoints[tnJ]; m_setBorderEndpoints.Erase (itEnd); assert (m_setBorderStartpoints.LowerBound (*itStart) == itStart); // sanity for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ) if (m_paitBorderStartpoints[tnJ] == itStart) ++m_paitBorderStartpoints[tnJ]; m_setBorderStartpoints.Erase (itStart); pRegionUnderConstructionMergedFrom->m_tnReferences -= 2; if (pRegionUnderConstructionMergedFrom != pRegionUnderConstructionMergedTo && pRegionUnderConstructionMergedFrom->m_tnReferences == 0) { // This region under construction, now pointing to the // merged-to region, has no more references to it. Get // rid of it. assert (pRegionUnderConstructionMergedFrom->m_pRegion == pRegionMergedTo); assert (pRegionUnderConstructionMergedFrom->m_pForward != pRegionUnderConstructionMergedFrom); pRegionUnderConstructionMergedFrom->Remove(); pRegionUnderConstructionMergedFrom->m_pRegion = NULL; delete pRegionUnderConstructionMergedFrom; } // We're done with this region. if (pRegionMergedFrom != pRegionMergedTo) delete pRegionMergedFrom; // Move to the next item in the set. itHere = itNext; } } // At this point, the region that contains the new pixel-group has // either been created, or it's been retrieved from the // possibly-intersecting set, and all regions that are contiguous // with the new pixel-group have been merged into it. But the new // pixel-group hasn't been added yet in either case. // Add the pixel-group's extents to this new/merged region. { PIXELINDEX tnY; // Used to loop through the pixel-group's lines.#ifdef PRINTREGIONMATH bool bRegionEmpty = ((pRegionMergedTo->NumberOfPoints() == 0) ? true : false);#endif // PRINTREGIONMATH // Add each line in the pixel-group. for (tnY = m_tnY; tnY < m_tnY + m_tnPGH; ++tnY) {#ifdef PRINTREGIONMATH //if (!bRegionEmpty /* && frame == 4 */) { fprintf (stderr, "Before Union with [%d, %d-%d]:\n", int (tnY), int (m_tnX), int (m_tnX + m_tnPGW)); PrintRegion (*pRegionMergedTo); fprintf (stderr, "\n"); }#endif // PRINTREGIONMATH pRegionMergedTo->Union (a_reStatus, tnY, m_tnX, m_tnX + m_tnPGW); if (a_reStatus != g_kNoError) { // We couldn't add the new pixel-group. If this // region has no references, we have to delete it // now. (It could have no references because it's // newly created, or because all references to it // were removed from the search-border.) if (pRegionUnderConstructionMergedTo->m_tnReferences == 0) goto cleanup2; // Return with our error. return 0; }#ifdef PRINTREGIONMATH //if (!bRegionEmpty /* && frame == 4 */) { fprintf (stderr, "After Union with [%d, %d-%d]:\n", int (tnY), int (m_tnX), int (m_tnX + m_tnPGW)); PrintRegion (*pRegionMergedTo); fprintf (stderr, "\n"); getchar(); fprintf (stderr, "\n"); }#endif // PRINTREGIONMATH } }#ifdef PRINT_SEARCHBORDER if (frame == 61) { fprintf (stderr, "Final new/merged region:\n"); PrintRegion (*pRegionMergedTo); fprintf (stderr, "\n"); }#endif // Hook the new/merged region to our startpoints/endpoints. for (tnI = 0; tnI <= m_tnPGH; ++tnI) aStart[tnI].m_pRegion = aEnd[tnI].m_pRegion = pRegionUnderConstructionMergedTo; // Add all startpoint/endpoints to the current-boundary lines. for (tnI = 0; tnI <= m_tnPGH; ++tnI) { // (If there is no last-border extent, skip adding the // last-border startpoint/endpoint.) if (tnI == 0 && !bLastBorderExtentFound) continue; // Add this startpoint to the current-boundary. { typename BorderExtentBoundarySet::InsertResult oInsertResult = m_setBorderStartpoints.Insert (a_reStatus, aStart[tnI]); if (a_reStatus != g_kNoError) goto cleanup5; assert (oInsertResult.m_bInserted); // Remember where it got inserted. aitCurrentStarts[tnI] = oInsertResult.m_itPosition; // That's one more reference to this region under // construction. ++pRegionUnderConstructionMergedTo->m_tnReferences; // If this new item was inserted before the current item on // this line, and it's got an equivalent index value, it // becomes the new current item. if (m_tnStepX == 1) { ++oInsertResult.m_itPosition; for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ) { if (m_paitBorderStartpoints[tnJ] == oInsertResult.m_itPosition && ((*aitCurrentStarts[tnI]).m_tnLine > m_tnY + tnJ - PIXELINDEX (1) || ((*aitCurrentStarts[tnI]).m_tnLine == m_tnY + tnJ - PIXELINDEX (1) && (*aitCurrentStarts[tnI]).m_tnIndex >= (m_tnX + m_tnPGW + 1 - ((tnJ == 0) ? 1 : 0))))) { --m_paitBorderStartpoints[tnJ]; assert (m_paitBorderStartpoints[tnJ] == aitCurrentStarts[tnI]); } } } else { assert (m_tnStepX == -1); ++oInsertResult.m_itPosition; for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ) { if (m_paitBorderStartpoints[tnJ] == oInsertResult.m_itPosition && ((*aitCurrentStarts[tnI]).m_tnLine > m_tnY + tnJ - PIXELINDEX (1) || ((*aitCurrentStarts[tnI]).m_tnLine == m_tnY + tnJ - PIXELINDEX (1) && (*aitCurrentStarts[tnI]).m_tnIndex > (m_tnX + m_tnPGW - ((tnJ == 0) ? 1 : 0))))) { --m_paitBorderStartpoints[tnJ]; assert (m_paitBorderStartpoints[tnJ] == aitCurrentStarts[tnI]); } } } } // Add this endpoint to the current-boundary. { typename BorderExtentBoundarySet::InsertResult oInsertResult = m_setBorderEndpoints.Insert (a_reStatus, aEnd[tnI]); if (a_reStatus != g_kNoError) goto cleanup3; assert (oInsertResult.m_bInserted); // Remember where it got inserted. aitCurrentEnds[tnI] = oInsertResult.m_itPosition; // That's one more reference to this region under // construction. ++pRegionUnderConstructionMergedTo->m_tnReferences; // If this new item was inserted before the current item on // this line, and it's got an equivalent index value, it // becomes the new current item. if (m_tnStepX == 1) { ++oInsertResult.m_itPosition; for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ) { if (m_paitBorderEndpoints[tnJ] == oInsertResult.m_itPosition && ((*aitCurrentEnds[tnI]).m_tnLine > m_tnY + tnJ - PIXELINDEX (1) || ((*aitCurrentEnds[tnI]).m_tnLine == m_tnY + tnJ - PIXELINDEX (1) && (*aitCurrentEnds[tnI]).m_tnIndex >= (m_tnX + ((tnJ == 0) ? 1 : 0))))) { --m_paitBorderEndpoints[tnJ]; assert (m_paitBorderEndpoints[tnJ] == aitCurrentEnds[tnI]); } } } else { ++oInsertResult.m_itPosition; for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ) { if (m_paitBorderEndpoints[tnJ] == oInsertResult.m_itPosition && ((*aitCurrentEnds[tnI]).m_tnLine > m_tnY + tnJ - PIXELINDEX (1) || ((*aitCurrentEnds[tnI]).m_tnLine == m_tnY + tnJ - PIXELINDEX (1) && (*aitCurrentEnds[tnI]).m_tnIndex > (m_tnX - 1 + ((tnJ == 0) ? 1 : 0))))) { --m_paitBorderEndpoints[tnJ]; assert (m_paitBorderEndpoints[tnJ] == aitCurrentEnds[tnI]); } } } } // Now that startpoint & endpoint are inserted, we can set up // their counterpart links. (*aitCurrentStarts[tnI]).m_pCounterpart = &(*aitCurrentEnds[tnI]); (*aitCurrentEnds[tnI]).m_pCounterpart = &(*aitCurrentStarts[tnI]); // Add this region under construction to the list of regions // that intersect with the current pixel-group. (Since this // new region contains the current pixel-group, obviously it // intersects.) { typename IntersectingRegionsSet::InsertResult oInsertResult = m_setBorderRegions.Insert (a_reStatus, *(aitCurrentStarts[tnI])); if (a_reStatus != g_kNoError) goto cleanup4; assert (oInsertResult.m_bInserted); // Remember where it got inserted, in case the operation // fails and we have to clean up after ourselves. aitCurrentRegions[tnI] = oInsertResult.m_itPosition; #ifdef PRINT_SEARCHBORDER if (frame == 61) { fprintf (stderr, "Inserted border startpoint " "(%d,%d), motion vector (%d,%d)\n", (*aitCurrentRegions[tnI]).m_tnIndex, (*aitCurrentRegions[tnI]).m_tnLine, (*aitCurrentRegions[tnI]).m_tnMotionX, (*aitCurrentRegions[tnI]).m_tnMotionY); fprintf (stderr, "\tcorresponding endpoint at (%d,%d)\n", (*aitCurrentEnds[tnI]).m_tnIndex, (*aitCurrentEnds[tnI]).m_tnLine); }#endif } } // If this is the first added match, then the last-border startpoint // and endpoint start off as one past the last item on its line, // i.e. the first item on the next line, i.e. the first item in the // set. if (m_paitBorderStartpoints[0] == m_setBorderStartpoints.End() && m_paitBorderEndpoints[0] == m_setBorderEndpoints.End()) {#ifdef PRINT_SEARCHBORDER if (frame == 61) fprintf (stderr, "Initialized last-border " "startpoint/endpoint.\n");#endif // PRINT_SEARCHBORDER m_paitBorderStartpoints[0] = m_setBorderStartpoints.Begin(); m_paitBorderEndpoints[0] = m_setBorderEndpoints.Begin(); } // All done. return pRegionMergedTo->NumberOfPoints(); // Handle errors.cleanup5: for (;;) { m_setBorderRegions.Erase (aitCurrentRegions[tnI]);cleanup4: for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ) if (m_paitBorderEndpoints[tnJ] == aitCurrentEnds[tnI]) ++m_paitBorderEndpoints[tnJ]; m_setBorderEndpoints.Erase (aitCurrentEnds[tnI]); --pRegionUnderConstructionMergedTo->m_tnReferences;cleanup3: for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ) if (m_paitBorderStartpoints[tnJ] == aitCurrentStarts[tnI]) ++m_paitBorderStartpoints[tnJ]; m_setBorderStartpoints.Erase (aitCurrentStarts[tnI]); --pRegionUnderConstructionMergedTo->m_tnReferences; if (tnI == 0) break; --tnI; if (m_tnY == 0 && tnI == 0) // skip nonexistent last-borders break; }cleanup2: if (pRegionUnderConstructionMergedTo->m_tnReferences == 0) { if (pRegionUnderConstructionMergedTo->m_pForward == pRegionUnderConstructionMergedTo) delete pRegionMergedTo; pRegionUnderConstructionMergedTo->Remove(); pRegionUnderConstructionMergedTo->m_pRegion = NULL; delete pRegionUnderConstructionMergedTo; } return 0;cleanup1: delete pRegionMergedTo;cleanup0: return 0;}// Remove all regions that matched the current pixel-group, except for// the single best one, and return it.template <class PIXELINDEX, class FRAMESIZE>typename SearchBorder<PIXELINDEX,FRAMESIZE>::MovedRegion *SearchBorder<PIXELINDEX,FRAMESIZE>::ChooseBestActiveRegion (Status_t &a_reStatus){ RegionUnderConstruction *pUn
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?