diff --git a/itu/h265.h b/itu/h265.h index ff576d4..848eedb 100644 --- a/itu/h265.h +++ b/itu/h265.h @@ -412,6 +412,118 @@ static inline uint32_t h265hvcc_get_profile_compatibility(const uint8_t *p) return (p[2] << 24) | (p[3] << 16) | (p[4] << 8) | p[5]; } +static const char *h265_get_range_ext_profile(bool max_12bit, bool max_10bit, bool max_8bit, bool max_422chroma, bool max_420chroma, bool max_monochrome, bool intra, bool one_picture_only, bool lower_bit_rate) +{ + /* ITU-T H.265 (V9) Table A.2 */ + +#define H265_CONSTRAINT_MAX_12BIT 7 +#define H265_CONSTRAINT_MAX_10BIT 6 +#define H265_CONSTRAINT_MAX_8BIT 5 +#define H265_CONSTRAINT_MAX_422CHROMA 4 +#define H265_CONSTRAINT_MAX_420CHROMA 3 +#define H265_CONSTRAINT_MAX_MONOCHROME 2 +#define H265_CONSTRAINT_INTRA 1 +#define H265_CONSTRAINT_ONE_PICTURE_ONLY 0 + +#define H265_PROFILE_16_BIT 0 +#define H265_PROFILE_12_BIT (1 << H265_CONSTRAINT_MAX_12BIT) +#define H265_PROFILE_10_BIT (1 << H265_CONSTRAINT_MAX_12BIT | 1 << H265_CONSTRAINT_MAX_10BIT) +#define H265_PROFILE_8_BIT (1 << H265_CONSTRAINT_MAX_12BIT | 1 << H265_CONSTRAINT_MAX_10BIT | 1 << H265_CONSTRAINT_MAX_8BIT) + +#define H265_PROFILE_INTRA (1 << H265_CONSTRAINT_INTRA) + +#define H265_PROFILE_STILL_PICTURE (H265_PROFILE_INTRA | 1 << H265_CONSTRAINT_ONE_PICTURE_ONLY) + +#define H265_PROFILE_444 0 +#define H265_PROFILE_422 (1 << H265_CONSTRAINT_MAX_422CHROMA) +#define H265_PROFILE_420 (1 << H265_CONSTRAINT_MAX_422CHROMA | 1 << H265_CONSTRAINT_MAX_420CHROMA) + +#define H265_PROFILE_MONOCHROME (H265_PROFILE_420 | 1 << H265_CONSTRAINT_MAX_MONOCHROME) + + uint8_t constraint = (!!max_12bit << H265_CONSTRAINT_MAX_12BIT) | + (!!max_10bit << H265_CONSTRAINT_MAX_10BIT) | + (!!max_8bit << H265_CONSTRAINT_MAX_8BIT) | + (!!max_422chroma << H265_CONSTRAINT_MAX_422CHROMA) | + (!!max_420chroma << H265_CONSTRAINT_MAX_420CHROMA) | + (!!max_monochrome << H265_CONSTRAINT_MAX_MONOCHROME) | + (!!intra << H265_CONSTRAINT_INTRA) | + (!!one_picture_only << H265_CONSTRAINT_ONE_PICTURE_ONLY); + + if (!intra && !lower_bit_rate) + goto unknown; + + switch (constraint) { + case H265_PROFILE_MONOCHROME | H265_PROFILE_8_BIT: + return "Monochrome"; + case H265_PROFILE_MONOCHROME | H265_PROFILE_10_BIT: + return "Monochrome 10"; + case H265_PROFILE_MONOCHROME | H265_PROFILE_12_BIT: + return "Monochrome 12"; + case H265_PROFILE_MONOCHROME | H265_PROFILE_16_BIT: + return "Monochrome 16"; + + case H265_PROFILE_12_BIT | H265_PROFILE_420: + return "Main 12"; + case H265_PROFILE_10_BIT | H265_PROFILE_422: + return "Main 4:2:2 10"; + case H265_PROFILE_12_BIT | H265_PROFILE_422: + return "Main 4:2:2 12"; + + case H265_PROFILE_8_BIT | H265_PROFILE_444: + return "Main 4:4:4"; + case H265_PROFILE_10_BIT | H265_PROFILE_444: + return "Main 4:4:4 10"; + case H265_PROFILE_12_BIT | H265_PROFILE_444: + return "Main 4:4:4 12"; + + case H265_PROFILE_8_BIT | H265_PROFILE_420 | H265_PROFILE_INTRA: + return "Main Intra"; + case H265_PROFILE_10_BIT | H265_PROFILE_420 | H265_PROFILE_INTRA: + return "Main 10 Intra"; + case H265_PROFILE_12_BIT | H265_PROFILE_420 | H265_PROFILE_INTRA: + return "Main 12 Intra"; + + case H265_PROFILE_10_BIT | H265_PROFILE_422 | H265_PROFILE_INTRA: + return "Main 4:2:2 10 Intra"; + case H265_PROFILE_12_BIT | H265_PROFILE_422 | H265_PROFILE_INTRA: + return "Main 4:2:2 12 Intra"; + + case H265_PROFILE_8_BIT | H265_PROFILE_444 | H265_PROFILE_INTRA: + return "Main 4:4:4 Intra"; + case H265_PROFILE_10_BIT | H265_PROFILE_444 | H265_PROFILE_INTRA: + return "Main 4:4:4 10 Intra"; + case H265_PROFILE_12_BIT | H265_PROFILE_444 | H265_PROFILE_INTRA: + return "Main 4:4:4 12 Intra"; + case H265_PROFILE_16_BIT | H265_PROFILE_444 | H265_PROFILE_INTRA: + return "Main 4:4:4 16 Intra"; + + case H265_PROFILE_8_BIT | H265_PROFILE_444 | H265_PROFILE_STILL_PICTURE: + return "Main 4:4:4 Still Picture"; + case H265_PROFILE_16_BIT | H265_PROFILE_444 | H265_PROFILE_STILL_PICTURE: + return "Main 4:4:4 16 Still Picture"; + default: + break; + }; + +unknown: + return "Range ext unknown profile"; +} + +static inline const char *h265_get_profile_txt(uint8_t i_profile) +{ + return i_profile == 0 ? "None" : + i_profile == 1 ? "Main" : + i_profile == 2 ? "Main 10" : + i_profile == 3 ? "Main Still Picture" : + i_profile == 4 ? "Range Extension" : + i_profile == 5 ? "High Throughput" : + i_profile == 6 ? "Multiview Main" : + i_profile == 7 ? "Scalable Main" : + i_profile == 8 ? "3D Main" : + i_profile == 9 ? "Screen Extended" : + i_profile == 10 ? "Scalable Range Extension" : "Reserved"; +} + static inline void h265hvcc_set_constraint_indicator(uint8_t *p, uint64_t val) { p[6] = val >> 40;