Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/platforms/agnostic/bytestreams/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 13 kB image not shown  

Quelle  H265.h   Sprache: C

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef DOM_MEDIA_PLATFORMS_AGNOSTIC_BYTESTREAMS_H265_H_
#define DOM_MEDIA_PLATFORMS_AGNOSTIC_BYTESTREAMS_H265_H_

#include <stdint.h>

#include "mozilla/CheckedInt.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "mozilla/Span.h"
#include "nsTArray.h"

namespace mozilla {

class BitReader;
class MediaByteBuffer;
class MediaRawData;

// Most classes in this file are implemented according to the H265 spec
// (https://www.itu.int/rec/T-REC-H.265-202108-I/en), except the HVCCConfig,
// which is in the ISO/IEC 14496-15. To make it easier to read the
// implementation with the spec, the naming style in this file follows the spec
// instead of our usual style.

enum {
  kMaxLongTermRefPicSets = 32,   // See num_long_term_ref_pics_sps
  kMaxShortTermRefPicSets = 64,  // See num_short_term_ref_pic_sets
  kMaxSubLayers = 7,             // See [v/s]ps_max_sub_layers_minus1
};

// H265NALU represents NALU data (Spec 7.3.1 NAL unit syntax) for convenient
// access. In addition, this class does not own the raw RBSP data. Ensure that
// the original data source remains valid when accessing `mNALU`.
class H265NALU final {
 public:
  H265NALU(const uint8_t* aData, uint32_t aByteSize);
  H265NALU() = default;

  // Table 7-1
  enum NAL_TYPES {
    TRAIL_N = 0,
    TRAIL_R = 1,
    TSA_N = 2,
    TSA_R = 3,
    STSA_N = 4,
    STSA_R = 5,
    RADL_N = 6,
    RADL_R = 7,
    RASL_N = 8,
    RASL_R = 9,
    RSV_VCL_N10 = 10,
    RSV_VCL_R11 = 11,
    RSV_VCL_N12 = 12,
    RSV_VCL_R13 = 13,
    RSV_VCL_N14 = 14,
    RSV_VCL_R15 = 15,
    BLA_W_LP = 16,
    BLA_W_RADL = 17,
    BLA_N_LP = 18,
    IDR_W_RADL = 19,
    IDR_N_LP = 20,
    CRA_NUT = 21,
    RSV_IRAP_VCL22 = 22,
    RSV_IRAP_VCL23 = 23,
    RSV_VCL24 = 24,
    RSV_VCL25 = 25,
    RSV_VCL26 = 26,
    RSV_VCL27 = 27,
    RSV_VCL28 = 28,
    RSV_VCL29 = 29,
    RSV_VCL30 = 30,
    RSV_VCL31 = 31,
    VPS_NUT = 32,
    SPS_NUT = 33,
    PPS_NUT = 34,
    AUD_NUT = 35,
    EOS_NUT = 36,
    EOB_NUT = 37,
    FD_NUT = 38,
    PREFIX_SEI_NUT = 39,
    SUFFIX_SEI_NUT = 40,
    RSV_NVCL41 = 41,
    RSV_NVCL42 = 42,
    RSV_NVCL43 = 43,
    RSV_NVCL44 = 44,
    RSV_NVCL45 = 45,
    RSV_NVCL46 = 46,
    RSV_NVCL47 = 47,
    UNSPEC48 = 48,
    UNSPEC49 = 49,
    UNSPEC50 = 50,
    UNSPEC51 = 51,
    UNSPEC52 = 52,
    UNSPEC53 = 53,
    UNSPEC54 = 54,
    UNSPEC55 = 55,
    UNSPEC56 = 56,
    UNSPEC57 = 57,
    UNSPEC58 = 58,
    UNSPEC59 = 59,
    UNSPEC60 = 60,
    UNSPEC61 = 61,
    UNSPEC62 = 62,
    UNSPEC63 = 63,
  };

  bool IsIframe() const {
    return mNalUnitType == NAL_TYPES::IDR_W_RADL ||
           mNalUnitType == NAL_TYPES::IDR_N_LP;
  }

  bool IsSPS() const { return mNalUnitType == NAL_TYPES::SPS_NUT; }
  bool IsVPS() const { return mNalUnitType == NAL_TYPES::VPS_NUT; }
  bool IsPPS() const { return mNalUnitType == NAL_TYPES::PPS_NUT; }
  bool IsSEI() const {
    return mNalUnitType == NAL_TYPES::PREFIX_SEI_NUT ||
           mNalUnitType == NAL_TYPES::SUFFIX_SEI_NUT;
  }

