Understanding VC-1
There is a WMV9/VC-1 reference decoder available on the internet which answers to the filename vc1_reference_decoder_release6.zip. This section of the MultimediaWiki is an effort to create an open VC-1 specification based on that reference implementation.
Acronyms
This section defines various terms that are useful to know when plodding through a discussion of the VC-1 reference implementation.
- AC/DC/DCAC = transform coefficients
- CBP/CBPCY = coded block pattern
- IC = intensity compensation
- IDU = independently decodable unit
- MB = macroblock
- MV = motion vector
- MVBP = motion vector block pattern
- NZC = non-zero coefficients
- SBP = sub block pattern
- SRD = SMPTE reference decoder (used in this description, not in the actual SRD)
- TTBLK = ??? (may mean block transform type)
- TTMB = ??? (may mean macroblock transform type)
- VOP = ???
Frame Types
- I-frame: intraframe
- P-frame: predicted frame
- B-frame: bi-directionally predicted frame
- BI-frame: ??? perhaps an I-frame upon which no other frames depend
Hierarchy of VC-1 Decoding Functions
These functions are necessary for processing VC-1 data using the reference decoder:
// set up pointers to bitstream (extradata) in internal state structure vc1DECBIT_InitialiseBitstream // analyze how much memory the client app needs to allocate vc1DEC_DecoderRequirements // init decoder vc1DEC_DecoderInitialise // process the extradata setup bitstream vc1DEC_DecodeSequence // decode a frame vc1DEC_DecodeFrame
These are the call trees for the above functions
vc1DECBIT_InitialiseBitstream +- vc1DECBIT_ReadBytes
vc1DEC_DecoderRequirements +- vc1DECBIT_GetBits +- vc1TOOLS_InitReferencePicture +- vc1TOOLS_InitImagePosition
vc1DEC_DecoderInitialise +- vc1DEC_SetMaxSize +- vc1TOOLS_InitReferencePicture
vc1DEC_DecodeSequence +- vc1DECSEQ_UnpackSequenceLayer +- vc1DECBIT_GetBits
vc1DEC_DecodeFrame +- vc1DECPIC_UnpackPictureLayer +- vc1DECPIC_ReadPictureLayer +- vc1DECBIT_GetBits +- vc1DECPIC_SetDimensionsInMB +- vc1DECPIC_UnpackPictureLayerAdvanced +- vc1DECBIT_GetBits +- vc1DECBIT_GetVLC +- vc1DECPIC_UnpackPanScanParams +- vc1DECBIT_GetBits +- vc1DECPIC_UnpackPictureLayerSimpleMain +- vc1DECBIT_BitCountGet +- vc1DECBIT_GetBits +- vc1DECBIT_GetVLC +- vc1DECPIC_UnpackQuantizationParams +- vc1DECBIT_GetBits +- vc1IQUANT_GetQuantizer +- vc1DECPIC_SetDimensionsInMB +- vc1DECBITPL_ReadBitplane +- vc1DECBIT_GetBits +- vc1DECBIT_GetVLC +- vc1DECBITPL_DecodeNorm2Bits +- vc1DECBIT_GetBits +- vc1DECBIT_GetVLC +- vc1DECBITPL_DecodeNorm6Bits +- vc1DECBIT_GetBits +- vc1DECBIT_GetVLC +- vc1DECBITPL_DecodeRowskipBits +- vc1DECBIT_GetBits +- vc1DECBITPL_DecodeColskipBits +- vc1DECBIT_GetBits +- vc1DECBITPL_DecodeDiff2Bits +- vc1DECBITPL_DecodeNorm2Bits +- vc1DECBITPL_BitplaneDiff +- vc1DECBITPL_DecodeDiff6Bits +- vc1DECBITPL_DecodeNorm6Bits +- vc1DECBITPL_BitplaneDiff +- vc1DECBITPL_DecodeRawBits +- vc1DECPIC_UnpackVOPDQUANTParams +- vc1DECBIT_GetBits +- vc1DECPIC_UnpackFieldPictureLayer +- vc1DECPIC_ReadAdvancedPictureLayer +- vc1DECPIC_UnpackFieldPictureLayerIAdvanced +- vc1DECPIC_UnpackQuantizationParams +- vc1DECBIT_GetBits +- vc1DECBITPL_ReadBitplane +- vc1DECBIT_GetVLC +- vc1DECPIC_UnpackVOPDQUANTParams +- vc1DECPIC_UnpackFieldPictureLayerPBAdvanced +- vc1DECPIC_UnpackQuantizationParams +- vc1DECBIT_GetBits +- vc1DECBIT_GetVLC +- vc1DECPIC_UnpackInterlaceMVModeParams +- vc1DECBITPL_ReadBitplane +- vc1DECPIC_DisplayPicture +- vc1DECPIC_DisplayField +- vc1DECPIC_InitialiseAppPicture +- vc1TOOLS_ResolutionUpsample +- vc1TOOLS_InitReferencePicture +- vc1TOOLS_NewReference +- vc1TOOLS_CopyReference +- vc1TOOLS_ICPadReferencePicture +- vc1TOOLS_RangeReduceReference +- vc1TOOLS_RangeReduce16 +- vc1TOOLS_RangeExpand +- vc1TOOLS_IntensityCompensate +- vc1TOOLS_ICComponent +- vc1TOOLS_PadReferencePicture +- vc1TOOLS_PadComponent +- vc1SCALEMV_InitScaleMV +- vc1DECSLICE_DecodeSlice +- vc1DECBIT_GetBits +- vc1DECPIC_UnpackSyncmarker +- vc1DECBIT_AlignBit +- vc1DECBIT_ReadBytes +- vc1DECBIT_GetBits +- vc1DECMB_UnpackMacroblockLayer +- vc1IQUANT_ChooseQuantizer +- vc1DECMB_UnpackMacroblockI +- vc1DECBITPL_ReadBitplaneBit +- vc1DECBIT_GetBits +- vc1DECBIT_GetVLC +- vc1PREDCBP_ApplyCBPCYPred +- vc1DECBIT_GetBits +- vc1DECMB_UnpackMBQuantParams +- vc1DECBIT_GetBits +- vc1DECMB_UnpackMacroblockProgP +- vc1DECBITPL_ReadBitplaneBit +- vc1DECMB_UnpackMacroblockProgPSkipped +- vc1DECBIT_LookBits +- vc1DECBIT_ReadBits +- vc1PREDMV_PredictProgressiveMV +- vc1PRED_pTopBlk +- vc1PRED_pLeftBlk +- vc1PRED_pB1MVBlk +- vc1PRED_pB4MVBlk +- vc1TOOLS_Median3 +- vc1CROPMV_BPredPullBack +- vc1DECBIT_GetBits +- vc1DECMV_ApplyMVPrediction +- vc1DERIVEMV_DecideChromaBlockType +- vc1DECMB_UnpackMacroblockProgP1MV +- vc1DECMV_UnpackMVData +- vc1DECBIT_LookBits +- vc1PREDMV_PredictProgressiveMV +- vc1DECBIT_GetBits +- vc1DECMV_ApplyMVPrediction +- vc1DERIVEMV_DecideChromaBlockType +- vc1DECMB_UnpackMBQuantParams +- vc1DECBIT_GetVLC +- vc1DECMB_DecodeTransformInfo +- vc1DECMB_UnpackTTMB +- vc1DECBIT_GetVLC +- vc1DECMB_UnpackMacroblockProgP4MV +- vc1DECBIT_GetVLC +- vc1DECMV_UnpackMVData +- vc1DECBIT_LookBits +- vc1PREDMV_PredictProgressiveMV +- vc1DECBIT_GetBits +- vc1DECMV_ApplyMVPrediction +- vc1DERIVEMV_DecideChromaBlockType +- vc1DECMB_UnpackMBQuantParams +- vc1PREDDCAC_ACPREDPresent +- vc1DECMB_DecodeTransformInfo +- vc1DECMB_UnpackMacroblockFieldP +- vc1DECBIT_GetVLC +- vc1DECMV_UnpackMVDataInterlace +- vc1DECBIT_GetVLC +- vc1DECBIT_GetBits +- vc1DECBIT_LookBits +- vc1PREDMV_PredictInterlacedFieldMV +- vc1SCALEMV_ScaleMV +- vc1TOOLS_Median3 +- vc1DECBIT_GetBits +- vc1DECMV_ApplyMVPrediction +- vc1DERIVEMV_DecideChromaBlockType +- vc1DECMB_UnpackMBQuantParams +- vc1DECMB_DecodeTransformInfo +- vc1DECMB_UnpackMacroblockFrameP +- vc1DECBITPL_ReadBitplaneBit +- vc1PREDMV_PredictInterlacedFrameMV +- vc1PREDMV_FrameMBPred +- vc1TOOLS_Median3 +- vc1DECMV_ApplyMVPrediction +- vc1DECBIT_GetVLC +- vc1DECBIT_GetBits +- vc1DERIVEMV_DecideChromaBlockType +- vc1DECMB_UnpackMBQuantParams +- vc1DECMV_UnpackMVDataInterlace +- vc1DECMB_UnpackMacroblockProgB +- vc1DECBITPL_ReadBitplaneBit +- vc1DECMV_UnpackMVData +- vc1DECBIT_GetVLC +- vc1DECMB_UnpackMBQuantParams +- vc1DECBIT_GetBits +- vc1PREDMV_PredictProgressiveMV +- vc1DECMV_ApplyMVPrediction +- vc1DERIVEMV_DecideChromaBlockType +- vc1DECMB_DecodeTransformInfo +- vc1DECMB_UnpackMacroblockFieldB +- vc1DECBIT_GetVLC +- vc1DECBITPL_ReadBitplaneBit +- vc1DECBITPL_SkipBitplaneBit +- vc1DECBIT_GetBits +- vc1DECMV_UnpackMVDataInterlace +- vc1PREDMV_PredictInterlacedFieldMV +- vc1DECMV_ApplyMVPrediction +- vc1DECMB_UnpackMBQuantParams +- vc1DERIVEMV_DecideChromaBlockType +- vc1DECMB_DecodeTransformInfo +- vc1DECMB_UnpackMacroblockFrameB +- vc1DECBITPL_ReadBitplaneBit +- vc1DECBIT_GetVLC +- vc1DECBITPL_SkipBitplaneBit +- vc1DECBIT_GetBits +- vc1DECMB_UnpackMBQuantParams +- vc1DERIVEMV_DecideChromaBlockType +- vc1DECMV_UnpackMVDataInterlace +- vc1PREDMV_PredictInterlacedFrameMV +- vc1DECMV_ApplyMVPrediction +- vc1DECMB_AssignCodedBlockPattern +- vc1DECBLK_DecodeBlockLayer +- vc1DECBLK_UnpackIntraBlock +- vc1PREDDCAC_DCDefault +- vc1PREDDCAC_DCStepSize +- vc1PREDDCAC_PredictDCAC +- vc1PREDDCAC_GetQuant +- vc1PREDDCAC_ScaleDC +- vc1PREDDCAC_DCStepSize +- vc1DECBLK_UnpackDCDifferential +- vc1DECBIT_GetVLC +- vc1DECBIT_GetBits +- vc1DEC3DH_DecodeACRunLevel +- vc1DEC3DH_ChooseACCodingSet +- vc1DEC3DH_ChooseEscapeMode3Table +- vc1DEC3DH_UnpackTransformACCoef +- vc1DECBIT_GetVLC +- vc1DECBIT_GetBits +- vc1DECZZ_DeZigZagBlock +- vc1DECZZ_DeZigZag +- vc1DECBLK_ApplyACPrediction +- vc1PREDDCAC_CopyDCAC +- vc1DECBLK_UnpackInterBlock +- vc1DECBLK_UnpackSubBlockPattern +- vc1DECBIT_GetVLC +- vc1DECBLK_UnpackTTBLK +- vc1DECBIT_GetVLC +- vc1DEC3DH_DecodeACRunLevel +- vc1DECZZ_DeZigZagBlock +- vc1INTERP_PredictMB +- vc1DERIVEMV_StoreMotionVectors +- vc1DERIVEMV_DeriveMV +- vc1DERIVEMV_DirectMV +- vc1DERIVEMV_DeriveProgMV +- vc1TOOLS_Median3 +- vc1TOOLS_Median4 +- vc1CROPMV_ChromaPullBack +- vc1DERIVEMV_DeriveIntFieldMV +- vc1TOOLS_Median4 +- vc1TOOLS_Median3 +- vc1DERIVEMV_DeriveIntFrameDirectMV +- vc1CROPMV_PPredPullBack +- vc1DERIVEMV_FillInInterlaceFieldMV +- vc1PREDMV_PredictInterlacedFieldMV +- vc1SCALEMV_ScaleMV +- vc1TOOLS_Median3 +- vc1INTERP_InterpolateBlock +- vc1CROPMV_LumaPullBack +- vc1DERIVEMV_DeriveChromaMV +- vc1DERIVEMV_DeriveProgMV +- vc1CROPMV_LumaPullBack +- vc1DERIVEMV_DeriveSecondStageChromaMV +- vc1CROPMV_ChromaPullBack +- vc1DERIVEMV_DeriveIntFieldMV +- vc1TOOLS_Median4 +- vc1CROPMV_ChromaPullBack +- vc1INTERP_InterpPatchQuarterPelBilinear +- vc1INTERP_InterpPatchHalfPelBilinear +- vc1INTERP_InterpPatchQuarterPelBilinear +- vc1INTERP_InterpPatchQuarterPelBicubic +- vc1INTERP_CopyPatch +- vc1INTERP_InterpPatchQuarterPelBicubicVert +- vc1INTERP_InterpPatchQuarterPelBicubicHoriz +- vc1INTERP_InterpPatchQuarterPelBicubicDiag +- vc1INTERP_InterpPatchHalfPelBicubic +- vc1INTERP_InterpPatchQuarterPelBicubic +- vc1INTERP_AverageBlocks +- vc1RECON_ReconstructMB +- vc1IQUANT_InverseACQuantize +- vc1IQUANT_InverseDCQuantize +- vc1PREDDCAC_DCStepSize +- vc1ITRANS_InverseTransformBlock +- vc1ITRANS_InverseTransform_AnnexA1 +- vc1RECON_ApplyPredictionAndCopyMB +- vc1INTERP_InterlaceDiffMB +- vc1INTERP_InterlacePredMB +- vc1SMOOTH_OverlapSmoothMB +- vc1PRED_pLeftMB +- vc1TOOLS_GetPictureDestination +- vc1SMOOTH_OverlapSmoothVertBlk +- vc1SMOOTH_OverlapSmoothHorizMB +- vc1TOOLS_GetPictureDestination +- vc1SMOOTH_OverlapSmoothHorizBlk +- vc1TOOLS_GetPictureDestination +- vc1SMOOTH_OverlapSmoothHorizMB +- vc1DEBLOCK_DeblockSlice +- vc1DEBLOCK_HorizDeblockMB +- vc1TOOLS_GetPictureDestination +- vc1DEBLOCK_HorizDeblockBlk +- vc1DEBLOCK_VertDeblockMB +- vc1TOOLS_GetPictureDestination +- vc1DEBLOCK_VertDeblockBlk +- vc1TOOLS_CopyReference +- vc1DECPIC_DisplayPicture
vc1CROPMV_BPredPullBack
vc1CROPMV_ChromaPullBack
vc1CROPMV_LumaPullBack
vc1CROPMV_PPredPullBack
vc1DEBLOCK_DeblockSlice
vc1DEBLOCK_HorizDeblockBlk
vc1DEBLOCK_HorizDeblockMB
vc1DEBLOCK_VertDeblockBlk
vc1DEBLOCK_VertDeblockMB
vc1DEC3DH_ChooseACCodingSet
vc1DEC3DH_ChooseEscapeMode3Table
vc1DEC3DH_DecodeACRunLevel
vc1DEC3DH_UnpackTransformACCoef
vc1DEC_DecodeFrame
vc1DEC_DecoderInitialise
vc1DEC_DecoderRequirements
This function is an API glue function to the VC-1 reference decoder. The function takes the first part of the encoded bitstream, and DecoderCofiguration data structure, and returns the total number of bytes that the client application must allocate for the decoder to establish all of its internal data structures.
2 bits: VC-1 profile 0 = simple profile 1 = main profile 2 = reserved, should not occur 3 = advanced profile if (profile == advanced) ...more processing goes here... else // simple or main profile move data from original page here
vc1DEC_DecodeSequence
vc1DEC_SetMaxSize
This function takes the width and height dimension pair for an image. The function validates that the number of macroblocks is allowed under to current profile. Then it assigns the dimension pair (not rounded) to 5 other dimension pairs:
- vc1DEC_sState.vc1_sSequenceLayer.MaxCoded[Width|Height]
- vc1DEC_sState.vc1_sSequenceLayer.Coded[Width|Height]
- vc1DEC_sState.vc1_sSequenceLayer.Display[Width|Height]
- vc1DEC_sState.vc1_sPosition.Coded[Width|Height]
- vc1DEC_sState.vc1_sPosition.MaxCoded[Width|Height]
vc1DECBIT_AlignBit
This function aligns the input bitstream on a byte boundary.
vc1DECBIT_BitCountGet
This function returns the total number of unconsumed bits remaining in the input bitstream.
vc1DECBIT_GetBits
GetBits returns and consumes the next n bits from the bitstream, as opposed to LookBits, which does not consume the bits after reading them.
vc1DECBIT_GetVLC
The GetVLC function returns the value represented by the next variable length code (i.e., Huffman) code in the bitstream. The reference decoder performes this operation in an exceptionally slow manner but it is also not held to any specific performance standards. Thus, a new VC-1 implementation should maintain VLC tables and decode values from then however it sees fit to do so.
vc1DECBIT_InitialiseBitstream
This function takes a pointer to bitstream accounting structure, a pointer to a buffer containing an encoded bitstream, and the length of that buffer. It initializes the internal bitstream accounting data structure. It also calls vc1DECBIT_ReadBytes to fill up the internal bit buffer in preparation for bit extraction. This function can also accept a flag that specifies the IDUs are encapsulated.
vc1DECBIT_LookBits
LookBits asks the bitstream reader to return the next n bits from the stream but to not actually consume them, as GetBits() would do.
vc1DECBIT_ReadBits
ReadBits is essentially equivalent to GetBits.
vc1DECBIT_ReadBytes
ReadBytes() is a bitstream accounting function that ensures the 32-bit bit buffer is completely filled.
vc1DECBITPL_BitplaneDiff
This function takes a bitplane data structure, an invert bit, and the width and height of the frame in macroblocks. It decodes 1 bit per MB. The bitplane data structure is assumed to be arranged as a macroblock frame with (width x height) macroblocks.
Each MB bit in the bitplane (which was decoded by another function) is XOR'd against a predictor bit. The predictor bit depends on the MB's placement in the bitplane. The precise algorithm follows:
- foreach j in 0..MBheight - 1
- foreach i in 0..MBwidth - 1
- if i and j are both 0 (upper left MB)
- predictor = invert flag
- else if i is 0 (left column MB)
- predictor = the MB bit above the current MB (MB[MBwidth * (j - 1)])
- else if (the current MB is not on the top row) and (the MB bit above the current MB != the MB bit to the left of the current MB)
- predictor = invert flag
- else
- predictor = MB bit to the left of the current MB
- current MB bit = current MB bit XOR predictor
- if i and j are both 0 (upper left MB)
- foreach i in 0..MBwidth - 1
vc1DECBITPL_DecodeColskipBits
This function takes a bitplane data structure, an invert bit, and the width and height of the frame in macroblocks. It decodes 1 bit per MB. The bitplane data structure is assumed to be arranged as a macroblock frame with (width x height) macroblocks.
- foreach i in 0..MBwidth - 1
- 1 bit: column skip value (colskip)
- foreach j in 0..MBheight - 1
- value = 0
- if colskip is 1
- 1 bit: value
- bitplane_macroblock[j * MBwidth + i] = value
- apply invert bit as necessary
vc1DECBITPL_DecodeDiff2Bits
This function takes a bitplane data structure, an invert bit, and the width and height of the frame in macroblocks. It decodes 1 bit per MB.
- call vc1DECBITPL_DecodeNorm2Bits with the invert parameter set to false
- call vc1DECBITPL_BitplaneDiff
vc1DECBITPL_DecodeDiff6Bits
This function takes a bitplane data structure, an invert bit, and the width and height of the frame in macroblocks. It decodes 1 bit per MB.
- call vc1DECBITPL_DecodeNorm6Bits with the invert parameter set to false
- call vc1DECBITPL_BitplaneDiff
vc1DECBITPL_DecodeNorm2Bits
This function takes a bitplane data structure, an invert bit, and the width and height of the frame in macroblocks. It decodes 1 bit per MB.
- MBcount = MBwidth * MBheight
- if MBcount is odd
- 1 bit: first bitplane flag
- apply invert flag as necessary
- count--
- foreach i in count/2
- VLC: Norm-2 table VLC
- the decoded VLC contains the next 2 bits, xy: x represents the 1st of the 2 bits and y is the second
- apply invert flag as necessary
vc1DECBITPL_DecodeNorm6Bits
This function takes a bitplane data structure, an invert bit, and the width and height of the frame in macroblocks. It decodes 1 bit per MB. The bitplane data structure is assumed to be arranged as a macroblock frame with (width x height) macroblocks.
- if the MBheight is divisible by 3 but the MBwidth is not
- decode using 2x3 tiles
- compute ResidualX as MBwidth & 1
- set ResidualY 0
- foreach 2x3 tile in bitplane data structure progressing from left -> right, top -> bottom
- VLC: 6-bit decoded value
- the decoded 6-bit value is laid out as 'abcdef' which corresponds to the following arrangement in the bitplane:
f e d c b a
- apply invert flag as necessary
- else
- decode using 3x2 tiles
- compute ResidualX as MBwidth % 3
- compute ResidualY as MBwidth & 1
- foreach 3x2 tile in bitplane data structure progressing from left -> right, top -> bottom
- VLC: 6-bit decoded value
- the decoded 6-bit value is laid out as 'abcdef' which corresponds to the following arrangement in the bitplane:
f e d c b a
- apply invert flag as necessary
- decode residual bits of frame edges using colskip and rowskip algorithms
(UNFINISHED)
vc1DECBITPL_DecodeRawBits
This function is conceptually a no-op. In raw mode, the bitplane is not encoded at all. 8 bitplane bits are packed into each byte and are read from right -> left.
vc1DECBITPL_DecodeRowskipBits
This function takes a bitplane data structure, an invert bit, and the width and height of the frame in macroblocks. It decodes 1 bit per MB. The bitplane data structure is assumed to be arranged as a macroblock frame with (width x height) macroblocks.
- foreach j in 0..MBheight - 1
- 1 bit: row skip value (rowskip)
- foreach i in 0..MBwidth - 1
- value rowskip is 1
- 1 bit: value
- bitplane_macroblock[j * MBwidth + i] = value
- apply invert bit as necessary
- value rowskip is 1
vc1DECBITPL_ReadBitplane
This function decodes a bitplane from an encoded VC-1 bitstream using 1 of a number of different methods.
- 1 bit: bitplane invert
- VLC: I-mode table VLC
- initialize bitplane data structure BP:
- BP.position = 0
- BP.RawMode = false
- select bitplane decoding method using I-mode VLC:
- 0: normal-2 bitplane coding, call vc1DECBITPL_DecodeNorm2Bits
- 1: normal-6 bitplane coding, call vc1DECBITPL_DecodeNorm6Bits
- 2: rowskip bitplane coding, call vc1DECBITPL_DecodeRowskipBits
- 3: colskip bitplane coding, call vc1DECBITPL_DecodeColskipBits
- 4: diff-2 bitplane coding, call vc1DECBITPL_DecodeDiff2Bits
- 5: diff-6 bitplane coding, call vc1DECBITPL_DecodeDiff6Bits
- 6: raw bitplane coding, vc1DECBITPL_DecodeRawBits
- if the coding mode was not 6 (raw)
- indicate in the master state structure that bitplane coding is used
Each of the 7 bitplane decoding methods take a bitplane structure and the frame width and height expressed in macroblocks, as well as the invert bit decoded in this function. The bitplane decoders use their respective algorithms to decode a map of flags, one per macroblock. If the invert bit is set, each flag is inverted during the bitplane decode operation.
vc1DECBITPL_ReadBitplaneBit
vc1DECBITPL_SkipBitplaneBit
vc1DECBLK_ApplyACPrediction
vc1DECBLK_DecodeBlockLayer
This function unpacks and reconstructs a macroblock.
- foreach block (Y0, Y1, Y2, Y3, U, V) in a macroblock
- if the current macroblock is not skipped
- if the block is intra-coded
- else
- if the current macroblock is not skipped
- vc1INTERP_PredictMB
- vc1RECON_ReconstructMB
vc1DECBLK_UnpackDCDifferential
vc1DECBLK_UnpackInterBlock
vc1DECBLK_UnpackIntraBlock
- zero out the 64-element coefficient array
- if (overlap filter is enabled for this macroblock) or (this is not an intra-coded frame) or (profile is advanced)
- call vc1PREDDCAC_DCDefault with a parameter of 128
- else
- call vc1PREDDCAC_DCDefault with a parameter of 0
- block_type = vc1PREDDCAC_PredictDCAC
- save block type (associate with the current block)
- vc1DECBLK_UnpackDCDifferential
- if the current block is marked as coded
- NZC = 1
- unpack AC coeffs into a temporary 64-element array with vc1DEC3DH_DecodeACRunLevel
- vc1DECZZ_DeZigZagBlock
- else
- no AC coefficients in this block (NZC = 0)
- if AC prediction is enabled for this MB
- compute quantized DC coefficient
- vc1PREDDCAC_CopyDCAC
vc1DECBLK_UnpackSubBlockPattern
vc1DECBLK_UnpackTTBLK
vc1DECMB_AssignCodedBlockPattern
vc1DECMB_DecodeTransformInfo
vc1DECMB_UnpackMacroblockFieldB
vc1DECMB_UnpackMacroblockFieldP
vc1DECMB_UnpackMacroblockFrameB
vc1DECMB_UnpackMacroblockFrameP
vc1DECMB_UnpackMacroblockI
vc1DECMB_UnpackMacroblockLayer
vc1DECMB_UnpackMacroblockProgB
vc1DECMB_UnpackMacroblockProgP
vc1DECMB_UnpackMacroblockProgP1MV
vc1DECMB_UnpackMacroblockProgP4MV
vc1DECMB_UnpackMacroblockProgPSkipped
vc1DECMB_UnpackMBQuantParams
vc1DECMB_UnpackTTMB
vc1DECMV_ApplyMVPrediction
vc1DECMV_UnpackMVData
vc1DECMV_UnpackMVDataInterlace
vc1DECPIC_DisplayField
vc1DECPIC_DisplayPicture
vc1DECPIC_InitialiseAppPicture
vc1DECPIC_ReadAdvancedPictureLayer
vc1DECPIC_ReadPictureLayer
if profile is advanced if picture is interlaced (pState->sSeqParams.Interlace = true) 1 bit: FCM_1 if (FCM_1 != 0) 1 bit: FCM_2 if (FCM_2 is 1) field count = 2 picture format is interlaced (pPosition->ePictureFormat = true) call vc1DECPIC_SetDimensionsInMB if picture format is interlaced validate that the number of macroblocks is allowed under the current profile call vc1DECPIC_UnpackPictureLayerAdvanced else call vc1DECPIC_UnpackPictureLayerSimpleMain
vc1DECPIC_SetDimensionsInMB
This function performs frame size accounting.
- if the profile is either simple or main
- if the picture resolution is configured to be doubled horizontally
- divide the coded width by 2
- if the picture resolution is configured to be doubled vertically
- divide the coded height by 2
- if the picture resolution is configured to be doubled horizontally
- if the picture format specifies interlaced fields
- divide coded height by 2
- width in MB = coded width / 16, rounded up to the nearest MB boundary (MBwidth = (codedwidth + 15) / 16)
- height in MB = coded height / 16, rounded up to the nearest MB boundary (MBheight = (codedheight + 15) / 16)
- frame size in MB = MBwidth * MBheight
vc1DECPIC_UnpackFieldPictureLayer
- if picture format is not progressive
- Position.bottomfieldflag = Position.Position.secondfieldflag
- if PictureParams.TopFieldFirst is false
- Position.bottomfieldflag = 1 - Position.secondfieldflag
- Position.picturetype = PictureParams.PictureType[Position.secondfieldflag]
- if profile is advanced
- BitPlaneCodingUsed = false
- vc1DECPIC_ReadAdvancedPictureLayer
- ZigZagTableIndex = vc1GENTAB_ChooseZigZagTableSet
- PictureParams.Interpolate.Size[X|Y] = 8
- if (picture type is I- or P-frame) or (picture type is "skipped")
- ...
- else
- ...
(UNFINISHED)
vc1DECPIC_UnpackFieldPictureLayerIAdvanced
vc1DECPIC_UnpackFieldPictureLayerPBAdvanced
vc1DECPIC_UnpackInterlaceMVModeParams
vc1DECPIC_UnpackPanScanParams
vc1DECPIC_UnpackPictureLayer
- call vc1DECPIC_ReadPictureLayer
- foreach field in the picture
vc1DECPIC_UnpackPictureLayerAdvanced
vc1DECPIC_UnpackPictureLayerSimpleMain
- if there are 8 or fewer bits remaining in the encoded bitstream, skip this picture (unchanged from the previous frame); disregard the remaining bits in the bitstream
- initialize "bitplane coding used" to false
- if frame interpolation flag is true
- 1 bit: frame smoothness interpolation hint
- else
- frame smoothness interpolation hint is set to false
- if profile is simple or main
- 2 bits: frame count (SRD indicates that this is not used by decoder)
- if range reduction flag is set
- 1 bit: range reduction (0 indicates scale value of 8, 1 indicates 16)
- RangeYScale = RangeUVScale = scale value
- else
- RangeYScale = RangeUVScale = 8
- 1 bit: frame type bit 1
- if frame type bit 1 is 1
- frame type is P-frame
- else
- if "max B-frames" is 0
- frame type is I-frame
- else
- 1 bit: frame type bit 2
- if frame type bit 2 is 0
- frame type is B-frame
- else
- frame type is I-frame
- if "max B-frames" is 0
- if frame type is B-frame
- "B fraction processing":
- VLC: B fraction VLC
- The decoded B fraction value indexes into a table that yields a numerator and denominator
- if the denominator is 0
- if the numerator is 1
- invalid B fraction
- if the numerator is 2
- frame type is BI-frame
- (note: SRD makes no provisions for other special cases when denominator is 0)
- if the numerator is 1
- if frame type is I- or BI-frame
- 7 bits: buffer fullness field
- vc1DECPIC_UnpackQuantizationParams
- if (extended motion vectors)
- VLC: motion vector range VLC
- else
- motion vector range is range #0 (see VC-1 Tables)
- if frame type is I- or O-frame
- if MultiResCoding is true
- 2 bits: progressive resolution picture index (see VC-1 Tables: Scaling Modes)
- if frame type is P-frame
- the decoded index needs to match that of the corresponding I-frame
- else progressive resolution picture mode = 1x1 (no scaling)
- if MultiResCoding is true
- at this point, enough information is known to determine image size in MBs; call vc1DECPIC_SetDimensionsInMB
- if frame type is P-frame
- if PictureLayerParams.PQuant > 12
- VLC: P-frame low rate motion vector mode
- else
- VLC: P-frame high rate motion vector mode
- if decoded VLC indicates indicated IC mode
- if profile is simple
- fatal error: IC not allowed in simple profile
- PictureLayerParams.IC[0].icflag = true
- if PictureLayerParams.PQuant > 12
- VLC: P-frame low rate motion vector mode
- else
- VLC: P-frame high rate motion vector mode
- 6 bits: luminance scale value (assign to PictureLayerParams.IC[0].LuminanceScale)
- 6 bits: luminance shift value (assign to PictureLayerParams.IC[0].LuminanceShift)
- if profile is simple
- else
- PictureLayerParams.IC[0].icflag = false
- if PictureLayerParams.PQuant > 12
- else if frame type is B-frame
- determine motion vector type for B-frame:
- if next bit is 0
- frame uses 1 MV/MB, half-pel grid, bilinear filtered
- else
- frame uses 1 MV/MB, full-pel grid
- PictureLayerParams.IC[0].icflag = false
- if frame type is P- or B-frame
- if motion vector mode is mixed mode (3)
- decode motion vector type bitplane by calling vc1DECBITPL_ReadBitplane
- if motion vector mode is mixed mode (3)
- if frame type is B-frame
- decode B-frame direct macroblock bitplace by calling vc1DECBITPL_ReadBitplane
- if (frame type is P- or B-frame
- decode macroblock skip bitplane by calling vc1DECBITPL_ReadBitplane
- 2 bits: which motion vector diff VLC table to use
- 2 bits: which CBP table to use
- vc1DECPIC_UnpackVOPDQUANTParams
- if SequenceParameters.VSTransform
- if next bit is 1
- 2 bits: frame-level block transform type (see VC-1 Tables, block transform types)
- else
- no frame-level block transform type
- if next bit is 1
- else
- block transform type for entire frame = 8x8
- decode frame level transform AC coding set index based on next 1-2 bits:
- 0 = 0
- 10 = 1
- 11 = 2
- if frame type is I- or BI-frame, decode frame level transform AC coding set index #2 based on next 1-2 bits:
- 0 = 0
- 10 = 1
- 11 = 2
- 1 bit: which intra transform DC table to use
- PictureParams.ConditionalOverlap = 1 (indicate that all MBs overlap smooth)
- if (frame type is B-frame) or (PictureParams.PQuant < 9) or (overlapped transform flag is false)
- PictureParams.ConditionalOverlap = 0 (indicate that no MBs overlap smooth)
vc1DECPIC_UnpackQuantizationParams
- 5 bits: picture quantizer (PQ) index
- if SequenceParameters.eQuantizer != 1 (1 indicates quantizer is explicity signaled)
- if PQ index is 0
- invalid PQ index (0 is reserved or forbidden)
- vc1IQUANT_GetQuantizer
- store the quantizer returned from the previous step's call in the Params data structure
- save the information of whether the decoded quantizer is uniform or non-uniform
- if PQ index is 0
- else
- The quantizer is explicit, and signaled on a per frame basis (vs. a per layer basis?)
- initialize half QP step = 0
- if PQ index >= 8
- 1 bit: half QP step (needs to be copied into each MB struct later)
- if quantizer is explicit
- 1 bit: picture quantizer type
- if picture quantizer type is 0
- set Params.Quantizer as non-uniform
- vc1IQUANT_GetQuantizer, save quantizer
- else
- set Params.Quantizer as uniform
- vc1IQUANT_GetQuantizer, save quantizer
vc1DECPIC_UnpackSyncmarker
This function unpacks a sync marker but discards the payload data.
- 24 bits: first part of sync marker
- if sync marker is 0x0000AA
- 5-byte sync marker; read and discard next 5 bytes
- else if sync marker is 0x0000AB
- 11-byte sync marker, read and discard next 11 bytes
- else
- unknown sync marker; fatal error
vc1DECPIC_UnpackVOPDQUANTParams
- if SequenceLayerParams.DQuant is either 1 or 3
- 1 bit: MB quantization frame value
- if value is 1
- 2 bits: MB quantization profile
- if profile is 0
- quantization mode is: MB quantisation selection on all four edges; Edge macroblocks use ALTPQUANT
- else if profile is 1
- MB quantisation selection on pair of edges
- 2 bits: which pair of edges:
- 0: Left/Top macroblocks use ALTPQUANT
- 1: Top/Right macroblocks use ALTPQUANT
- 2: Right/Bottom macroblocks use ALTPQUANT
- 3: Bottom/Left macroblocks use ALTPQUANT
- else if profile is 2
- MB quantisation selection on single edges
- 2 bits: which edge:
- 0: Left macroblocks use ALTPQUANT
- 1: Top macroblocks use ALTPQUANT
- 2: Right macroblocks use ALTPQUANT
- 3: Bottom macroblocks use ALTPQUANT
- else if profile is 3
- Macroblock quantization bi-level
- 1 bit: value
- if value is 0
- quantization mode is: Any QUANT selected on a macroblock basis
- else
- PQUANT/ALTPQUANT selected on macroblock basis
- else
- quantization mode is: default (all MBs use PQUANT)
- else if SequenceLayerParams.DQuant is 2
- quantization mode is: Edge macroblocks use ALTPQUANT
- if SequenceLayerParams.DQuant is 1, 2, or 3
- decode pquant value
- if quantizer mode is "Any QUANT selected on a macroblock basis" or "All macroblocks use PQUANT"
- 3 bits: value (PQuant differential or escape code)
- if value != 7
- altpquant = pquant + value + 1
- else
- 5 bits: altpquant
- else
- altpquant = 0
- quantizer mode is: All macroblocks use PQUANT
vc1DECSEQ_UnpackSequenceLayer
vc1DECSLICE_DecodeSlice
vc1DECZZ_DeZigZag
vc1DECZZ_DeZigZagBlock
vc1DERIVEMV_DecideChromaBlockType
vc1DERIVEMV_DeriveChromaMV
vc1DERIVEMV_DeriveIntFieldMV
vc1DERIVEMV_DeriveIntFrameDirectMV
vc1DERIVEMV_DeriveMV
vc1DERIVEMV_DeriveProgMV
vc1DERIVEMV_DeriveSecondStageChromaMV
vc1DERIVEMV_DirectMV
vc1DERIVEMV_FillInInterlaceFieldMV
vc1DERIVEMV_StoreMotionVectors
vc1INTERP_AverageBlocks
This function takes pointers to 2 64-element byte arrays and averages them into a third 64-element byte array. The averaging weights up:
average = (a + b + 1) / 2
vc1INTERP_CopyPatch
This function is called when there is no need to do any inter-pixel interpolation because the X and Y coordinates line up on the fractional pel grid.
vc1INTERP_InterlaceDiffMB
vc1INTERP_InterlacePredMB
vc1INTERP_InterpolateBlock
vc1INTERP_InterpPatchHalfPelBicubic
This function takes X and Y coordinates in half-pel coordinate. It calls vc1INTERP_InterpPatchQuarterPelBicubic after multiplying each coordinate by 2.
vc1INTERP_InterpPatchHalfPelBilinear
This function takes X and Y coordinates in half-pel coordinate. It calls vc1INTERP_InterpPatchQuarterPelBilinear after multiplying each coordinate by 2.
vc1INTERP_InterpPatchQuarterPelBicubic
This function takes X and Y coordinates in quarter pel coordinates.
- if X and Y are both divisible by 4
- else if X is divisible by 4
- else if Y is divisible by 4
- else
vc1INTERP_InterpPatchQuarterPelBicubicDiag
vc1INTERP_InterpPatchQuarterPelBicubicHoriz
This function takes a pointer to a plane of byte samples and the quarter-pel coordinates of a rectangle to interpolate and returns a rectangle of interpolated samples. This function is used for the case when the X quarter-pel coordinate is not divisible by 4 but the Y quarter-pel coordinate is. Further, this function also accepts a flag governing whether the interpolated values should be rounded to the nearest number or always rounded down.
This is the precise interpolation algorithm:
- derive the full-pel X and Y coordinates of the rectangle by dividing the quarter-pel coordinates by 4 (shift right by 2 for proper accuracy)
- foreach rectangle row (Y) as specified by the rectangle height
- foreach pixel in the row (X) as specified by the rectangle width:
- compute the interpolated pixel @ (X, Y) as:
- foreach pixel in the row (X) as specified by the rectangle width:
ROUND(a0p0 + a1p1 + a2p2 + a3p3) / divisor
where:
- p0 = sample @ (X - 1, Y)
- p1 = sample @ (X, Y)
- p2 = sample @ (X + 1, Y)
- p3 = sample @ (X + 2, Y)
- coefficients [a0...a3] depend on whether the quarter-pel X coordinate falls at the 1/4, 1/2, or 3/4 point between 2 pixels; see VC-1 Tables for the coefficients
- if the samples are to be rounded up ROUND() adds the quantity (divisor / 2 - 1) to the sum before division
- divisor is always a power of 2 so the sum can be shifted right by (log2divisor) for speed; the rounding portion of the previous step counts on this; see VC-1 Tables for the possible divisors
- the final sample is saturated to an unsigned byte range of 0..255
vc1INTERP_InterpPatchQuarterPelBicubicVert
This function takes a pointer to a plane of byte samples and the quarter-pel coordinates of a rectangle to interpolate and returns a rectangle of interpolated samples. This function is used for the case when the Y quarter-pel coordinate is not divisible by 4 but the X quarter-pel coordinate is. Further, this function also accepts a flag governing whether the interpolated values should be rounded to the nearest number or always rounded down.
This is the precise interpolation algorithm:
- derive the full-pel X and Y coordinates of the rectangle by dividing the quarter-pel coordinates by 4 (shift right by 2 for proper accuracy)
- foreach rectangle row (Y) as specified by the rectangle height
- foreach pixel in the row (X) as specified by the rectangle width:
- compute the interpolated pixel @ (X, Y) as:
- foreach pixel in the row (X) as specified by the rectangle width:
ROUND(a0p0 + a1p1 + a2p2 + a3p3) / divisor
where:
- p0 = sample @ (X, Y - 1)
- p1 = sample @ (X, Y)
- p2 = sample @ (X, Y + 1)
- p3 = sample @ (X, Y + 2)
- coefficients [a0...a3] depend on whether the quarter-pel Y coordinate falls at the 1/4, 1/2, or 3/4 point between 2 pixels; see VC-1 Tables for the coefficients
- if the samples are to be rounded up ROUND() adds the quantity (divisor / 2 - 1) to the sum before division
- divisor is always a power of 2 so the sum can be shifted right by (log2divisor) for speed; the rounding portion of the previous step counts on this; see VC-1 Tables for the possible divisors
- the final sample is saturated to an unsigned byte range of 0..255
vc1INTERP_InterpPatchQuarterPelBilinear
This function takes a pointer to a plane of byte samples and the quarter-pel coordinates of a rectangle to interpolate and returns a rectangle of interpolated samples. Further, this function accepts a flag governing whether the interpolated values should be rounded to the nearest number or always rounded down.
This is the precise interpolation algorithm:
- derive the full-pel X and Y coordinates of the rectangle by dividing the quarter-pel coordinates by 4 (shift right by 2 for proper accuracy)
- foreach rectangle row (Y) as specified by the rectangle height
- foreach pixel in the row (X) as specified by the rectangle width:
- compute the interpolated pixel @ (X, Y) as:
- foreach pixel in the row (X) as specified by the rectangle width:
ROUND(axayp0 + axbyp1 + bxayp2 + bxbyp3) / 16
where:
- p0 = pixel @ (X, Y)
- p1 = pixel @ (X + 1, Y)
- p2 = pixel @ (X, Y + 1)
- p3 = pixel @ (X + 1, Y + 2)
- the a and b coefficients are defined in VC-1 Tables; the x and y indices are the quarter-pel fractional coordinates of the rectangle, i.e.:
x = (x quarter-pel coordinate & 3) y = (y quarter-pel coordinate & 3)
- the ROUND() function adds 8 to the sum before division if rounding control flag indicates that the interpolation should round towards to the nearest number vs. always rounding down
- the division by 16 should be carried out as a bit shift right by 4 bits to maintain accuracy
vc1INTERP_PredictMB
- vc1DERIVEMV_StoreMotionVectors
- if macroblock is not intra-coded
- vc1DERIVEMV_DeriveMV
- foreach block in MB (Y0, Y1, Y2, Y3, U, V)
- if block is intra-coded
- iterate to next block
- switch = 0
- if this MB type is a switch MV
- if the block is either the U or V component
- switch = 1
- if the block is either the U or V component
- if the MB uses forward prediction
- call vc1INTERP_InterpolateBlock using the (switch) parameter
- else if the MV uses backward prediction
- call vc1INTERP_InterpolateBlock using the (switch) parameter inverted
- else
- block uses both forward and backward prediction
- call vc1INTERP_InterpolateBlock with a (switch) parameter of 0
- call vc1INTERP_InterpolateBlock with a (switch) parameter of 1
- call vc1INTERP_AverageBlocks to average the 2 interpolated blocks
- if block is intra-coded
vc1IQUANT_ChooseQuantizer
vc1IQUANT_GetQuantizer
vc1IQUANT_InverseACQuantize
vc1IQUANT_InverseDCQuantize
vc1ITRANS_InverseTransform_AnnexA1
This function transforms a MxN block of samples. Learning from problems encountered in earlier coding methods, VC-1 specifies a bit-exact transform that will be outlined here. (This section could use a formal mathematical definition and some research regarding optimizations.)
VC-1 block sizes are 4x4, 4x8, 8x4, and 8x8. The transform takes 4 parameters: input[64], output[64], width, and height. For the transform matrices and constants, see VC-1 Tables-- Transform Tables
- declare temp_matrix[64]
- if width is 8
- transform_matrix = transform_matrix_8x8
- else
- transform_matrix = transform_matrix_4x4
- row transform:
- foreach j in 0..height - 1
- foreach i in 0..width - 1
- accumulator = 0
- foreach k in 0..width - 1
- accumulator += input[j * 8 + k] * transform_matrix[k * width + i]
- temp_matrix[j * 8 + i] = (accumulator + 4) / 8
- foreach i in 0..width - 1
- if height is 8
- transform_matrix = transform_matrix_8x8
- else
- transform_matrix = transform_matrix_4x4
- if height is 8
- constants = constants_8
- else
- constants = constants_4
- column transform:
- foreach i in 0..width - 1
- foreach j in 0..height - 1
- accumulator = 0
- foreach k in 0..height - 1
- accumulator += temp_matrix[i + k * 8] * transform_matrix[k * height + j]
- output[i + j * 8] = (accumulator + constants[j] + 64) / 128
- foreach j in 0..height - 1
vc1ITRANS_InverseTransformBlock
This function takes a buffer of 64 transformed samples laid out as an 8x8 matrix.
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
If the block type is 8x8, the array is passed to vc1ITRANS_InverseTransform_AnnexA1 to be transformed. If the block type is 8x4 this function partitions the array into 2 halves and calls vc1ITRANS_InverseTransform_AnnexA1 twice.
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
The same goes for a 4x8 block size, except that the block to be transformed is split in half vertically:
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
Finally, the block type might be 4x4 which partitions the block and calls vc1ITRANS_InverseTransform_AnnexA1 4 times:
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
vc1PRED_pB1MVBlk
vc1PRED_pB4MVBlk
vc1PRED_pLeftBlk
vc1PRED_pLeftMB
vc1PRED_pTopBlk
vc1PREDCBP_ApplyCBPCYPred
This function takes the position of a macroblock in a frame as well as a vector of differential bits for the MB's coded block pattern (CBP). This differential vector shall be expressed as having components (DY0, DY1, DY2, DY3, DCb, DCr). This function evaluates which of the surrounding blocks are coded and predicts the current MB's CBP based on those blocks. The prediction only applies to the Y blocks. This is the arrangement of the relevant MBs with respect to the current MB:
top-left | top |
left | current |
The Y blocks of each MB can be expanded thusly:
LT0 | LT1 | T0 | T1 |
LT2 | LT3 | T2 | T3 |
L0 | L1 | Y0 | Y1 |
L2 | L3 | Y2 | Y3 |
Each of those 12 Y blocks in the top, left, and top-left MBs contains a bit specifying whether it is coded in this frame. Depending on where the current MB is in the frame, any of the 3 predicting MBs may not exist which makes all of their constituent coded bits 0. This is the algorithm for applying the predictors to find the actual CBP:
- if LT3 == T2
- Y0 = L1 XOR DY0
- else
- Y0 = T2 XOR DY0
- if T2 == T3
- Y1 = Y0 XOR DY1
- else
- Y1 = T3 XOR DY1
- if L1 == Y0
- Y2 = L3 XOR DY2
- else
- Y2 = Y0 XOR DY2
- if Y0 == Y1
- Y3 = Y2 XOR DY3
- else
- Y3 = Y1 XOR DY3
vc1PREDDCAC_ACPREDPresent
vc1PREDDCAC_CopyDCAC
vc1PREDDCAC_DCDefault
Compute a block's default DC predictor. The function takes a quantizer for the entire MB and a bias (either 0 or 128). The default is expected to be round(8*(128-Bias)/DCStepSize).
- if bias is 128
- return 0
- dc_step_size = vc1PREDDCAC_DCStepSize(quantizer)
- return ((1024 + (dc_step_size >> 1)) / dc_step_size)
vc1PREDDCAC_DCStepSize
This function takes a quantization step size and returns a calculated DC step size. This function only applies towards 8x8 intra-coded blocks.
- if (quantizer < 4)
- return (1 << quantizer)
- else
- return (quantizer / 2) + 6
vc1PREDDCAC_GetQuant
vc1PREDDCAC_PredictDCAC
This function predicts the DC and AC coefficients for a block based on the surrounding blocks that have already been decoded.
This is the arrangement of the relevant MBs with respect to the current MB:
top-left | top |
left | current |
The Y blocks of each MB can be expanded thusly:
LT0 | LT1 | T0 | T1 |
LT2 | LT3 | T2 | T3 |
L0 | L1 | Y0 | Y1 |
L2 | L3 | Y2 | Y3 |
Y0 predicts from blocks LT3, T2 and L1, if they exist (i.e., if the current macroblock is not on a frame boundary). Y1 predicts from blocks Y0 (always) and T2 and T3 if they exist. Y2 predicts from Y0 (always) and L1 and L3 if they exist. Y3 always predicts from Y0, Y1 and Y2.
For the 2 chrominance blocks (U and V): Each is predicted from the same component blocks from the top, left, and top-left macroblocks if those MBs exist.
- if (top block exists) and (top block is intra-coded)
- if (left block exists) and (top block is intra-coded)
- ...
- else
- ...
- if (left block exists) and (top block is intra-coded)
- else
- if (top-left block exists) and (top-left block is intra-coded)
- ...
- if (top-left block exists) and (top-left block is intra-coded)
- ... prediction logic ...
(UNFINISHED)
vc1PREDDCAC_ScaleDC
This function takes a DC coefficient, an old quantizer value and a new quantizer value. It scales the DC coefficient per the new quantizer value vs. the old value. Both quantizers are represented as (2 * quantizer + half-step).
- remove the half-step by shifting the old and new quantizer values right 1 bit
- if the new quantizer is not the same as the old quantizer
- new quantizer = vc1PREDDCAC_DCStepSize(new quantizer)
- old quantizer = vc1PREDDCAC_DCStepSize(old quantizer)
- DC value = (vc1PREDDCAC_DQScaleTable[new quantizer] * old quantizer + 0x20000) >> 18
vc1PREDMV_FrameMBPred
vc1PREDMV_PredictInterlacedFieldMV
vc1PREDMV_PredictInterlacedFrameMV
vc1PREDMV_PredictProgressiveMV
vc1RECON_ApplyPredictionAndCopyMB
vc1RECON_ReconstructMB
vc1SCALEMV_InitScaleMV
vc1SCALEMV_ScaleMV
vc1SMOOTH_OverlapSmoothHorizBlk
vc1SMOOTH_OverlapSmoothHorizMB
vc1SMOOTH_OverlapSmoothMB
vc1SMOOTH_OverlapSmoothVertBlk
vc1TOOLS_CopyReference
This function copies an entire reference picture and all associated data structures to another. The reference source notes that it is to be used in the case of a skipped frame.
vc1TOOLS_GetPictureDestination
Provided a block number, this function returns a data structure with the information about that block.
vc1TOOLS_ICComponent
vc1TOOLS_ICPadReferencePicture
vc1TOOLS_InitImagePosition
vc1TOOLS_InitReferencePicture
vc1TOOLS_IntensityCompensate
vc1TOOLS_Median3
The Median3 function takes 3 numbers as input and returns the middle value of the 3.
vc1TOOLS_Median4
The Median4 function takes 4 numbers as input and returns the average between the middle 2 values of the set, weighted down. For 4 inputs, (a, b, c, d), find the minimum and maximum values of the set (min, max) and the median4 value is computed as:
(a + b + c + d - min - max) / 2
vc1TOOLS_NewReference
vc1TOOLS_PadComponent
vc1TOOLS_PadReferencePicture
vc1TOOLS_RangeExpand
This function takes a scale value and a pointer to a rectangle of byte values and performs the following operation on each byte in the rectangle:
byte = (((byte - 128) * scale + 4) / 8) + 128
The final arithmetic is saturated to an unsigned byte range (0..255).
vc1TOOLS_RangeReduce16
This function takes a pointer to a rectangle of byte values and performs the following operation on each byte:
byte = ((byte - 128) / 2) + 128
vc1TOOLS_RangeReduceReference
This function performs intensity compensation on a reference picture. It takes a reference picture data structure and a new range reduction value. Then, for each of the planes, Y, U, and V:
if range reduction value is 16 then call RangeReduce16 with the entire plane as the rectangle else call RangeExpand with the entire plane as the rectange and 16 as the scale value
note: if 16 is always the scale value, then there is an optimization opportunity in RangeExpand()
vc1TOOLS_ResolutionUpsample
The reference decoder includes the upsampling filter but the exact implementation is not defined in the official spec.
(TODO: Fill in the reference decoder's algorithm anyway)