Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 1de86c35 authored by Simon Chan's avatar Simon Chan
Browse files

fix(scrcpy): fix decoding h265 header

fixes #732
parent cecb3ce2
Loading
Loading
Loading
Loading
+197 −0
Original line number Diff line number Diff line
@@ -357,5 +357,202 @@ describe("h265", () => {
                sps_extension_data_flag: undefined,
            } satisfies ReturnType<typeof h265ParseSequenceParameterSet>);
        });

        it("issue #732", () => {
            const buffer = new Uint8Array([
                66, 1, 3, 1, 96, 0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 150, 0,
                0, 160, 2, 28, 128, 9, 33, 99, 107, 92, 146, 41, 187, 226, 170,
                151, 43, 182, 64,
            ]);

            const sps = h265ParseSequenceParameterSet(buffer);

            assert.deepStrictEqual(sps, {
                sps_video_parameter_set_id: 4,
                sps_max_sub_layers_minus1: 1,
                sps_temporal_id_nesting_flag: false,
                profileTierLevel: {
                    generalProfileTier: {
                        profile_space: 0,
                        tier_flag: false,
                        profile_idc: 1,
                        profileCompatibilitySet: new Uint8Array([3, 1, 96, 0]),
                        profile_compatibility_flag: [
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            true,
                            true,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            true,
                            false,
                            true,
                            true,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                        ],
                        constraintSet: new Uint8Array([0, 0, 0, 0, 0, 0]),
                        progressive_source_flag: false,
                        interlaced_source_flag: false,
                        non_packed_constraint_flag: false,
                        frame_only_constraint_flag: false,
                        max_12bit_constraint_flag: false,
                        max_10bit_constraint_flag: false,
                        max_8bit_constraint_flag: false,
                        max_422chroma_constraint_flag: false,
                        max_420chroma_constraint_flag: false,
                        max_monochrome_constraint_flag: false,
                        intra_constraint_flag: false,
                        one_picture_only_constraint_flag: false,
                        lower_bit_rate_constraint_flag: false,
                        max_14bit_constraint_flag: undefined,
                        inbld_flag: false,
                    },
                    general_level_idc: 0,
                    sub_layer_profile_present_flag: [false],
                    sub_layer_level_present_flag: [false],
                    subLayerProfileTier: [],
                    sub_layer_level_idc: [],
                },
                sps_seq_parameter_set_id: 81923,
                chroma_format_idc: 6,
                separate_colour_plane_flag: undefined,
                pic_width_in_luma_samples: 3,
                pic_height_in_luma_samples: 583,
                conformance_window_flag: false,
                conf_win_left_offset: undefined,
                conf_win_right_offset: undefined,
                conf_win_top_offset: undefined,
                conf_win_bottom_offset: undefined,
                bit_depth_luma_minus8: 0,
                bit_depth_chroma_minus8: 2,
                log2_max_pic_order_cnt_lsb_minus4: 12,
                sps_sub_layer_ordering_info_present_flag: true,
                sps_max_dec_pic_buffering_minus1: [1, 1],
                sps_max_num_reorder_pics: [0, 0],
                sps_max_latency_increase_plus1: [0, 0],
                log2_min_luma_coding_block_size_minus3: 0,
                log2_diff_max_min_luma_coding_block_size: 3,
                log2_min_luma_transform_block_size_minus2: 0,
                log2_diff_max_min_luma_transform_block_size: 3,
                max_transform_hierarchy_depth_inter: 1,
                max_transform_hierarchy_depth_intra: 0,
                scaling_list_enabled_flag: false,
                sps_scaling_list_data_present_flag: undefined,
                scalingListData: undefined,
                amp_enabled_flag: false,
                sample_adaptive_offset_enabled_flag: true,
                pcm_enabled_flag: true,
                pcm_sample_bit_depth_luma_minus1: 7,
                pcm_sample_bit_depth_chroma_minus1: 7,
                log2_min_pcm_luma_coding_block_size_minus3: 0,
                log2_diff_max_min_pcm_luma_coding_block_size: 0,
                pcm_loop_filter_disabled_flag: false,
                num_short_term_ref_pic_sets: 4,
                shortTermRefPicSets: [
                    {
                        stRpsIdx: 0,
                        num_short_term_ref_pic_sets: 4,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 1,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [1],
                        used_by_curr_pic_s0_flag: [true],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                    {
                        stRpsIdx: 1,
                        num_short_term_ref_pic_sets: 4,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 1,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [0],
                        used_by_curr_pic_s0_flag: [true],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                    {
                        stRpsIdx: 2,
                        num_short_term_ref_pic_sets: 4,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 1,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [2],
                        used_by_curr_pic_s0_flag: [true],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                    {
                        stRpsIdx: 3,
                        num_short_term_ref_pic_sets: 4,
                        inter_ref_pic_set_prediction_flag: false,
                        delta_idx_minus1: 0,
                        delta_rps_sign: false,
                        abs_delta_rps_minus1: 0,
                        used_by_curr_pic_flag: [],
                        use_delta_flag: [],
                        num_negative_pics: 0,
                        num_positive_pics: 0,
                        delta_poc_s0_minus1: [],
                        used_by_curr_pic_s0_flag: [],
                        delta_poc_s1_minus1: [],
                        used_by_curr_pic_s1_flag: [],
                    },
                ],
                long_term_ref_pics_present_flag: false,
                num_long_term_ref_pics_sps: undefined,
                lt_ref_pic_poc_lsb_sps: undefined,
                used_by_curr_pic_lt_sps_flag: undefined,
                sps_temporal_mvp_enabled_flag: true,
                strong_intra_smoothing_enabled_flag: true,
                vui_parameters_present_flag: false,
                vuiParameters: undefined,
                sps_extension_present_flag: false,
                sps_range_extension_flag: undefined,
                sps_multilayer_extension_flag: undefined,
                sps_3d_extension_flag: undefined,
                sps_scc_extension_flag: undefined,
                sps_extension_4bits: undefined,
                spsMultilayerExtension: undefined,
                sps3dExtension: undefined,
                sps_extension_data_flag: undefined,
            } satisfies ReturnType<typeof h265ParseSequenceParameterSet>);
        });
    });
});
+31 −5
Original line number Diff line number Diff line
@@ -330,8 +330,10 @@ export function h265ParseSequenceParameterSet(nalu: Uint8Array) {
    if (pcm_enabled_flag) {
        pcm_sample_bit_depth_luma_minus1 = reader.read(4);
        pcm_sample_bit_depth_chroma_minus1 = reader.read(4);
        log2_min_pcm_luma_coding_block_size_minus3 = reader.read(4);
        log2_diff_max_min_pcm_luma_coding_block_size = reader.read(4);
        log2_min_pcm_luma_coding_block_size_minus3 =
            reader.decodeExponentialGolombNumber();
        log2_diff_max_min_pcm_luma_coding_block_size =
            reader.decodeExponentialGolombNumber();
        pcm_loop_filter_disabled_flag = !!reader.next();
    }

@@ -894,6 +896,30 @@ export function h265ParseShortTermReferencePictureSet(
    };
}