  uint8_t mNalUnitType;
  uint8_t mNuhLayerId;
  uint8_t mNuhTemporalIdPlus1;
  // This contain the full content of NALU, which can be used to decode rbsp.
  const Span<const uint8_t> mNALU;
};

// H265 spec, 7.3.3 Profile, tier and level syntax
struct H265ProfileTierLevel final {
  H265ProfileTierLevel() = default;

  bool operator==(const H265ProfileTierLevel& aOther) const;

  enum H265ProfileIdc {
    kProfileIdcMain = 1,
    kProfileIdcMain10 = 2,
    kProfileIdcMainStill = 3,
    kProfileIdcRangeExtensions = 4,
    kProfileIdcHighThroughput = 5,
    kProfileIdcMultiviewMain = 6,
    kProfileIdcScalableMain = 7,
    kProfileIdc3dMain = 8,
    kProfileIdcScreenContentCoding = 9,
    kProfileIdcScalableRangeExtensions = 10,
    kProfileIdcHighThroughputScreenContentCoding = 11,
  };

  // From Table A.8 - General tier and level limits.
  uint32_t GetMaxLumaPs() const;

  // From A.4.2 - Profile-specific level limits for the video profiles.
  uint32_t GetDpbMaxPicBuf() const;

  // Syntax elements.
  uint8_t general_profile_space = {};
  bool general_tier_flag = {};
  uint8_t general_profile_idc = {};
  uint32_t general_profile_compatibility_flags = {};
  bool general_progressive_source_flag = {};
  bool general_interlaced_source_flag = {};
  bool general_non_packed_constraint_flag = {};
  bool general_frame_only_constraint_flag = {};
  uint8_t general_level_idc = {};
};

// H265 spec, 7.3.7 Short-term reference picture set syntax
struct H265StRefPicSet final {
  H265StRefPicSet() = default;

  bool operator==(const H265StRefPicSet& aOther) const;

  // Syntax elements.
  uint32_t num_negative_pics = {};
  uint32_t num_positive_pics = {};

  // Calculated fields
  // From the H265 spec 7.4.8
  bool usedByCurrPicS0[kMaxShortTermRefPicSets] = {};  // (7-65)
  bool usedByCurrPicS1[kMaxShortTermRefPicSets] = {};  // (7-66)
  uint32_t deltaPocS0[kMaxShortTermRefPicSets] = {};   // (7-67) + (7-69)
  uint32_t deltaPocS1[kMaxShortTermRefPicSets] = {};   // (7-68) + (7-70)
  uint32_t numDeltaPocs = {};                          // (7-72)
};

// H265 spec, E.2.1 VUI parameters syntax
struct H265VUIParameters {
  H265VUIParameters() = default;

  bool operator==(const H265VUIParameters& aOther) const;

  bool HasValidAspectRatio() const;

  // This should only be called when VUI has a valid aspect ratio.
  double GetPixelAspectRatio() const;

  // Syntax elements.
  bool aspect_ratio_info_present_flag = false;
  uint32_t sar_width = {};
  uint32_t sar_height = {};
  bool video_full_range_flag = {};
  Maybe<uint8_t> colour_primaries;
  Maybe<uint8_t> transfer_characteristics;
  Maybe<uint8_t> matrix_coeffs;

  // Not spec element.
  bool mIsSARValid = false;
};

// H265 spec, 7.3.2.2 Sequence parameter set RBSP syntax
struct H265SPS final {
  H265SPS() = default;

  bool operator==(const H265SPS& aOther) const;
  bool operator!=(const H265SPS& aOther) const;

  // Syntax elements.
  uint8_t sps_video_parameter_set_id = {};
  uint8_t sps_max_sub_layers_minus1 = {};
  bool sps_temporal_id_nesting_flag = {};
  H265ProfileTierLevel profile_tier_level = {};
  uint32_t sps_seq_parameter_set_id = {};
  uint32_t chroma_format_idc = {};
  bool separate_colour_plane_flag = {};
  uint32_t pic_width_in_luma_samples = {};
  uint32_t pic_height_in_luma_samples = {};

  bool conformance_window_flag = {};
  uint32_t conf_win_left_offset = {};
  uint32_t conf_win_right_offset = {};
  uint32_t conf_win_top_offset = {};
  uint32_t conf_win_bottom_offset = {};

