History

avcodec/hevc/ps: Add basic HEVC_SCALABILITY_AUXILIARY support

Only implementing what's needed for HEVC with alpha.

Zhao Zhili committed 1 year ago

Commit d3670161 parent d3220ed3 files · +95 −36Browse files

Unified · Split

3 files
  1. libavcodec/hevc/hevc.h +5 −0
  2. libavcodec/hevc/ps.c +89 −36
  3. libavcodec/hevc/ps.h +1 −0
libavcodec/hevc/hevc.h+5−0
@@ -170,4 +170,9 @@ enum HEVCScalabilityMask { · 169 unmodified lines
170 HEVC_SCALABILITY_MASK_MAX = 0xFFFF,170 HEVC_SCALABILITY_MASK_MAX = 0xFFFF,
171};171};
172 172
173enum HEVCAuxId {
174 HEVC_AUX_ALPHA = 1,
175 HEVC_AUX_DEPTH = 2,
176};
177
173#endif /* AVCODEC_HEVC_HEVC_H */178#endif /* AVCODEC_HEVC_HEVC_H */
libavcodec/hevc/ps.c+89−36
@@ -460,14 +460,17 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 459 unmodified lines
460 uint64_t layer1_id_included)460 uint64_t layer1_id_included)
461{461{
462 PTL ptl_dummy;462 PTL ptl_dummy;
463 uint8_t max_sub_layers[HEVC_MAX_LAYERS];463 uint8_t max_sub_layers[HEVC_MAX_LAYERS] = {1, 1};
464 uint8_t dimension_id_len[16] = {0};
465 uint8_t dimension_id[16] = {0};
466 unsigned n;
464 467
465 int splitting_flag, dimension_id_len, view_id_len, num_add_olss, num_scalability_types,468 int splitting_flag, view_id_len, num_add_olss, num_scalability_types,
466 default_output_layer_idc, direct_dep_type_len, direct_dep_type,469 default_output_layer_idc, direct_dep_type_len, direct_dep_type,
467 sub_layers_max_present, sub_layer_flag_info_present_flag, nb_ptl;470 sub_layers_max_present, sub_layer_flag_info_present_flag, nb_ptl;
468 unsigned non_vui_extension_length;471 unsigned non_vui_extension_length;
469 472
470 if (vps->vps_max_layers == 1 || vps->vps_num_layer_sets == 1) {473 if (vps->vps_max_layers == 1) {
471 av_log(avctx, AV_LOG_VERBOSE, "Ignoring VPS extensions with a single layer\n");474 av_log(avctx, AV_LOG_VERBOSE, "Ignoring VPS extensions with a single layer\n");
472 return 0;475 return 0;
473 }476 }
@@ -520,6 +523,7 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 46 unmodified lines
520 */523 */
521 vps->nb_layers = 2;524 vps->nb_layers = 2;
522 525
526 /* vps_base_layer_internal_flag is true has been checked before */
523 if (parse_ptl(gb, avctx, 0, &ptl_dummy, vps->vps_max_sub_layers) < 0)527 if (parse_ptl(gb, avctx, 0, &ptl_dummy, vps->vps_max_sub_layers) < 0)
524 return AVERROR_INVALIDDATA;528 return AVERROR_INVALIDDATA;
525 529
@@ -529,20 +533,25 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 3 unmodified lines
529 if (!num_scalability_types) {533 if (!num_scalability_types) {
530 av_log(avctx, AV_LOG_ERROR, "Missing scalability mask\n");534 av_log(avctx, AV_LOG_ERROR, "Missing scalability mask\n");
531 return AVERROR_INVALIDDATA;535 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 }536 }
537 537
538 if (!(vps->scalability_mask_flag & HEVC_SCALABILITY_MULTIVIEW)) {538 if (!(vps->scalability_mask_flag &
539 (HEVC_SCALABILITY_MULTIVIEW | HEVC_SCALABILITY_AUXILIARY))) {
539 av_log(avctx, AV_LOG_ERROR, "Scalability type %d not supported\n",540 av_log(avctx, AV_LOG_ERROR, "Scalability type %d not supported\n",
540 15 - ff_ctz(vps->scalability_mask_flag));541 15 - ff_ctz(vps->scalability_mask_flag));
541 return AVERROR_PATCHWELCOME;542 return AVERROR_PATCHWELCOME;
542 }543 }
544 // x265 specify MULTIVIEW when the stream really is alpha video only.
545 if (num_scalability_types > 1)
546 av_log(avctx, AV_LOG_WARNING, "Multiple scalability types presented\n");
543 547
544 if (!splitting_flag)548 n = 0;
545 dimension_id_len = get_bits(gb, 3) + 1;549 for (int i = 0; i < num_scalability_types - splitting_flag; i++) {
550 dimension_id_len[i] = get_bits(gb, 3) + 1;
551 n += dimension_id_len[i];
552 }
553 if (splitting_flag)
554 dimension_id_len[num_scalability_types - 1] = 5 - n;
546 555
547 if (get_bits1(gb)) { /* vps_nuh_layer_id_present_flag */556 if (get_bits1(gb)) { /* vps_nuh_layer_id_present_flag */
548 int layer_id_in_nuh = get_bits(gb, 6);557 int layer_id_in_nuh = get_bits(gb, 6);
@@ -559,28 +568,57 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 10 unmodified lines
559 }568 }
560 569
561 if (!splitting_flag) {570 if (!splitting_flag) {
562 int view_idx = get_bits(gb, dimension_id_len);571 int index = 0;
563 if (view_idx != 1) {572
564 av_log(avctx, AV_LOG_ERROR, "Unexpected ViewOrderIdx: %d\n", view_idx);573 for (int i = 0; i < num_scalability_types; i++)
574 dimension_id[i] = get_bits(gb, dimension_id_len[i]);
575
576 if (vps->scalability_mask_flag & HEVC_SCALABILITY_MULTIVIEW)
577 index++;
578
579 /* AuxId 1 is alpha, 2 is depth. Only support alpha */
580 if (vps->scalability_mask_flag & HEVC_SCALABILITY_AUXILIARY &&
581 dimension_id[index] != HEVC_AUX_ALPHA) {
582 av_log(avctx, AV_LOG_WARNING,
583 "Unsupported dimension_id %d for HEVC_SCALABILITY_AUXILIARY\n",
584 dimension_id[index]);
565 return AVERROR_PATCHWELCOME;585 return AVERROR_PATCHWELCOME;
566 }586 }
567 }587 }
568 588
569 view_id_len = get_bits(gb, 4);589 view_id_len = get_bits(gb, 4);
570 if (view_id_len)590 if (view_id_len) {
571 for (int i = 0; i < 2 /* NumViews */; i++)591 n = (vps->scalability_mask_flag & HEVC_SCALABILITY_MULTIVIEW) ? 2 : 1;
592 for (int i = 0; i < n; i++)
572 vps->view_id[i] = get_bits(gb, view_id_len);593 vps->view_id[i] = get_bits(gb, view_id_len);
594 }
573 595
574 if (!get_bits1(gb) /* direct_dependency_flag */) {596 /* direct_dependency_flag */
575 av_log(avctx, AV_LOG_WARNING, "Independent output layers not supported\n");597 vps->num_direct_ref_layers[1] = get_bits1(gb);
576 return AVERROR_PATCHWELCOME;598 if (!vps->num_direct_ref_layers[1]) {
599 vps->num_add_layer_sets = get_ue_golomb(gb);
600 if (vps->num_add_layer_sets > 1) {
601 av_log(avctx, AV_LOG_WARNING,
602 "Unsupported num_add_layer_sets: %d\n", vps->num_add_layer_sets);
603 return AVERROR_PATCHWELCOME;
604 }
605
606 if (vps->num_add_layer_sets) {
607 /* highest_layer_idx_plus1 */
608 if (!get_bits1(gb))
609 return AVERROR_PATCHWELCOME;
610 }
577 }611 }
578 vps->num_direct_ref_layers[1] = 1;612 vps->num_output_layer_sets = vps->vps_num_layer_sets + vps->num_add_layer_sets;
613 if (vps->num_output_layer_sets != 2)
614 return AVERROR_INVALIDDATA;
579 615
580 sub_layers_max_present = get_bits1(gb); // vps_sub_layers_max_minus1_present_flag616 sub_layers_max_present = get_bits1(gb); // vps_sub_layers_max_minus1_present_flag
581 for (int i = 0; i < vps->vps_max_layers; i++)617 if (sub_layers_max_present) {
582 max_sub_layers[i] = sub_layers_max_present ? get_bits(gb, 3) + 1 :618 for (int i = 0; i < vps->vps_max_layers; i++)
583 vps->vps_max_sub_layers;619 max_sub_layers[i] = sub_layers_max_present ? get_bits(gb, 3) + 1 :
620 vps->vps_max_sub_layers;
621 }
584 622
585 if (get_bits1(gb) /* max_tid_ref_present_flag */)623 if (get_bits1(gb) /* max_tid_ref_present_flag */)
586 skip_bits(gb, 3); // max_tid_il_ref_pics_plus1624 skip_bits(gb, 3); // max_tid_il_ref_pics_plus1
@@ -613,18 +651,24 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 26 unmodified lines
613 }651 }
614 652
615 /* Consequence of established layer dependencies */653 /* Consequence of established layer dependencies */
616 if (layer1_id_included != ((1 << vps->layer_id_in_nuh[0]) |654 if (layer1_id_included &&
655 layer1_id_included != ((1 << vps->layer_id_in_nuh[0]) |
617 (1 << vps->layer_id_in_nuh[1]))) {656 (1 << vps->layer_id_in_nuh[1]))) {
618 av_log(avctx, AV_LOG_ERROR, "Dependent layer not included in layer ID?\n");657 av_log(avctx, AV_LOG_ERROR,
619 return AVERROR_PATCHWELCOME;658 "Dependent layer not included in layer ID?\n");
659 return AVERROR_PATCHWELCOME;
620 }660 }
661 if (!layer1_id_included)
662 vps->ols[1] = 2;
663 else
664 vps->ols[1] = 3;
621 665
622 vps->num_output_layer_sets = 2;666 if (vps->vps_num_layer_sets == 1 || default_output_layer_idc == 2)
623 vps->ols[1] = 3;667 skip_bits1(gb);
624 668
625 for (int j = 0; j < av_popcount64(vps->ols[1]); j++) {669 for (int j = 0; j < av_popcount64(vps->ols[1]); j++) {
626 int ptl_idx = get_bits(gb, av_ceil_log2(nb_ptl));670 int ptl_idx = get_bits(gb, av_ceil_log2(nb_ptl));
627 if (ptl_idx < 1 || ptl_idx >= nb_ptl) {671 if (ptl_idx >= nb_ptl) {
628 av_log(avctx, AV_LOG_ERROR, "Invalid PTL index: %d\n", ptl_idx);672 av_log(avctx, AV_LOG_ERROR, "Invalid PTL index: %d\n", ptl_idx);
629 return AVERROR_INVALIDDATA;673 return AVERROR_INVALIDDATA;
630 }674 }
@@ -667,6 +711,8 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 36 unmodified lines
667 711
668 vps->max_one_active_ref_layer = get_bits1(gb);712 vps->max_one_active_ref_layer = get_bits1(gb);
669 vps->poc_lsb_aligned = get_bits1(gb);713 vps->poc_lsb_aligned = get_bits1(gb);
714 if (!vps->num_direct_ref_layers[1])
715 vps->poc_lsb_not_present = get_bits1(gb) << 1;
670 716
671 sub_layer_flag_info_present_flag = get_bits1(gb);717 sub_layer_flag_info_present_flag = get_bits1(gb);
672 for (int j = 0; j < FFMAX(max_sub_layers[0], max_sub_layers[1]); j++) {718 for (int j = 0; j < FFMAX(max_sub_layers[0], max_sub_layers[1]); j++) {
@@ -688,12 +734,14 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 15 unmodified lines
688 return AVERROR_INVALIDDATA;734 return AVERROR_INVALIDDATA;
689 }735 }
690 736
691 skip_bits1(gb); /* direct_depenency_all_layers_flag */737 /* direct_depenency_all_layers_flag */
692 direct_dep_type = get_bits_long(gb, direct_dep_type_len);738 if (get_bits1(gb)) {
693 if (direct_dep_type > HEVC_DEP_TYPE_BOTH) {739 direct_dep_type = get_bits_long(gb, direct_dep_type_len);
694 av_log(avctx, AV_LOG_WARNING, "Unsupported direct_dep_type: %d\n",740 if (direct_dep_type > HEVC_DEP_TYPE_BOTH) {
695 direct_dep_type);741 av_log(avctx, AV_LOG_WARNING, "Unsupported direct_dep_type: %d\n",
696 return AVERROR_PATCHWELCOME;742 direct_dep_type);
743 return AVERROR_PATCHWELCOME;
744 }
697 }745 }
698 746
699 non_vui_extension_length = get_ue_golomb(gb);747 non_vui_extension_length = get_ue_golomb(gb);
@@ -718,6 +766,7 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, · 18 unmodified lines
718 ptrdiff_t nal_size = gb->buffer_end - gb->buffer;766 ptrdiff_t nal_size = gb->buffer_end - gb->buffer;
719 int ret = AVERROR_INVALIDDATA;767 int ret = AVERROR_INVALIDDATA;
720 uint64_t layer1_id_included = 0;768 uint64_t layer1_id_included = 0;
769 unsigned vps_base_layer_internal_flag, vps_base_layer_available_flag;
721 HEVCVPS *vps;770 HEVCVPS *vps;
722 771
723 if (ps->vps_list[vps_id]) {772 if (ps->vps_list[vps_id]) {
@@ -741,8 +790,12 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, · 17 unmodified lines
741 }790 }
742 vps->vps_id = vps_id;791 vps->vps_id = vps_id;
743 792
744 if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits793 vps_base_layer_internal_flag = get_bits1(gb);
745 av_log(avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n");794 vps_base_layer_available_flag = get_bits1(gb);
795 if (!vps_base_layer_internal_flag || !vps_base_layer_available_flag) {
796 av_log(avctx, AV_LOG_ERROR,
797 "vps_base_layer_internal_flag or vps_base_layer_available_flag not set\n");
798 ret = AVERROR_PATCHWELCOME;
746 goto err;799 goto err;
747 }800 }
748 801
libavcodec/hevc/ps.h+1−0
@@ -237,6 +237,7 @@ typedef struct HEVCVPS { · 236 unmodified lines
237 237
238 // NumDirectRefLayers[layer_idx]238 // NumDirectRefLayers[layer_idx]
239 uint8_t num_direct_ref_layers[HEVC_VPS_MAX_LAYERS];239 uint8_t num_direct_ref_layers[HEVC_VPS_MAX_LAYERS];
240 uint8_t num_add_layer_sets;
240 241
241 RepFormat rep_format;242 RepFormat rep_format;
242 243

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t