export const H265AspectRatioIndicator = {
    Unspecified: 0,
    Square: 1,
    _12_11: 2,
    _10_11: 3,
    _16_11: 4,
    _40_33: 5,
    _24_11: 6,
    _20_11: 7,
    _32_11: 8,
    _80_33: 9,
    _18_11: 10,
    _15_11: 11,
    _64_33: 12,
    _160_99: 13,
    _4_3: 15,
    _3_2: 16,
    _2_1: 17,
    Extended: 255,
} as const;

export type H265AspectRatioIndicator =
    (typeof H265AspectRatioIndicator)[keyof typeof H265AspectRatioIndicator];

/**
 * E.2.1 VUI parameters syntax
 */
@@ -902,12 +928,12 @@ export function h265ParseVuiParameters(
    sps_max_sub_layers_minus1: number,
) {
    const aspect_ratio_info_present_flag = !!reader.next();
    let aspect_ratio_idc: number | undefined;
    let aspect_ratio_idc: H265AspectRatioIndicator | undefined;
    let sar_width: number | undefined;
    let sar_height: number | undefined;
    if (aspect_ratio_info_present_flag) {
        aspect_ratio_idc = reader.read(8);
        if (aspect_ratio_idc === 255) {
        aspect_ratio_idc = reader.read(8) as H265AspectRatioIndicator;
        if (aspect_ratio_idc === H265AspectRatioIndicator.Extended) {
            sar_width = reader.read(16);
            sar_height = reader.read(16);
        }