  uint32_t bit_depth_luma_minus8 = {};
  uint32_t bit_depth_chroma_minus8 = {};
  uint32_t log2_max_pic_order_cnt_lsb_minus4 = {};
  bool sps_sub_layer_ordering_info_present_flag = {};
  uint32_t sps_max_dec_pic_buffering_minus1[kMaxSubLayers] = {};
  uint32_t sps_max_num_reorder_pics[kMaxSubLayers] = {};
  uint32_t sps_max_latency_increase_plus1[kMaxSubLayers] = {};
  uint32_t log2_min_luma_coding_block_size_minus3 = {};
  uint32_t log2_diff_max_min_luma_coding_block_size = {};
  uint32_t log2_min_luma_transform_block_size_minus2 = {};
  uint32_t log2_diff_max_min_luma_transform_block_size = {};
  uint32_t max_transform_hierarchy_depth_inter = {};
  uint32_t max_transform_hierarchy_depth_intra = {};

  bool pcm_enabled_flag = {};
  uint8_t pcm_sample_bit_depth_luma_minus1 = {};
  uint8_t pcm_sample_bit_depth_chroma_minus1 = {};
  uint32_t log2_min_pcm_luma_coding_block_size_minus3 = {};
  uint32_t log2_diff_max_min_pcm_luma_coding_block_size = {};
  bool pcm_loop_filter_disabled_flag = {};

  uint32_t num_short_term_ref_pic_sets = {};
  H265StRefPicSet st_ref_pic_set[kMaxShortTermRefPicSets] = {};

  bool sps_temporal_mvp_enabled_flag = {};
  bool strong_intra_smoothing_enabled_flag = {};
  Maybe<H265VUIParameters> vui_parameters;

  // Calculated fields
  uint32_t subWidthC = {};       // From Table 6-1.
  uint32_t subHeightC = {};      // From Table 6-1.
  CheckedUint32 mDisplayWidth;   // Per (E-68) + (E-69)
  CheckedUint32 mDisplayHeight;  // Per (E-70) + (E-71)
  uint32_t maxDpbSize = {};

  // Often used information
  uint32_t BitDepthLuma() const { return bit_depth_luma_minus8 + 8; }
  uint32_t BitDepthChroma() const { return bit_depth_chroma_minus8 + 8; }
  gfx::IntSize GetImageSize() const;
  gfx::IntSize GetDisplaySize() const;
  gfx::ColorDepth ColorDepth() const;
  gfx::YUVColorSpace ColorSpace() const;
  bool IsFullColorRange() const;
  uint8_t ColorPrimaries() const;
  uint8_t TransferFunction() const;
};

// ISO/IEC 14496-15 : hvcC.
struct HVCCConfig final {
 public:
  static Result<HVCCConfig, nsresult> Parse(
      const mozilla::MediaRawData* aSample);
  static Result<HVCCConfig, nsresult> Parse(
      const mozilla::MediaByteBuffer* aExtraData);

  uint8_t NALUSize() const { return lengthSizeMinusOne + 1; }
  uint32_t NumSPS() const;
  bool HasSPS() const;

  // Returns the first available NALU of the specified type, or nothing if no
  // such NALU is found.
  Maybe<H265NALU> GetFirstAvaiableNALU(H265NALU::NAL_TYPES aType) const;

  uint8_t configurationVersion;
  uint8_t general_profile_space;
  bool general_tier_flag;
  uint8_t general_profile_idc;
  uint32_t general_profile_compatibility_flags;
  uint64_t general_constraint_indicator_flags;
  uint8_t general_level_idc;
  uint16_t min_spatial_segmentation_idc;
  uint8_t parallelismType;
  uint8_t chroma_format_idc;
  uint8_t bit_depth_luma_minus8;
  uint8_t bit_depth_chroma_minus8;
  uint16_t avgFrameRate;
  uint8_t constantFrameRate;
  uint8_t numTemporalLayers;
  bool temporalIdNested;
  uint8_t lengthSizeMinusOne;

  nsTArray<H265NALU> mNALUs;

  // Keep the orginal buffer alive in order to let H265NALU always access to
  // valid data if there is any NALU.
  RefPtr<const MediaByteBuffer> mByteBuffer;

 private:
  HVCCConfig() = default;
};

class SPSIterator final {
 public:
  explicit SPSIterator(const HVCCConfig& aConfig)
      : mCurrentIdx(0), mConfig(aConfig) {
    FindSPS();
  }

  SPSIterator& operator++() {
    mCurrentIdx++;
    FindSPS();
    return *this;
  }

