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

Showing the changes to libavcodec (3 of 3 files). Show all

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
170170 HEVC_SCALABILITY_MASK_MAX = 0xFFFF,
171171 };
172172
173+enum HEVCAuxId {
174+ HEVC_AUX_ALPHA = 1,
175+ HEVC_AUX_DEPTH = 2,
176+};
177+
173178 #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
460460 uint64_t layer1_id_included)
461461 {
462462 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;
464467
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,
466469 default_output_layer_idc, direct_dep_type_len, direct_dep_type,
467470 sub_layers_max_present, sub_layer_flag_info_present_flag, nb_ptl;
468471 unsigned non_vui_extension_length;
469472
470− if (vps->vps_max_layers == 1 || vps->vps_num_layer_sets == 1) {
473+ if (vps->vps_max_layers == 1) {
471474 av_log(avctx, AV_LOG_VERBOSE, "Ignoring VPS extensions with a single layer\n");
472475 return 0;
473476 }
@@ -520,6 +523,7 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 46 unmodified lines
520523 */
521524 vps->nb_layers = 2;
522525
526+ /* vps_base_layer_internal_flag is true has been checked before */
523527 if (parse_ptl(gb, avctx, 0, &ptl_dummy, vps->vps_max_sub_layers) < 0)
524528 return AVERROR_INVALIDDATA;
525529
@@ -529,20 +533,25 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 3 unmodified lines
529533 if (!num_scalability_types) {
530534 av_log(avctx, AV_LOG_ERROR, "Missing scalability mask\n");
531535 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;
536536 }
537537
538− if (!(vps->scalability_mask_flag & HEVC_SCALABILITY_MULTIVIEW)) {
538+ if (!(vps->scalability_mask_flag &
539+ (HEVC_SCALABILITY_MULTIVIEW | HEVC_SCALABILITY_AUXILIARY))) {
539540 av_log(avctx, AV_LOG_ERROR, "Scalability type %d not supported\n",
540541 15 - ff_ctz(vps->scalability_mask_flag));
541542 return AVERROR_PATCHWELCOME;
542543 }
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");
543547
544− if (!splitting_flag)
545− dimension_id_len = get_bits(gb, 3) + 1;
548+ n = 0;
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;
546555
547556 if (get_bits1(gb)) { /* vps_nuh_layer_id_present_flag */
548557 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
559568 }
560569
561570 if (!splitting_flag) {
562− int view_idx = get_bits(gb, dimension_id_len);
563− if (view_idx != 1) {
564− av_log(avctx, AV_LOG_ERROR, "Unexpected ViewOrderIdx: %d\n", view_idx);
571+ int index = 0;
572+
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]);
565585 return AVERROR_PATCHWELCOME;
566586 }
567587 }
568588
569589 view_id_len = get_bits(gb, 4);
570− if (view_id_len)
571− for (int i = 0; i < 2 /* NumViews */; i++)
590+ if (view_id_len) {
591+ n = (vps->scalability_mask_flag & HEVC_SCALABILITY_MULTIVIEW) ? 2 : 1;
592+ for (int i = 0; i < n; i++)
572593 vps->view_id[i] = get_bits(gb, view_id_len);
594+ }
573595
574− if (!get_bits1(gb) /* direct_dependency_flag */) {
575− av_log(avctx, AV_LOG_WARNING, "Independent output layers not supported\n");
576− return AVERROR_PATCHWELCOME;
596+ /* direct_dependency_flag */
597+ vps->num_direct_ref_layers[1] = get_bits1(gb);
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+ }
577611 }
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;
579615
580616 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++)
582− max_sub_layers[i] = sub_layers_max_present ? get_bits(gb, 3) + 1 :
583− vps->vps_max_sub_layers;
617+ if (sub_layers_max_present) {
618+ for (int i = 0; i < vps->vps_max_layers; i++)
619+ max_sub_layers[i] = sub_layers_max_present ? get_bits(gb, 3) + 1 :
620+ vps->vps_max_sub_layers;
621+ }
584622
585623 if (get_bits1(gb) /* max_tid_ref_present_flag */)
586624 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
613651 }
614652
615653 /* 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]) |
617656 (1 << vps->layer_id_in_nuh[1]))) {
618− av_log(avctx, AV_LOG_ERROR, "Dependent layer not included in layer ID?\n");
619− return AVERROR_PATCHWELCOME;
657+ av_log(avctx, AV_LOG_ERROR,
658+ "Dependent layer not included in layer ID?\n");
659+ return AVERROR_PATCHWELCOME;
620660 }
661+ if (!layer1_id_included)
662+ vps->ols[1] = 2;
663+ else
664+ vps->ols[1] = 3;
621665
622− vps->num_output_layer_sets = 2;
623− vps->ols[1] = 3;
666+ if (vps->vps_num_layer_sets == 1 || default_output_layer_idc == 2)
667+ skip_bits1(gb);
624668
625669 for (int j = 0; j < av_popcount64(vps->ols[1]); j++) {
626670 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) {
628672 av_log(avctx, AV_LOG_ERROR, "Invalid PTL index: %d\n", ptl_idx);
629673 return AVERROR_INVALIDDATA;
630674 }
@@ -667,6 +711,8 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps · 36 unmodified lines
667711
668712 vps->max_one_active_ref_layer = get_bits1(gb);
669713 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;
670716
671717 sub_layer_flag_info_present_flag = get_bits1(gb);
672718 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
688734 return AVERROR_INVALIDDATA;
689735 }
690736
691− skip_bits1(gb); /* direct_depenency_all_layers_flag */
692− direct_dep_type = get_bits_long(gb, direct_dep_type_len);
693− if (direct_dep_type > HEVC_DEP_TYPE_BOTH) {
694− av_log(avctx, AV_LOG_WARNING, "Unsupported direct_dep_type: %d\n",
695− direct_dep_type);
696− return AVERROR_PATCHWELCOME;
737+ /* direct_depenency_all_layers_flag */
738+ if (get_bits1(gb)) {
739+ direct_dep_type = get_bits_long(gb, direct_dep_type_len);
740+ if (direct_dep_type > HEVC_DEP_TYPE_BOTH) {
741+ av_log(avctx, AV_LOG_WARNING, "Unsupported direct_dep_type: %d\n",
742+ direct_dep_type);
743+ return AVERROR_PATCHWELCOME;
744+ }
697745 }
698746
699747 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
718766 ptrdiff_t nal_size = gb->buffer_end - gb->buffer;
719767 int ret = AVERROR_INVALIDDATA;
720768 uint64_t layer1_id_included = 0;
769+ unsigned vps_base_layer_internal_flag, vps_base_layer_available_flag;
721770 HEVCVPS *vps;
722771
723772 if (ps->vps_list[vps_id]) {
@@ -741,8 +790,12 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, · 17 unmodified lines
741790 }
742791 vps->vps_id = vps_id;
743792
744− if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits
745− av_log(avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n");
793+ vps_base_layer_internal_flag = get_bits1(gb);
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;
746799 goto err;
747800 }
748801
libavcodec/hevc/ps.h+1−0
@@ -237,6 +237,7 @@ typedef struct HEVCVPS { · 236 unmodified lines
237237
238238 // NumDirectRefLayers[layer_idx]
239239 uint8_t num_direct_ref_layers[HEVC_VPS_MAX_LAYERS];
240+ uint8_t num_add_layer_sets;
240241
241242 RepFormat rep_format;
242243

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