Esempio n. 1
0
        private static void ParseFrameNum(INalUnitReader reader, ISequenceState sequenceState)        // TODO:checks uitbreiden volgens 7.4.3(Current Header Semantics).frame_num specs
        {
            uint frameNum = reader.GetBits((int)sequenceState.Log2MaxFrameNum, Attribute.FrameNumber);

#if DEBUG
            H264Debug.WriteLine("+ frame_num={0} ({1} bits)", frameNum, sequenceState.Log2MaxFrameNum);
#endif
            if (reader.State.IdrPicFlag && (frameNum != 0))
            {
                //FIXME: Some H.264 files seem to use frame number != 0 for IDR pictures!?
                //readerState.Invalidate();
            }
        }
Esempio n. 2
0
        public void Parse(INalUnitReader reader, IResultNodeState resultState)
        {
            var sliceState = reader.State.SliceState;

            if (sliceState == null)
            {
                return;                //Apparently no header data is available, so skip the deepslice parsing.
            }

#if DEBUG
            H264Debug.WriteLine(sliceState.SliceType + " at " + reader.Position + " (" + sliceState.FirstMacroBlockInSlice + ")");
#endif
            var sliceData = CreateSliceData(reader, resultState, sliceState);
            sliceData.Parse();
            H264Debug.DebugEnabled = false;
        }
