Remove a for loop and make it easy to extend to support other types of scalability. Move ScalabilityMask to hevc header file so it can be used in hevc decoder.
Showing the changes to libavcodec (3 of 3 files). Show all
Unified · Split
| @@ -162,5 +162,12 @@ enum { · 161 unmodified lines | ||
| 162 | 162 | HEVC_MAX_PALETTE_PREDICTOR_SIZE = 128, |
| 163 | 163 | }; |
| 164 | 164 | |
| 165 | +enum HEVCScalabilityMask { | |
| 166 | + HEVC_SCALABILITY_DEPTH = 1 << (15 - 0), | |
| 167 | + HEVC_SCALABILITY_MULTIVIEW = 1 << (15 - 1), | |
| 168 | + HEVC_SCALABILITY_SPATIAL = 1 << (15 - 2), | |
| 169 | + HEVC_SCALABILITY_AUXILIARY = 1 << (15 - 3), | |
| 170 | + HEVC_SCALABILITY_MASK_MAX = 0xFFFF, | |
| 171 | +}; | |
| 165 | 172 | |
| 166 | 173 | #endif /* AVCODEC_HEVC_HEVC_H */ |
| @@ -450,14 +450,6 @@ static void hevc_vps_free(AVRefStructOpaque opaque, void *obj) · 449 unmodified lines | ||
| 450 | 450 | av_freep(&vps->data); |
| 451 | 451 | } |
| 452 | 452 | |
| 453 | −enum ScalabilityMask { | |
| 454 | − HEVC_SCALABILITY_DEPTH = 0, | |
| 455 | − HEVC_SCALABILITY_MULTIVIEW = 1, | |
| 456 | − HEVC_SCALABILITY_SPATIAL = 2, | |
| 457 | − HEVC_SCALABILITY_AUXILIARY = 3, | |
| 458 | − HEVC_SCALABILITY_MASK_MAX = 15, | |
| 459 | −}; | |
| 460 | − | |
| 461 | 453 | enum DependencyType { |
| 462 | 454 | HEVC_DEP_TYPE_SAMPLE = 0, |
| 463 | 455 | HEVC_DEP_TYPE_MV = 1, |
| @@ -532,17 +524,22 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 68 unmodified lines | ||
| 532 | 524 | return AVERROR_INVALIDDATA; |
| 533 | 525 | |
| 534 | 526 | splitting_flag = get_bits1(gb); |
| 535 | − num_scalability_types = 0; | |
| 536 | − for (int i = 0; i <= HEVC_SCALABILITY_MASK_MAX; i++) { | |
| 537 | − int scalability_mask_flag = get_bits1(gb); | |
| 538 | − if (scalability_mask_flag && (i != HEVC_SCALABILITY_MULTIVIEW)) { | |
| 539 | − av_log(avctx, AV_LOG_ERROR, "Scalability type %d not supported\n", i); | |
| 540 | − return AVERROR_PATCHWELCOME; | |
| 541 | − } | |
| 542 | − num_scalability_types += scalability_mask_flag; | |
| 543 | − } | |
| 544 | − if (num_scalability_types != 1) | |
| 527 | + vps->scalability_mask_flag = get_bits(gb, 16); | |
| 528 | + num_scalability_types = av_popcount(vps->scalability_mask_flag); | |
| 529 | + if (!num_scalability_types) { | |
| 530 | + av_log(avctx, AV_LOG_ERROR, "Missing scalability mask\n"); | |
| 545 | 531 | return AVERROR_INVALIDDATA; |
| 532 | + } else if (num_scalability_types > 1) { | |
| 533 | + av_log(avctx, AV_LOG_ERROR, "Scalability number %d not supported\n", | |
| 534 | + num_scalability_types); | |
| 535 | + return AVERROR_PATCHWELCOME; | |
| 536 | + } | |
| 537 | + | |
| 538 | + if (!(vps->scalability_mask_flag & HEVC_SCALABILITY_MULTIVIEW)) { | |
| 539 | + av_log(avctx, AV_LOG_ERROR, "Scalability type %d not supported\n", | |
| 540 | + 15 - ff_ctz(vps->scalability_mask_flag)); | |
| 541 | + return AVERROR_PATCHWELCOME; | |
| 542 | + } | |
| 546 | 543 | |
| 547 | 544 | if (!splitting_flag) |
| 548 | 545 | dimension_id_len = get_bits(gb, 3) + 1; |
| @@ -205,6 +205,8 @@ typedef struct HEVCVPS { · 204 unmodified lines | ||
| 205 | 205 | */ |
| 206 | 206 | int nb_layers; |
| 207 | 207 | |
| 208 | + uint16_t scalability_mask_flag; | |
| 209 | + | |
| 208 | 210 | // LayerIdxInVps[nuh_layer_id], i.e. a mapping of nuh_layer_id to VPS layer |
| 209 | 211 | // indices. Valid values are between 0 and HEVC_VPS_MAX_LAYERS. Entries for |
| 210 | 212 | // unmapped values of nuh_layer_id are set to -1. |