diff options
author | Jeffrey Kardatzke <jkardatzke@google.com> | 2022-05-24 14:49:13 -0700 |
---|---|---|
committer | Marcin Wojtas <mwojtas@google.com> | 2023-01-29 19:56:49 +0000 |
commit | b8b5f78b7df108b0af01ccdcae33c5e9040f6a51 (patch) | |
tree | 296cfe8ea514cd720362351226c957f16a1a1d25 | |
parent | 8a36efe56644e7263f9bc63955cd4d40c9d878c0 (diff) | |
download | v4l2_codec2-b8b5f78b7df108b0af01ccdcae33c5e9040f6a51.tar.gz |
v4l2_codec2: Add support for HEVC to the video decoder tests.
This adds support for the HEVC codec to the e2e video decoder tests.
Bug: 215043150
Bug: 183217901
Test: c2_e2e_test APK works for HEVC on guybrush w/ codecs added and
corresponding crosvm/libvda changes
Change-Id: I7b3351cede200f9be406960e2d6507d58acac55c
(cherry picked from commit e43cc425ce63d39c8ba9bdb6bb60fd08c5a3b02a)
-rw-r--r-- | tests/c2_e2e_test/jni/common.cpp | 3 | ||||
-rw-r--r-- | tests/c2_e2e_test/jni/common.h | 6 | ||||
-rw-r--r-- | tests/c2_e2e_test/jni/encoded_data_helper.cpp | 53 | ||||
-rw-r--r-- | tests/c2_e2e_test/jni/encoded_data_helper.h | 14 | ||||
-rw-r--r-- | tests/c2_e2e_test/jni/mediacodec_decoder.cpp | 4 | ||||
-rw-r--r-- | tests/c2_e2e_test/jni/video_decoder_e2e_test.cpp | 4 |
6 files changed, 59 insertions, 25 deletions
diff --git a/tests/c2_e2e_test/jni/common.cpp b/tests/c2_e2e_test/jni/common.cpp index 50f4cdf..673e36c 100644 --- a/tests/c2_e2e_test/jni/common.cpp +++ b/tests/c2_e2e_test/jni/common.cpp @@ -257,6 +257,7 @@ VideoCodecType VideoCodecProfileToType(VideoCodecProfile profile) { if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) return VideoCodecType::H264; if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) return VideoCodecType::VP8; if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) return VideoCodecType::VP9; + if (profile >= HEVCPROFILE_MIN && profile <= HEVCPROFILE_MAX) return VideoCodecType::HEVC; return VideoCodecType::UNKNOWN; } @@ -286,6 +287,8 @@ const char* GetMimeType(VideoCodecType type) { return "video/x-vnd.on2.vp8"; case VideoCodecType::VP9: return "video/x-vnd.on2.vp9"; + case VideoCodecType::HEVC: + return "video/hevc"; default: // unknown type return nullptr; } diff --git a/tests/c2_e2e_test/jni/common.h b/tests/c2_e2e_test/jni/common.h index ea8d212..b28fd3a 100644 --- a/tests/c2_e2e_test/jni/common.h +++ b/tests/c2_e2e_test/jni/common.h @@ -41,6 +41,11 @@ enum VideoCodecProfile { VP9PROFILE_PROFILE2 = 14, VP9PROFILE_PROFILE3 = 15, VP9PROFILE_MAX = VP9PROFILE_PROFILE3, + HEVCPROFILE_MIN = 16, + HEVCPROFILE_MAIN = HEVCPROFILE_MIN, + HEVCPROFILE_MAIN10 = 17, + HEVCPROFILE_MAIN_STILL_PICTURE = 18, + HEVCPROFILE_MAX = HEVCPROFILE_MAIN_STILL_PICTURE, }; // The enum class of video codec type. @@ -49,6 +54,7 @@ enum class VideoCodecType { H264, VP8, VP9, + HEVC, }; // Structure to store resolution. diff --git a/tests/c2_e2e_test/jni/encoded_data_helper.cpp b/tests/c2_e2e_test/jni/encoded_data_helper.cpp index 0ced022..54e4382 100644 --- a/tests/c2_e2e_test/jni/encoded_data_helper.cpp +++ b/tests/c2_e2e_test/jni/encoded_data_helper.cpp @@ -43,12 +43,12 @@ bool GetPosForNextNALUHeader(const std::string& data, size_t* next_header_pos) { } if (pos + 3 >= data.size()) return false; // No more NALUs - // NALU header is the first byte after Annex-B start code. + // NALU header is the first byte after Annex-B start code for H264/HEVC. *next_header_pos = pos + 3; return true; } -// For H264, return data bytes of next AU fragment in |data| from |next_pos|, +// For H264/HEVC, return data bytes of next AU fragment in |data| from |next_pos|, // and update the position to |next_pos|. std::string GetBytesForNextAU(const std::string& data, size_t* next_pos) { // Helpful description: @@ -144,6 +144,7 @@ void EncodedDataHelper::SliceToFragments(const std::string& data) { std::unique_ptr<Fragment> fragment(new Fragment()); switch (type_) { case VideoCodecType::H264: + case VideoCodecType::HEVC: fragment->data = GetBytesForNextAU(data, &next_pos); if (!ParseAUFragmentType(fragment.get())) continue; if (!seen_csd && !fragment->csd_flag) @@ -178,23 +179,37 @@ bool EncodedDataHelper::ParseAUFragmentType(Fragment* fragment) { return false; } - // Check NALU type ([3:7], 5-bit). - uint8_t nalu_type = nalu_header & 0x1f; - switch (nalu_type) { - case NON_IDR_SLICE: - case IDR_SLICE: - // If AU contains both CSD and VCL NALUs (e.g. PPS + IDR_SLICE), don't - // raise csd_flag, treat this fragment as VCL one. - fragment->csd_flag = false; - return true; // fragment in interest as VCL. - case SPS: - case PPS: - fragment->csd_flag = true; - // Continue on finding the subsequent NALUs, it may have VCL data. - break; - default: - // Skip uninterested NALU type. - break; + if (type_ == VideoCodecType::H264) { + // Check NALU type ([3:7], 5-bit). + uint8_t nalu_type = nalu_header & 0x1f; + switch (nalu_type) { + case NON_IDR_SLICE: + case IDR_SLICE: + // If AU contains both CSD and VCL NALUs (e.g. PPS + IDR_SLICE), don't + // raise csd_flag, treat this fragment as VCL one. + fragment->csd_flag = false; + return true; // fragment in interest as VCL. + case SPS: + case PPS: + fragment->csd_flag = true; + // Continue on finding the subsequent NALUs, it may have VCL data. + break; + default: + // Skip uninterested NALU type. + break; + } + } else if (type_ == VideoCodecType::HEVC) { + // Check NALU type ([1:7], 6-bit). + uint8_t nalu_type = (nalu_header & 0x7e) >> 1; + if (nalu_type >= VCL_NALU_MIN && nalu_type <= VCL_NALU_MAX) { + // If AU contains both CSD and VCL NALUs (e.g. PPS + IDR_SLICE), don't + // raise csd_flag, treat this fragment as VCL one. + fragment->csd_flag = false; + return true; // fragment in interest as VCL. + } else if (nalu_type >= CSD_NALU_MIN && nalu_type <= CSD_NALU_MAX) { + fragment->csd_flag = true; + // Continue on finding the subsequent NALUs, it may have VCL data. + } } } return fragment->csd_flag; // fragment in interest as CSD. diff --git a/tests/c2_e2e_test/jni/encoded_data_helper.h b/tests/c2_e2e_test/jni/encoded_data_helper.h index cf107c2..9ec5086 100644 --- a/tests/c2_e2e_test/jni/encoded_data_helper.h +++ b/tests/c2_e2e_test/jni/encoded_data_helper.h @@ -21,7 +21,7 @@ public: EncodedDataHelper(const std::string& file_path, VideoCodecType type); ~EncodedDataHelper(); - // A fragment will contain the bytes of one AU (H264) or frame (VP8/9) in + // A fragment will contain the bytes of one AU (H264/HEVC) or frame (VP8/9) in // |data|, and |csd_flag| indicator for input buffer flag CODEC_CONFIG. struct Fragment { std::string data; @@ -41,17 +41,25 @@ public: private: // NALU type enumeration as defined in H264 Annex-B. Only interested ones are // listed here. - enum NALUType : uint8_t { + enum H264NALUType : uint8_t { NON_IDR_SLICE = 0x1, IDR_SLICE = 0x5, SPS = 0x7, PPS = 0x8, }; + // NALU type enumeration for ranges for VCL and CSD NALUs for HEVC. + enum HEVCNALUType : uint8_t { + VCL_NALU_MIN = 0, + VCL_NALU_MAX = 31, + CSD_NALU_MIN = 32, // VPS, SPS, PPS + CSD_NALU_MAX = 34, + }; + // Slice input stream into fragments. This should be done in constructor. void SliceToFragments(const std::string& data); - // For H264, parse csd_flag from |fragment| data and store inside. Return true + // For H264/HEVC, parse csd_flag from |fragment| data and store inside. Return true // if this fragment is in interest; false otherwise (fragment will be // discarded.) bool ParseAUFragmentType(Fragment* fragment); diff --git a/tests/c2_e2e_test/jni/mediacodec_decoder.cpp b/tests/c2_e2e_test/jni/mediacodec_decoder.cpp index b14a841..cbebfdd 100644 --- a/tests/c2_e2e_test/jni/mediacodec_decoder.cpp +++ b/tests/c2_e2e_test/jni/mediacodec_decoder.cpp @@ -32,7 +32,7 @@ constexpr size_t kTimeoutMaxRetries = 500; // Helper function to get possible C2 hardware decoder names from |type|. // Note: A single test APK is built for both ARC++ and ARCVM, so both the VDA decoder and the new -// V4L2 decoder names need to be specified here. +// V4L2 decoder names need to be specified here (except for HEVC, which is only on ARCVM). std::vector<const char*> GetC2VideoDecoderNames(VideoCodecType type) { switch (type) { case VideoCodecType::H264: @@ -41,6 +41,8 @@ std::vector<const char*> GetC2VideoDecoderNames(VideoCodecType type) { return {"c2.v4l2.vp8.decoder", "c2.vda.vp8.decoder"}; case VideoCodecType::VP9: return {"c2.v4l2.vp9.decoder", "c2.vda.vp9.decoder"}; + case VideoCodecType::HEVC: + return {"c2.v4l2.hevc.decoder"}; default: // unknown type return {}; } diff --git a/tests/c2_e2e_test/jni/video_decoder_e2e_test.cpp b/tests/c2_e2e_test/jni/video_decoder_e2e_test.cpp index 46b497f..62589c2 100644 --- a/tests/c2_e2e_test/jni/video_decoder_e2e_test.cpp +++ b/tests/c2_e2e_test/jni/video_decoder_e2e_test.cpp @@ -50,10 +50,10 @@ public: // "input_file_path:width:height:num_frames:num_fragments:min_fps_render: // min_fps_no_render:video_codec_profile[:output_file_path]" // - |input_file_path| is compressed video stream in H264 Annex B (NAL) format - // (H264) or IVF (VP8/9). + // (H264/HEVC) or IVF (VP8/9). // - |width| and |height| are visible frame size in pixels. // - |num_frames| is the number of picture frames for the input stream. - // - |num_fragments| is the number of AU (H264) or frame (VP8/9) in the input + // - |num_fragments| is the number of AU (H264/HEVC) or frame (VP8/9) in the input // stream. (Unused. Test will automatically parse the number.) // - |min_fps_render| and |min_fps_no_render| are minimum frames/second speeds // expected to be achieved with and without rendering respective. |