Esempio n. 3
0
        // 7.3.3 Slice header syntax
        public void Parse(INalUnitReader reader, IResultNodeState resultState)
        {
            reader.State.SliceState = null;                                                                          // Invalid, unless the slice header is valid!

            uint firstMacroblockInSlice = reader.GetExpGolombCoded(Attribute.FirstMacroblockInSlice, uint.MaxValue); // first_mb_in_slice

#if DEBUG
            H264Debug.WriteLine("+ first_mb_in_slice={0}", firstMacroblockInSlice);
#endif
            SliceType pictureSliceType = (SliceType)reader.GetExpGolombCoded(Attribute.SliceType, _sliceTypeResultFormatter);
            SliceType sliceType        = (SliceType)((int)pictureSliceType % 5);
#if DEBUG
            H264Debug.WriteLine("+ slice_type={0}", (int)sliceType);
#endif
            byte pictureParamaterSetId = (byte)reader.GetExpGolombCoded(Attribute.PictureParameterSetId, 255);
#if DEBUG
            H264Debug.WriteLine("+ pic_parameter_set_id={0}", pictureParamaterSetId);
#endif
            var pictureState = reader.State.PictureStates[pictureParamaterSetId];
            if (pictureState == null)
            {
                if (resultState.Valid)
                {
                    if (IsFalseHit(firstMacroblockInSlice, sliceType, pictureParamaterSetId) || (pictureParamaterSetId > 10))
                    {
                        resultState.Invalidate();
                    }
                }
                return;                 // cannot validate slice header!!
            }

            ISliceStateBuilder builder = new SliceStateBuilder(pictureState);
            builder.FirstMacroBlockInSlice = firstMacroblockInSlice;
            builder.SliceType = sliceType;

            if (pictureState.PictureSliceType.HasValue && (sliceType != pictureState.PictureSliceType))
            {
                // FIXME: This rule only applies to slices within a single picture.
                //        Since we currently don't detect whether this slice starts a
                //        new picture, we have to disable this rule for now!
                //				oldIReaderState.Invalidate();
                //				return;
            }
            if (/*!pictureState.PictureSliceType.HasValue && */ sliceType != pictureSliceType)
            {
                pictureState.PictureSliceType = pictureSliceType;
            }
            if (IsNonIntraSliceInIntraCodedPicture(reader, sliceType, pictureState))
            {
                resultState.Invalidate();
                return;
            }

            var sequenceState = pictureState.SequenceState;
            if (sequenceState.ChromaFormat == ChromaFormat.SeparateColorPlane)
            {
                reader.GetBits(2, Attribute.ColorPlane, _colorPlaneResultFormatter);                 // colour_plane_id
            }

            ParseFrameNum(reader, sequenceState);

            bool fieldPicFlag = false;
            if (!sequenceState.FrameMbsOnlyFlag)
            {
                fieldPicFlag         = reader.GetBit();         // field_pic_flag
                builder.FieldPicFlag = fieldPicFlag;
                if (fieldPicFlag)
                {
                    reader.GetBit();                     // bottom_field_flag
                }
            }
            if (reader.State.IdrPicFlag)
            {
                reader.GetExpGolombCoded(Attribute.IdrPictureId, 65535);                 // idr_pic_id
            }
            if (sequenceState.PictureOrderCountType == 0)
            {
                reader.GetBits((int)sequenceState.Log2MaxPicOrderCntLsb);                  // pic_order_cnt_lsb

                if (pictureState.PictureOrderPresent && !fieldPicFlag)
                {
                    reader.GetSignedExpGolombCoded();                     // delta_pic_order_cnt_bottom
                }
            }
            else if ((sequenceState.PictureOrderCountType == 1) && !sequenceState.DeltaPicOrderAlwaysZeroFlag)
            {
                reader.GetSignedExpGolombCoded();                 // delta_pic_order_cnt_0

                if (pictureState.PictureOrderPresent && !fieldPicFlag)
                {
                    reader.GetSignedExpGolombCoded();                     // delta_pic_order_cnt_1
                }
            }
            if (pictureState.RedundantPictureControlPresent)
            {
                reader.GetExpGolombCoded(Attribute.RedundantPictureCounter, 127);                 // redundant_pic_cnt
            }
            if (sliceType == SliceType.B)
            {
                reader.GetBit();                 // direct_spatial_mv_pred_flag
            }

            uint activeReferencePictureCount0 = pictureState.DefaultReferencePictureCount0;
            uint activeReferencePictureCount1 = pictureState.DefaultReferencePictureCount1;
            if (!IsIntraCoded(sliceType) && reader.GetBit())             // num_ref_idx_active_override_flag
            {
                uint maxRefIdxActiveMinus1 = fieldPicFlag ? 31U : 15U;
                activeReferencePictureCount0 = reader.GetExpGolombCoded(maxRefIdxActiveMinus1) + 1;                 // num_ref_idx_l0_active_minus1

                if (sliceType == SliceType.B)
                {
                    activeReferencePictureCount1 = reader.GetExpGolombCoded(maxRefIdxActiveMinus1) + 1;                     // num_ref_idx_l1_active_minus1
                }
            }

            builder.ActiveReferencePictureCount0 = activeReferencePictureCount0;
            builder.ActiveReferencePictureCount1 = activeReferencePictureCount1;

            RefPicListModification(reader, resultState, sliceType);

            if ((pictureState.WeightedPrediction && (sliceType == SliceType.P || sliceType == SliceType.Sp)) ||
                (pictureState.WeightedBidirectionalPrediction == WeightedBidirectionalPredictionType.ExplicitWeightedPrediction && sliceType == SliceType.B))
            {
                PredWeightTable(reader, sequenceState, sliceType, activeReferencePictureCount0, activeReferencePictureCount1);
            }
            if (reader.State.NalRefIdc != 0)
            {
                DecRefPicMarking(reader, resultState);
            }
            if (pictureState.EntropyCodingMode && !IsIntraCoded(sliceType))
            {
                builder.CabacInitIdc = reader.GetExpGolombCoded(2U);
            }

            builder.SliceQpDelta = reader.GetSignedExpGolombCoded();

            if ((sliceType == SliceType.Sp) || (sliceType == SliceType.Si))
            {
                if (sliceType == SliceType.Sp)
                {
                    reader.GetBit();                    // sp_for_switch_flag
                }

                reader.GetSignedExpGolombCoded();                // slice_qs_delta
            }
            if (pictureState.DeblockingFilterControlPresent)
            {
                uint disableDeblockingFilterIdc = reader.GetExpGolombCoded();                   // disable_deblocking_filter_idc
                if (disableDeblockingFilterIdc != 1)
                {
                    reader.GetSignedExpGolombCoded();                           // slice_alpha_c0_offset_div2
                    reader.GetSignedExpGolombCoded();                           // slice_beta_offset_div2
                }
            }
            if (pictureState.SliceGroupCount > 1 &&
                pictureState.SliceGroupMapType >= SliceGroupMapType.ChangingSliceGroups3 && pictureState.SliceGroupMapType <= SliceGroupMapType.ChangingSliceGroups5)
            {
                uint value = (sequenceState.PicSizeInMapUnits / pictureState.SliceGroupChangeRate);
                int  requiredBitsToRepresentValue = DetectorUtils.Log2(value) + 1;
                builder.SliceGroupChangeCycle = reader.GetBits(requiredBitsToRepresentValue);                 // slice_group_change_cycle;
            }

            // Check 'firstMacroblockInSlice' field
            uint picHeightInMbs = sequenceState.FrameHeightInMbs / (fieldPicFlag ? 2U : 1U);
            uint picSizeInMbs   = sequenceState.PicWidthInMbs * picHeightInMbs;
            bool mbAffFrameFlag = sequenceState.MbAdaptiveFrameFieldFlag && !fieldPicFlag;
            if ((firstMacroblockInSlice * (mbAffFrameFlag ? 2U : 1U)) >= picSizeInMbs)
            {
                resultState.Invalidate();
            }

            if (resultState.Valid)
            {
                // Since the 'pictureParameterSetId' is probably correct at this point,
                // we prevent the check for 'pictureParameterSetId > 10'.
                if (IsFalseHit(firstMacroblockInSlice, sliceType, Math.Min((byte)1, pictureParamaterSetId)))
                {
                    resultState.Invalidate();
                }
                else
                {
                    reader.State.SliceState = builder.Build();
                }
            }
        }