  explicit operator bool() const { return IsValid(); }

  const H265NALU* operator*() const {
    if (!IsValid()) {
      return nullptr;
    }
    if (!mConfig.mNALUs[mCurrentIdx].IsSPS()) {
      return nullptr;
    }
    return &mConfig.mNALUs[mCurrentIdx];
  }

 private:
  void FindSPS() {
    Maybe<size_t> spsIdx;
    for (auto idx = mCurrentIdx; idx < mConfig.mNALUs.Length(); idx++) {
      if (mConfig.mNALUs[idx].IsSPS()) {
        spsIdx = Some(idx);
        break;
      }
    }
    if (spsIdx) {
      mCurrentIdx = *spsIdx;
    }
  }

  bool IsValid() const { return mCurrentIdx < mConfig.mNALUs.Length(); }

  size_t mCurrentIdx;
  const HVCCConfig& mConfig;
};

class H265 final {
 public:
  static Result<H265SPS, nsresult> DecodeSPSFromHVCCExtraData(
      const mozilla::MediaByteBuffer* aExtraData);
  static Result<H265SPS, nsresult> DecodeSPSFromSPSNALU(
      const H265NALU& aSPSNALU);

  // Extract SPS and PPS NALs from aSample by looking into each NALs.
  static already_AddRefed<mozilla::MediaByteBuffer> ExtractHVCCExtraData(
      const mozilla::MediaRawData* aSample);

  // Return true if both extradata are equal.
  static bool CompareExtraData(const mozilla::MediaByteBuffer* aExtraData1,
                               const mozilla::MediaByteBuffer* aExtraData2);

  // Return the value of sps_max_dec_pic_buffering_minus1[0] + 1 from a valid
  // SPS in the extradata, otherwise return 0.
  static uint32_t ComputeMaxRefFrames(
      const mozilla::MediaByteBuffer* aExtraData);

  // Create a dummy extradata, useful to create a decoder and test the
  // capabilities of the decoder.
  static already_AddRefed<mozilla::MediaByteBuffer> CreateFakeExtraData();

  // Create new extradata with the essential information from the given
  // HVCCConfig, excluding its original NALUs. The NALUs will be replaced by the
  // provided SPS, PPS, and VPS.
  static already_AddRefed<mozilla::MediaByteBuffer> CreateNewExtraData(
      const HVCCConfig& aConfig, const Maybe<H265NALU>& aSPS,
      const Maybe<H265NALU>& aPPS, const Maybe<H265NALU>& aVPS);

 private:
  // Return RAW BYTE SEQUENCE PAYLOAD (rbsp) from NAL content.
  static already_AddRefed<mozilla::MediaByteBuffer> DecodeNALUnit(
      const Span<const uint8_t>& aNALU);

  //  Parse the profile level based on the H265 spec, 7.3.3. MUST use a bit
  //  reader which starts from the position of the first bit of the data.
  static Result<Ok, nsresult> ParseProfileTierLevel(
      BitReader& aReader, bool aProfilePresentFlag,
      uint8_t aMaxNumSubLayersMinus1, H265ProfileTierLevel& aProfile);

  //  Parse the short-term reference picture set based on the H265 spec, 7.3.7.
  //  MUST use a bit reader which starts from the position of the first bit of
  //  the data.
  static Result<Ok, nsresult> ParseStRefPicSet(BitReader& aReader,
                                               uint32_t aStRpsIdx,
                                               H265SPS& aSPS);

  //  Parse the VUI parameters based on the H265 spec, E.2.1. MUST use a bit
  //  reader which starts from the position of the first bit of the data.
  static Result<Ok, nsresult> ParseVuiParameters(BitReader& aReader,
                                                 H265SPS& aSPS);

  // Parse and ignore the structure. MUST use a bitreader which starts from the
  // position of the first bit of the data.
  static Result<Ok, nsresult> ParseAndIgnoreScalingListData(BitReader& aReader);
  static Result<Ok, nsresult> ParseAndIgnoreHrdParameters(
      BitReader& aReader, bool aCommonInfPresentFlag,
      int aMaxNumSubLayersMinus1);
  static Result<Ok, nsresult> ParseAndIgnoreSubLayerHrdParameters(
      BitReader& aReader, int aCpbCnt, bool aSubPicHrdParamsPresentFlag);
};

}  // namespace mozilla

#endif  // DOM_MEDIA_PLATFORMS_AGNOSTIC_BYTESTREAMS_H265_H_

Messung V0.5
C=84 H=93 G=88

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.