Understanding VC-1

From MultimediaWiki
Jump to navigation Jump to search

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

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.

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.

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

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

vc1DECBITPL_ReadBitplane

This function decodes a bitplane from an encoded VC-1 bitstream using 1 of a number of different methods.

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

vc1DECBLK_UnpackDCDifferential

vc1DECBLK_UnpackInterBlock

vc1DECBLK_UnpackIntraBlock

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 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
  • 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
    • call vc1DECPIC_UnpackFieldPictureLayer

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 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 frame type is I- or BI-frame
    • 7 bits: buffer fullness field
  • vc1DECPIC_UnpackQuantizationParams
  • if (extended motion vectors)
    • VLC: motion vector range VLC
  • else
  • 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)
  • 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)
    • else
      • PictureLayerParams.IC[0].icflag = false
  • 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 frame type is B-frame
  • 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
    • else
      • block transform type for entire frame = 8x8
  • decode frame level transform AC coding set index based on next 1-2 bits:
    • 0 = 0
    • 00 = 1
    • 01 = 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
    • 00 = 1
    • 01 = 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
  • 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

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 array. The averaging weights up:

 average = (a + b + 1) / 2

vc1INTERP_CopyPatch

vc1INTERP_InterlaceDiffMB

vc1INTERP_InterlacePredMB

vc1INTERP_InterpolateBlock

vc1INTERP_InterpPatchHalfPelBicubic

vc1INTERP_InterpPatchHalfPelBilinear

vc1INTERP_InterpPatchQuarterPelBicubic

vc1INTERP_InterpPatchQuarterPelBicubicDiag

vc1INTERP_InterpPatchQuarterPelBicubicHoriz

vc1INTERP_InterpPatchQuarterPelBicubicVert

vc1INTERP_InterpPatchQuarterPelBilinear

vc1INTERP_PredictMB

vc1IQUANT_ChooseQuantizer

vc1IQUANT_GetQuantizer

vc1IQUANT_InverseACQuantize

vc1IQUANT_InverseDCQuantize

vc1ITRANS_InverseTransform_AnnexA1

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

vc1PREDDCAC_DCStepSize

vc1PREDDCAC_GetQuant

vc1PREDDCAC_PredictDCAC

vc1PREDDCAC_ScaleDC

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)