package dependencydescriptor import "errors" type DependencyDescriptorReader struct { // Output. descriptor *DependencyDescriptor // Values that are needed while reading the descriptor, but can be discarded // when reading is complete. buffer *BitStreamReader frameDependencyTemplateId int activeDecodeTargetsPresentFlag bool customDtisFlag bool customFdiffsFlag bool customChainsFlag bool structure *FrameDependencyStructure } func NewDependencyDescriptorReader(buf []byte, structure *FrameDependencyStructure, descriptor *DependencyDescriptor) *DependencyDescriptorReader { buffer := NewBitStreamReader(buf) return &DependencyDescriptorReader{ buffer: buffer, descriptor: descriptor, structure: structure, } } func (r *DependencyDescriptorReader) Parse() (int, error) { if err := r.readMandatoryFields(); err != nil { return 0, err } if len(r.buffer.buf) > 3 { err := r.readExtendedFields() if err != nil { return 0, err } } if r.descriptor.AttachedStructure != nil { r.structure = r.descriptor.AttachedStructure } if r.structure == nil { r.buffer.Invalidate() return 0, errors.New("DependencyDescriptorReader: Structure is nil") } if r.activeDecodeTargetsPresentFlag { bitmask, err := r.buffer.ReadBits(r.structure.NumDecodeTargets) if err != nil { return 0, err } mask := uint32(bitmask) r.descriptor.ActiveDecodeTargetsBitmask = &mask } err := r.readFrameDependencyDefinition() if err != nil { return 0, err } return r.buffer.ReadedBytes(), nil } func (r *DependencyDescriptorReader) readMandatoryFields() error { var err error r.descriptor.FirstPacketInFrame, err = r.buffer.ReadBool() if err != nil { return err } r.descriptor.LastPacketInFrame, err = r.buffer.ReadBool() if err != nil { return err } templateID, err := r.buffer.ReadBits(6) if err != nil { return err } r.frameDependencyTemplateId = int(templateID) frameNumber, err := r.buffer.ReadBits(16) if err != nil { return err } r.descriptor.FrameNumber = uint16(frameNumber) return nil } func (r *DependencyDescriptorReader) readExtendedFields() error { templateDependencyStructurePresentFlag, err := r.buffer.ReadBool() if err != nil { return err } flag, err := r.buffer.ReadBool() if err != nil { return err } r.activeDecodeTargetsPresentFlag = flag flag, err = r.buffer.ReadBool() if err != nil { return err } r.customDtisFlag = flag flag, err = r.buffer.ReadBool() if err != nil { return err } r.customFdiffsFlag = flag flag, err = r.buffer.ReadBool() if err != nil { return err } r.customChainsFlag = flag if templateDependencyStructurePresentFlag { err = r.readTemplateDependencyStructure() if err != nil { return err } if r.descriptor.AttachedStructure == nil { return errors.New("DependencyDescriptorReader: has templateDependencyStructurePresentFlag but AttachedStructure is nil") } bitmask := uint32((uint64(1) << r.descriptor.AttachedStructure.NumDecodeTargets) - 1) r.descriptor.ActiveDecodeTargetsBitmask = &bitmask } return nil } func (r *DependencyDescriptorReader) readTemplateDependencyStructure() error { r.descriptor.AttachedStructure = &FrameDependencyStructure{} structureId, err := r.buffer.ReadBits(6) if err != nil { return err } r.descriptor.AttachedStructure.StructureId = int(structureId) numDecodeTargets, err := r.buffer.ReadBits(5) if err != nil { return err } r.descriptor.AttachedStructure.NumDecodeTargets = int(numDecodeTargets) + 1 if err = r.readTemplateLayers(); err != nil { return err } if err = r.readTemplateDtis(); err != nil { return err } if err = r.readTemplateFdiffs(); err != nil { return err } if err = r.readTemplateChains(); err != nil { return err } flag, err := r.buffer.ReadBool() if err != nil { return err } if flag { return r.readResolutions() } return nil } type nextLayerIdcType int const ( sameLayer nextLayerIdcType = iota nextTemporalLayer nextSpatialLayer noMoreLayer invalidLayer ) func (r *DependencyDescriptorReader) readTemplateLayers() error { var ( templates []*FrameDependencyTemplate temporalId, spatialId int nextLayerIdc nextLayerIdcType ) for { if len(templates) == MaxTemplates { return errors.New("DependencyDescriptorReader: too many templates") } var lastTemplate FrameDependencyTemplate templates = append(templates, &lastTemplate) lastTemplate.TemporalId = temporalId lastTemplate.SpatialId = spatialId idc, err := r.buffer.ReadBits(2) if err != nil { return err } nextLayerIdc = nextLayerIdcType(idc) if nextLayerIdc == nextTemporalLayer { temporalId++ if temporalId >= MaxTemporalIds { return errors.New("DependencyDescriptorReader: too many temporal layers") } } else if nextLayerIdc == nextSpatialLayer { spatialId++ temporalId = 0 if spatialId >= MaxSpatialIds { return errors.New("DependencyDescriptorReader: too many spatial layers") } } if !(nextLayerIdc != noMoreLayer && r.buffer.Ok()) { break } } r.descriptor.AttachedStructure.Templates = templates return nil } func (r *DependencyDescriptorReader) readTemplateDtis() error { structure := r.descriptor.AttachedStructure for _, template := range structure.Templates { if len(template.DecodeTargetIndications) < structure.NumDecodeTargets { template.DecodeTargetIndications = append(template.DecodeTargetIndications, make([]DecodeTargetIndication, structure.NumDecodeTargets-len(template.DecodeTargetIndications))...) } else { template.DecodeTargetIndications = template.DecodeTargetIndications[:structure.NumDecodeTargets] } for i := range template.DecodeTargetIndications { indication, err := r.buffer.ReadBits(2) if err != nil { return err } template.DecodeTargetIndications[i] = DecodeTargetIndication(indication) } } return nil } func (r *DependencyDescriptorReader) readTemplateFdiffs() error { for _, template := range r.descriptor.AttachedStructure.Templates { for { fdiffFollow, err := r.buffer.ReadBool() if err != nil { return err } if !fdiffFollow { break } fDiffMinusOne, err := r.buffer.ReadBits(4) if err != nil { return err } template.FrameDiffs = append(template.FrameDiffs, int(fDiffMinusOne+1)) } } return nil } func (r *DependencyDescriptorReader) readTemplateChains() error { structure := r.descriptor.AttachedStructure numChains, err := r.buffer.ReadNonSymmetric(uint32(structure.NumDecodeTargets) + 1) if err != nil { return err } structure.NumChains = int(numChains) if structure.NumChains == 0 { return nil } for i := 0; i < structure.NumDecodeTargets; i++ { protectedByChain, err := r.buffer.ReadNonSymmetric(uint32(structure.NumChains)) if err != nil { return err } structure.DecodeTargetProtectedByChain = append(structure.DecodeTargetProtectedByChain, int(protectedByChain)) } for _, frameTemplate := range structure.Templates { for chainId := 0; chainId < structure.NumChains; chainId++ { chainDiff, err := r.buffer.ReadBits(4) if err != nil { return err } frameTemplate.ChainDiffs = append(frameTemplate.ChainDiffs, int(chainDiff)) } } return nil } func (r *DependencyDescriptorReader) readResolutions() error { structure := r.descriptor.AttachedStructure // The way templates are bitpacked, they are always ordered by spatial_id. spatialLayers := structure.Templates[len(structure.Templates)-1].SpatialId + 1 for sid := 0; sid < spatialLayers; sid++ { widthMinus1, err := r.buffer.ReadBits(16) if err != nil { return err } heightMinus1, err := r.buffer.ReadBits(16) if err != nil { return err } structure.Resolutions = append(structure.Resolutions, RenderResolution{ Width: int(widthMinus1 + 1), Height: int(heightMinus1 + 1), }) } return nil } func (r *DependencyDescriptorReader) readFrameDependencyDefinition() error { templateIndex := (r.frameDependencyTemplateId + MaxTemplates - r.structure.StructureId) % MaxTemplates if templateIndex >= len(r.structure.Templates) { r.buffer.Invalidate() return errors.New("DependencyDescriptorReader: invalid template index") } // Copy all the fields from the matching template r.descriptor.FrameDependencies = r.structure.Templates[templateIndex].Clone() if r.customDtisFlag { err := r.readFrameDtis() if err != nil { return err } } if r.customFdiffsFlag { err := r.readFrameFdiffs() if err != nil { return err } } if r.customChainsFlag { err := r.readFrameChains() if err != nil { return err } } if len(r.structure.Resolutions) == 0 { r.descriptor.Resolution = nil } else { // Format guarantees that if there were resolutions in the last structure, // then each spatial layer got one. if r.descriptor.FrameDependencies.SpatialId >= len(r.structure.Resolutions) { r.buffer.Invalidate() return errors.New("DependencyDescriptorReader: invalid spatial layer, should be less than the number of resolutions") } res := r.structure.Resolutions[r.descriptor.FrameDependencies.SpatialId] r.descriptor.Resolution = &res } return nil } func (r *DependencyDescriptorReader) readFrameDtis() error { if len(r.descriptor.FrameDependencies.DecodeTargetIndications) != r.structure.NumDecodeTargets { return errors.New("DependencyDescriptorReader: decode target indications length mismatch with structure num decode targets") } for i := range r.descriptor.FrameDependencies.DecodeTargetIndications { indication, err := r.buffer.ReadBits(2) if err != nil { return err } r.descriptor.FrameDependencies.DecodeTargetIndications[i] = DecodeTargetIndication(indication) } return nil } func (r *DependencyDescriptorReader) readFrameFdiffs() error { r.descriptor.FrameDependencies.FrameDiffs = r.descriptor.FrameDependencies.FrameDiffs[:0] for { nexFdiffSize, err := r.buffer.ReadBits(2) if err != nil { return err } if nexFdiffSize == 0 { break } fDiffMinusOne, err := r.buffer.ReadBits(int(nexFdiffSize * 4)) if err != nil { return err } r.descriptor.FrameDependencies.FrameDiffs = append(r.descriptor.FrameDependencies.FrameDiffs, int(fDiffMinusOne+1)) } return nil } func (r *DependencyDescriptorReader) readFrameChains() error { if len(r.descriptor.FrameDependencies.ChainDiffs) != r.structure.NumChains { return errors.New("DependencyDescriptorReader: chain diffs length mismatch with structure num chains") } for i := range r.descriptor.FrameDependencies.ChainDiffs { chainDiff, err := r.buffer.ReadBits(8) if err != nil { return err } r.descriptor.FrameDependencies.ChainDiffs[i] = int(chainDiff) } return nil }