📄 umc_h264_task_supplier.cpp
字号:
SliceGroup++;
if (SliceGroup == (Ipp32s)uNumSliceGroups)
SliceGroup = 0;
prevMB = PrevMapUnit[SliceGroup];
NumThisGroup = 0;
}
if (prevMB >= 0)
{
// new
next_mb_tables[1][prevMB] = mbnum;
}
prevMB = mbnum;
NumThisGroup++;
}
}
m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[1];
break;
case 1:
// dispersed
{
Ipp32u row, col;
// Init PrevMapUnit to -1 (none), for first unit of each slice group
for (i=0; i<uNumSliceGroups; i++)
PrevMapUnit[i] = -1;
mbnum = FirstMB;
for (row = 0; row < uNumMBRows; row++)
{
SliceGroup = ((row * uNumSliceGroups)/2) % uNumSliceGroups;
for (col=0; col<uNumMBCols; col++)
{
prevMB = PrevMapUnit[SliceGroup];
if (prevMB != -1)
{
next_mb_tables[1][prevMB] = mbnum;
}
PrevMapUnit[SliceGroup] = mbnum;
mbnum++;
SliceGroup++;
if (SliceGroup == (Ipp32s)uNumSliceGroups)
SliceGroup = 0;
} // col
} // row
}
m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[1];
break;
case 2:
{
// foreground + leftover: Slice groups are rectangles, any MB not
// in a defined rectangle is in the leftover slice group, a MB within
// more than one rectangle is in the lower-numbered slice group.
// Two steps:
// 1. Set m_pMBMap with slice group for all MBs.
// 2. Set nextMB fields of MBInfo from m_pMBMap.
Ipp32u RectUpper, RectLeft, RectRight, RectLower;
Ipp32u RectRows, RectCols;
Ipp32u row, col;
// First init all as leftover
for (mbnum=FirstMB; mbnum<uNumMapUnits; mbnum++)
m_pMBMap[mbnum] = (Ipp8u)(uNumSliceGroups - 1);
// Next set those in slice group rectangles, from back to front
for (SliceGroup = (Ipp32s)(uNumSliceGroups - 2); SliceGroup >= 0; SliceGroup--)
{
mbnum = pps->SliceGroupInfo.t1.top_left[SliceGroup];
RectUpper = pps->SliceGroupInfo.t1.top_left[SliceGroup] / uNumMBCols;
RectLeft = pps->SliceGroupInfo.t1.top_left[SliceGroup] % uNumMBCols;
RectLower = pps->SliceGroupInfo.t1.bottom_right[SliceGroup] / uNumMBCols;
RectRight = pps->SliceGroupInfo.t1.bottom_right[SliceGroup] % uNumMBCols;
RectRows = RectLower - RectUpper + 1;
RectCols = RectRight - RectLeft + 1;
for (row = 0; row < RectRows; row++)
{
for (col=0; col < RectCols; col++)
{
m_pMBMap[mbnum+col] = (Ipp8u)SliceGroup;
} // col
mbnum += uNumMBCols;
} // row
} // SliceGroup
}
m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[1];
pMap = m_pMBMap;
bSetFromMap = true; // to cause step 2 to occur below
break;
case 3:
{
// Box-out, clockwise or counterclockwise. Result is two slice groups,
// group 0 included by the box, group 1 excluded.
// Two steps:
// 1. Set m_pMBMap with slice group for all MBs.
// 2. Set nextMB fields of MBInfo from m_pMBMap.
Ipp32u x, y, leftBound, topBound, rightBound, bottomBound;
Ipp32s xDir, yDir;
Ipp32u mba;
Ipp32u dir_flag = pps->SliceGroupInfo.t2.slice_group_change_direction_flag;
Ipp32u uNumInGroup0;
Ipp32u uGroup0Count = 0;
SliceGroup = 1; // excluded group
uNumInGroup0 = IPP_MIN(pps->SliceGroupInfo.t2.slice_group_change_rate *
sliceHeader->slice_group_change_cycle, uNumMapUnits - FirstMB);
if (uNumInGroup0 >= uNumMapUnits)
{
// all units in group 0
uNumInGroup0 = uNumMapUnits;
SliceGroup = 0;
uGroup0Count = uNumInGroup0; // to skip box out
}
// First init all
for (mbnum = FirstMB; mbnum < uNumMapUnits; mbnum++)
m_pMBMap[mbnum] = (Ipp8u)SliceGroup;
// Next the box-out algorithm to change included MBs to group 0
// start at center
x = (uNumMBCols - dir_flag)>>1;
y = (uNumMBRows - dir_flag)>>1;
leftBound = rightBound = x;
topBound = bottomBound = y;
xDir = dir_flag - 1;
yDir = dir_flag;
// expand out from center until group 0 includes the required number
// of units
while (uGroup0Count < uNumInGroup0)
{
mba = x + y*uNumMBCols;
if (m_pMBMap[mba + FirstMB] == 1)
{
// add MB to group 0
m_pMBMap[mba + FirstMB] = 0;
uGroup0Count++;
}
if (x == leftBound && xDir == -1)
{
if (leftBound > 0)
{
leftBound--;
x--;
}
xDir = 0;
yDir = dir_flag*2 - 1;
}
else if (x == rightBound && xDir == 1)
{
if (rightBound < uNumMBCols - 1)
{
rightBound++;
x++;
}
xDir = 0;
yDir = 1 - dir_flag*2;
}
else if (y == topBound && yDir == -1)
{
if (topBound > 0)
{
topBound--;
y--;
}
xDir = 1 - dir_flag*2;
yDir = 0;
}
else if (y == bottomBound && yDir == 1)
{
if (bottomBound < uNumMBRows - 1)
{
bottomBound++;
y++;
}
xDir = dir_flag*2 - 1;
yDir = 0;
}
else
{
x += xDir;
y += yDir;
}
} // while
}
m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[1];
pMap = m_pMBMap;
bSetFromMap = true; // to cause step 2 to occur below
break;
case 4:
// raster-scan: 2 slice groups. Both groups contain units ordered
// by raster-scan, so initializing nextMB for simple raster-scan
// ordering is all that is required.
m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[0];
break;
case 5:
// wipe: 2 slice groups, the vertical version of case 4. Init
// nextMB by processing the 2 groups as two rectangles (left
// and right); to allow for the break between groups occurring
// not at a column boundary, the rectangles also have an upper
// and lower half (same heights both rectangles) that may vary
// in width from one another by one macroblock, for example:
// L L L L R R R R R
// L L L L R R R R R
// L L L R R R R R R
// L L L R R R R R R
{
Ipp32u uNumInGroup0;
Ipp32u uNumInLGroup;
Ipp32s SGWidth;
Ipp32s NumUpperRows;
Ipp32s NumRows;
Ipp32s row, col;
Ipp32s iMBNum;
uNumInGroup0 = IPP_MIN(pps->SliceGroupInfo.t2.slice_group_change_rate *
sliceHeader->slice_group_change_cycle, uNumMapUnits - FirstMB);
if (uNumInGroup0 >= uNumMapUnits)
{
// all units in group 0
uNumInGroup0 = uNumMapUnits;
}
if (pps->SliceGroupInfo.t2.slice_group_change_direction_flag == 0)
uNumInLGroup = uNumInGroup0;
else
uNumInLGroup = uNumMapUnits - uNumInGroup0;
if (uNumInLGroup > 0)
{
// left group
NumUpperRows = uNumInLGroup % uNumMBRows;
NumRows = uNumMBRows;
SGWidth = uNumInLGroup / uNumMBRows; // lower width, left
if (NumUpperRows)
{
SGWidth++; // upper width, left
// zero-width lower case
if (SGWidth == 1)
NumRows = NumUpperRows;
}
iMBNum = FirstMB;
for (row = 0; row < NumRows; row++)
{
col = 0;
while (col < SGWidth-1)
{
next_mb_tables[1][iMBNum + col] = (iMBNum + col + 1);
col++;
} // col
// next for last MB on row
next_mb_tables[1][iMBNum + col] = (iMBNum + uNumMBCols);
iMBNum += uNumMBCols;
// time to switch to lower?
NumUpperRows--;
if (NumUpperRows == 0)
SGWidth--;
} // row
} // left group
if (uNumInLGroup < uNumMapUnits)
{
// right group
NumUpperRows = uNumInLGroup % uNumMBRows;
NumRows = uNumMBRows;
// lower width, right:
SGWidth = uNumMBCols - uNumInLGroup / uNumMBRows;
if (NumUpperRows)
SGWidth--; // upper width, right
if (SGWidth > 0)
{
// first MB is on first row
iMBNum = uNumMBCols - SGWidth;
}
else
{
// zero-width upper case
SGWidth = 1;
iMBNum = (NumUpperRows + 1)*uNumMBCols - 1;
NumRows = uNumMBRows - NumUpperRows;
NumUpperRows = 0;
}
for (row = 0; row < NumRows; row++)
{
col = 0;
while (col < SGWidth-1)
{
next_mb_tables[1][iMBNum + col] = (iMBNum + col + 1);
col++;
} // col
// next for last MB on row
next_mb_tables[1][iMBNum + col] = (iMBNum + uNumMBCols);
// time to switch to lower?
NumUpperRows--;
if (NumUpperRows == 0)
{
SGWidth++;
// fix next for last MB on row
next_mb_tables[1][iMBNum + col]= (iMBNum+uNumMBCols - 1);
iMBNum--;
}
iMBNum += uNumMBCols;
} // row
} // right group
}
m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[1];
break;
case 6:
// explicit map read from bitstream, contains slice group id for
// each map unit
m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[1];
pMap = pps->SliceGroupInfo.t3.pSliceGroupIDMap;
bSetFromMap = true;
break;
default:
// can't happen
VM_ASSERT(0);
} // switch map type
if (bSetFromMap)
{
// Set the nextMB MBInfo field of a set of macroblocks depending upon
// the slice group information in the map, to create an ordered
// (raster-scan) linked list of MBs for each slice group. The first MB
// of each group will be identified by the first slice header for each
// group.
// For each map unit get assigned slice group from the map
// For all except the first unit in each
// slice group, set the next field of the previous MB in that
// slice group.
// Init PrevMapUnit to -1 (none), for first unit of each slice group
for (i=0; i<uNumSliceGroups; i++)
PrevMapUnit[i] = -1;
for (mbnum=FirstMB; mbnum<uNumMapUnits; mbnum++)
{
SliceGroup = pMap[mbnum];
prevMB = PrevMapUnit[SliceGroup];
if (prevMB != -1)
{
next_mb_tables[1][prevMB] = mbnum;
}
PrevMapUnit[SliceGroup] = mbnum;
}
}
} // >1 slice group
}
} // setMBMap
void TaskSupplier::SlideWindow(H264Slice * pSlice, Ipp32s field_index, bool force)
{
Ipp32u NumShortTermRefs, NumLongTermRefs;
H264SeqParamSet* sps = pSlice->GetSeqParam();
// find out how many active reference frames currently in decoded
// frames buffer
m_pDecodedFramesList->countActiveRefs(NumShortTermRefs, NumLongTermRefs);
if (((NumShortTermRefs + NumLongTermRefs) >= sps->num_ref_frames) && !field_index)
{
// mark oldest short-term reference as unused
VM_ASSERT(NumShortTermRefs > 0);
H264DecoderFrame * pFrame = m_pDecodedFramesList->freeOldestShortTermRef();
if (!force)
OnSlideWindow(pFrame, m_pCurrentFrame, &m_DefaultNotifyChain, false);
else
OnSlideWindow(pFrame, 0, &m_DefaultNotifyChain, false);
}
}
//////////////////////////////////////////////////////////////////////////////
// updateRefPicMarking
// Called at the completion of decoding a frame to update the marking of the
// reference pictures in the decoded frames buffer.
//////////////////////////////////////////////////////////////////////////////
Status TaskSupplier::UpdateRefPicMarking(H264DecoderFrame * pFrame, H264Slice * pSlice, Ipp32s fiel
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -