📄 iframe.cpp
字号:
default:
break;
}
GetStartCode();
}
else
{
// User_data
GetStartCode();
}
}
}
////////////////////////////////////////////////////////////////////
void CIFrame::SequenceExtension ()
{
int iProfileLevelIndication;
int iHorizontalSizeEx;
int iVerticalSizeEx;
MPEG2_Flag = 1;
m_iScalableMode = SC_NONE; // unless overwritten by sequence_scalable_extension()
iProfileLevelIndication = GetBits (8);
m_iProgressiveSequence = GetBits (1);
m_iChromaFormat = GetBits (2);
iHorizontalSizeEx = GetBits (2);
iVerticalSizeEx = GetBits (2);
FlushBits (12); // BitRateEx
FlushBits (1); // marker bit
FlushBits (8); // VbvBufferSizeEx
FlushBits (1); // LowDelay
FlushBits (2); // FrameRateExN
FlushBits (5); // FrameRateExD
if((iProfileLevelIndication >> 7) & 1)
{ // escape bit of profile_and_level_indication set
// 4:2:2 Profile @ Main Level
if((iProfileLevelIndication & 15) == 5)
{
profile = PROFILE_422;
level = MAIN_LEVEL;
}
}
else
{
profile = iProfileLevelIndication >> 4; // Profile is upper nibble
level = iProfileLevelIndication & 0xF; // Level is lower nibble
}
m_iHorizontalSize = (iHorizontalSizeEx << 12) | (m_iHorizontalSize & 0x0FFF);
m_iVerticalSize = (iVerticalSizeEx << 12) | (m_iVerticalSize & 0x0FFF);
}
////////////////////////////////////////////////////////////////////
void CIFrame::SequenceDisplayExtension ()
{
int iVideoFormat;
int iColourDescription;
int iColourPrimaries;
int iTransferCharacteristics;
iVideoFormat = GetBits(3);
iColourDescription = GetBits(1);
if (iColourDescription)
{
iColourPrimaries = GetBits (8);
iTransferCharacteristics = GetBits (8);
m_iMatrixCoefficients = GetBits (8);
}
FlushBits (14); // DisplayHorizontalSize
FlushBits (1); // MarkerBit
FlushBits (14); // DisplayVerticalSize
}
////////////////////////////////////////////////////////////////////
void CIFrame::SequenceScalableExtension ()
{
int iLayerId;
int iPictureMuxEnable;
int iMuxToProgressiveSequence;
m_iScalableMode = GetBits (2) + 1; // Add 1 to make SC_DP != SC_NONE
iLayerId = GetBits (4);
if (m_iScalableMode == SC_SPAT)
{
FlushBits (14); // LowerLayerPredHorSize
FlushBits (1); // marker bit
FlushBits (14); // LowerLayerPredVerticalSize
FlushBits (5); // HorSubFactorM
FlushBits (5); // HorSubFactorN
FlushBits (5); // VerticalSubFactorM
FlushBits (5); // VerticalSubFactorN
}
else if (m_iScalableMode == SC_TEMP)
{
iPictureMuxEnable = GetBits (1);
if (iPictureMuxEnable)
iMuxToProgressiveSequence = GetBits (1);
FlushBits (3); // PictureMuxOrder
FlushBits (3); // PictureMuxFactor
}
}
////////////////////////////////////////////////////////////////////
void CIFrame::GOPHeader ()
{
FlushBits (1); // DropFrameFlag
FlushBits (5); // Hour
FlushBits (6); // Minute
FlushBits (1); // Markerbit
FlushBits (6); // Second
FlushBits (6); // Pictures
FlushBits (1); // ClosedGop
FlushBits (1); // BrokenLink
ExtensionUserData();
}
////////////////////////////////////////////////////////////////////
void CIFrame::PictureHeader ()
{
int iVbvDelay;
// unless later overwritten by PictureSpatialScalableExtension()
m_iPictScal = 0;
m_iTemporalRef = GetBits (10);
m_iPictureCodeType = GetBits (3);
iVbvDelay = GetBits (16);
if (m_iPictureCodeType == 2 || m_iPictureCodeType == 3)
{
m_iFullPelForwardVector = GetBits (1);
m_iForwardFCode = GetBits (3);
}
if (m_iPictureCodeType == 3)
{
m_iFullPelBackwardVector = GetBits (1);
m_iBackwardFCode = GetBits (3);
}
// Extra bit information
while (GetBits (1))
{
FlushBits(8);
if (m_bStopVideoDemux)
break;
}
ExtensionUserData ();
}
////////////////////////////////////////////////////////////////////
void CIFrame::PictureCodingExtension ()
{
int iChroma420Type;
int iCompositeDisplayFlag;
int iVAxis;
int iFieldSequence;
int iSubCarrier;
int iBurstAmplitude;
int iSubCarrierPhase;
f_code[0][0] = GetBits (4);
f_code[0][1] = GetBits (4);
f_code[1][0] = GetBits (4);
f_code[1][1] = GetBits (4);
m_iIntraDcPrecision = GetBits (2);
m_iPictureStructure = GetBits (2);
m_iTopFieldFirst = GetBits (1);
m_iFramePredFrameDct = GetBits (1);
m_iConcealmentMotionVectors = GetBits (1);
m_iQScaleType = GetBits (1);
m_iIntraVlcFormat = GetBits (1);
m_iAlternateScan = GetBits (1);
m_iRepeatFirstField = GetBits (1);
iChroma420Type = GetBits (1);
m_iProgressiveFrame = GetBits (1);
iCompositeDisplayFlag = GetBits (1);
if (iCompositeDisplayFlag)
{
iVAxis = GetBits (1);
iFieldSequence = GetBits (3);
iSubCarrier = GetBits (1);
iBurstAmplitude = GetBits (7);
iSubCarrierPhase = GetBits (8);
}
}
////////////////////////////////////////////////////////////////////
void CIFrame::QuantMatrixExtension ()
{
register int i;
int iLoadIntraQuantiserMatrix;
int iLoadNonIntraQuantiserMatrix;
int iLoadChromaIntraQuantiserMatrix;
int iLoadChromnaNonIntraQuantiserMatrix;
iLoadIntraQuantiserMatrix = GetBits (1);
if (iLoadIntraQuantiserMatrix)
{
for (i=0; i<64; i++)
{
m_iChromaIntraQuantiserMatrix[scan[ZIG_ZAG][i]]
= m_iIntraQuantiserMatrix[scan[ZIG_ZAG][i]]
= GetBits(8);
}
}
iLoadNonIntraQuantiserMatrix = GetBits (1);
if (iLoadNonIntraQuantiserMatrix)
{
for (i = 0; i < 64; i++)
{
m_iChromaNonIntraQuantiserMatrix[scan[ZIG_ZAG][i]]
= m_iNonIntraQuantiserMatrix[scan[ZIG_ZAG][i]]
= GetBits(8);
}
}
iLoadChromaIntraQuantiserMatrix = GetBits (1);
if (iLoadChromaIntraQuantiserMatrix)
{
for (i = 0; i < 64; i++)
m_iChromaIntraQuantiserMatrix[scan[ZIG_ZAG][i]] = GetBits (8);
}
iLoadChromnaNonIntraQuantiserMatrix = GetBits (1);
if (iLoadChromnaNonIntraQuantiserMatrix)
{
for (i = 0; i < 64; i++)
m_iChromaNonIntraQuantiserMatrix[scan[ZIG_ZAG][i]] = GetBits (8);
}
}
////////////////////////////////////////////////////////////////////
void CIFrame::PictureDisplayExtension ()
{
int i;
int number_of_frame_center_offsets;
// based on ISO/IEC 13818-2 section 6.3.12
// (November 1994) Picture display extensions
// derive number_of_frame_center_offsets
if(m_iProgressiveSequence)
{
if(m_iRepeatFirstField)
{
if(m_iTopFieldFirst)
number_of_frame_center_offsets = 3;
else
number_of_frame_center_offsets = 2;
}
else
{
number_of_frame_center_offsets = 1;
}
}
else
{
if(m_iPictureStructure != FRAME_PICTURE)
{
number_of_frame_center_offsets = 1;
}
else
{
if(m_iRepeatFirstField)
number_of_frame_center_offsets = 3;
else
number_of_frame_center_offsets = 2;
}
}
// now parse
for (i=0; i < number_of_frame_center_offsets; i++)
{
m_iFrameCenterHorizontalOffset[i] = GetBits(16);
GetBits (1); // marker bit
m_iFrameCenterVerticalOffset[i] = GetBits(16);
GetBits (1); // marker bit
if (m_bStopVideoDemux)
break;
}
}
////////////////////////////////////////////////////////////////////
void CIFrame::PictureTemporalScalableExtension ()
{
int iRefSelectCode;
int iForwardTemporalRef;
int iMarkerBit;
int iBakwardTemporalRef;
iRefSelectCode = GetBits (2);
iForwardTemporalRef = GetBits (10);
iMarkerBit = GetBits (1);
iBakwardTemporalRef = GetBits (10);
}
////////////////////////////////////////////////////////////////////
void CIFrame::PictureSpatialScalableExtension ()
{
int iLowerLayerTemporalRef;
int iMarkerBit;
int iLowerLayerProgressiveMatrix;
int iLowerLayerDeinterlacedFieldSelect;
m_iPictScal = 1; // use spatial scalability in this picture
iLowerLayerTemporalRef = GetBits (10);
iMarkerBit = GetBits (1);
m_iLowerLayerHorizontalOffset = GetBits (15);
if (m_iLowerLayerHorizontalOffset >= 16384)
m_iLowerLayerHorizontalOffset -= 32768;
iMarkerBit = GetBits (1);
m_iLowerLayerVerticalOffset = GetBits (15);
if (m_iLowerLayerVerticalOffset >= 16384)
m_iLowerLayerVerticalOffset -= 32768;
m_iSpatialTemporalWeightCodeTableIndex = GetBits (2);
iLowerLayerProgressiveMatrix = GetBits (1);
iLowerLayerDeinterlacedFieldSelect = GetBits (1);
}
////////////////////////////////////////////////////////////////////
void CIFrame::CopyrightExtension ()
{
FlushBits (1); // CopyrightFlag
FlushBits (8); // CopyrightId
FlushBits (1); // OriginalOrCopy
FlushBits (7); // Reserved
FlushBits (1); // MarkerBit
FlushBits (20); // Copyright1
FlushBits (1); // MarketBit
FlushBits (22); // Copyright2
FlushBits (1); // MarkerBit
FlushBits (22); // Copyright3
}
////////////////////////////////////////////////////////////////////
void CIFrame::PictureData ()
{
int MBAmax;
static int Table_6_20[3] = {6,8,12};
// force MPEG-1 parameters for proper decoder behavior
// see ISO/IEC 13818-2 section D.9.14
if (!MPEG2_Flag)
{
m_iProgressiveSequence = 1;
m_iProgressiveFrame = 1;
m_iPictureStructure = FRAME_PICTURE;
m_iFramePredFrameDct = 1;
m_iChromaFormat = CHROMA420;
m_iMatrixCoefficients = 5;
}
// Round to nearest multiple of coded macroblocks
// ISO/IEC 13818-2 section 6.3.3 sequence_header()
mb_width = (m_iHorizontalSize + 15) / 16;
mb_height = (MPEG2_Flag && !m_iProgressiveSequence) ?
2 * ((m_iVerticalSize + 31) / 32) : (m_iVerticalSize + 15) / 16;
// Derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17
block_count = Table_6_20[m_iChromaFormat-1];
// number of macroblocks per picture
MBAmax = mb_width * mb_height;
if (m_iPictureStructure != FRAME_PICTURE)
MBAmax >>= 1; // Field picture has half as mnay macroblocks as frame
for(;;)
{
if (Slice(MBAmax) < 0)
return;
if (m_bStopVideoDemux)
return;
}
}
////////////////////////////////////////////////////////////////////
int CIFrame::Slice (int MBAmax)
{
int iSliceVerticalPositionEx;
int iQuantiserScaleCode;
int iPriorityBreakpoint;
DWORD dwSyncCode = 0;
int MBA = 0; // Macroblock address
int MBAinc = 0; // Macroblock increment
int iMacroblockType = 0, iMotionType = 0, iDctType = 0;
int iStwType=0, iStwClass=0;
int PMV[2][2][2], motion_vertical_field_select[2][2];
int dmvector[2];
int dc_dct_pred[3];
GetStartCode();
dwSyncCode = ShowBits (32);
if (dwSyncCode < SLICE_START_CODE_MIN || dwSyncCode > SLICE_START_CODE_MAX)
return -1;
FlushBits(32);
iSliceVerticalPositionEx = (MPEG2_Flag && m_iVerticalSize > 2800) ? GetBits(3) : 0;
if (m_iScalableMode == SC_DP)
iPriorityBreakpoint = GetBits (7);
iQuantiserScaleCode = GetBits (5);
m_iQuantiserScale = MPEG2_Flag ? (m_iQScaleType ? Non_Linear_quantizer_scale[iQuantiserScaleCode]
: iQuantiserScaleCode << 1) : iQuantiserScaleCode;
if (GetBits(1))
{
GetBits (1); // Intra slice flag
GetBits(1); // Intra slice
GetBits (6); // Reversed bits
while (GetBits(1)) // Extra information slice
{
FlushBits(8);
if (m_bStopVideoDemux)
return -1;
}
}
// SCALABILITY: Data Partitioning
if (m_iScalableMode == SC_DP)
{
GetStartCode();
dwSyncCode = ShowBits(32);
if (dwSyncCode < SLICE_START_CODE_MIN || dwSyncCode > SLICE_START_CODE_MAX)
// only slice headers are allowed in picture_data
// throw "DP: Premature end of picture";
throw -1;
FlushBits(32);
// decode slice header (may change quantizer_scale)
iSliceVerticalPositionEx = (MPEG2_Flag && m_iVerticalSize > 2800) ? GetBits(3) : 0;
if (m_iScalableMode == SC_DP)
iPriorityBreakpoint = GetBits (7);
iQuantiserScaleCode = GetBits (5);
m_iQuantiserScale = MPEG2_Flag ? (m_iQScaleType ? Non_Linear_quantizer_scale[iQuantiserScaleCode]
: iQuantiserScaleCode << 1) : iQuantiserScaleCode;
if (GetBits(1))
{
GetBits (1); // Intra slice flag
GetBits(1); // Intra slice
GetBits (6); // Reversed bits
while (GetBits(1)) // Extra information slice
{
FlushBits(8);
if (m_bStopVideoDemux)
return -1;
}
}
}
MBAinc = MacroblockAddrIncrement ();
// Set current location
// NOTE: the arithmetic used to derive macroblock_address below is
// equivalent to ISO/IEC 13818-2 section 6.3.17: Macroblock
MBA = ((iSliceVerticalPositionEx << 7) + (dwSyncCode & 255) - 1) * mb_width + MBAinc - 1;
MBAinc = 1; // first macroblock in slice: not skipped
// reset all DC coefficient and motion vector predictors
// reset all DC coefficient and motion vector predictors
// ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
// ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
for (;;)
{
if (m_bStopVideoDemux)
return -1;
// This is how we properly exit out of picture
if (MBA >= MBAmax)
return -1; // all macroblocks decoded
if (MBAinc == 0)
{
if (!ShowBits(23)) // next_start_code or fault
return 0; // trigger: go to next slice
else // neither next_start_code nor Fault_Flag
MBAinc = MacroblockAddrIncrement();
}
if (MBA >= MBAmax)
{
return -1;
}
if (MBAinc == 1) // Not skipped
{
int ret = Macroblock (&iMacroblockType, &iStwType, &iStwClass,
&iMotionType, &iDctType, PMV, dc_dct_pred, motion_vertical_field_select, dmvector);
if (ret == -1)
return -1;
}
else // MBAinc!=1: skipped macroblock
{
// ISO/IEC 13818-2 section 7.6.6
SkipMacroblock(dc_dct_pred, PMV, &iMotionType,
motion_vertical_field_select, &iStwType, &iMacroblockType);
}
// Advance to next macroblock
MBA++;
MBAinc--;
if (MBA >= MBAmax)
{
return -1; // All macroblocks decoded
}
}
}
////////////////////////////////////////////////////////////////////
int CIFrame::Macroblock(int* pMacroblockType, int* pStwType, int* pStwClass,
int* pMotionType, int* pDctType, int PMV[2][2][2], int dc_dct_pred[3],
int motion_vertical_field_select[2][2], int dmvector[2])
{
int iMotionVectorCount = 0;
int iMvFormat = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -