v4l2_codec2: Add support for HEVC/H265 to the V4L2 decoder.

This adds support for the HEVC/H265 codec to the Android codec2 V4L2
decode component.

Bug: 215043150
Bug: 183217901
Test: ExoPlayer works with HEVC on guybrush w/ codecs added and
corresponding ChromeOS CLs for crosvm/libvda

Change-Id: I3707e9730d245871b74982527edfebe81b484e8a
(cherry picked from commit 05bacef7fa53541f21c85f26f6f8351dcdfd7f0e)
diff --git a/common/V4L2ComponentCommon.cpp b/common/V4L2ComponentCommon.cpp
index 518b489..f67a516 100644
--- a/common/V4L2ComponentCommon.cpp
+++ b/common/V4L2ComponentCommon.cpp
@@ -18,15 +18,18 @@
 const std::string V4L2ComponentName::kH264Decoder = "c2.v4l2.avc.decoder";
 const std::string V4L2ComponentName::kVP8Decoder = "c2.v4l2.vp8.decoder";
 const std::string V4L2ComponentName::kVP9Decoder = "c2.v4l2.vp9.decoder";
+const std::string V4L2ComponentName::kHEVCDecoder = "c2.v4l2.hevc.decoder";
 const std::string V4L2ComponentName::kH264SecureDecoder = "c2.v4l2.avc.decoder.secure";
 const std::string V4L2ComponentName::kVP8SecureDecoder = "c2.v4l2.vp8.decoder.secure";
 const std::string V4L2ComponentName::kVP9SecureDecoder = "c2.v4l2.vp9.decoder.secure";
+const std::string V4L2ComponentName::kHEVCSecureDecoder = "c2.v4l2.hevc.decoder.secure";
 
 // static
 bool V4L2ComponentName::isValid(const char* name) {
     return name == kH264Encoder || name == kVP8Encoder || name == kVP9Encoder ||
            name == kH264Decoder || name == kVP8Decoder || name == kVP9Decoder ||
-           name == kH264SecureDecoder || name == kVP8SecureDecoder || name == kVP9SecureDecoder;
+           name == kHEVCDecoder || name == kH264SecureDecoder || name == kVP8SecureDecoder ||
+           name == kVP9SecureDecoder || name == kHEVCSecureDecoder;
 }
 
 // static
diff --git a/common/V4L2Device.cpp b/common/V4L2Device.cpp
index 68a9dca..4e44fed 100644
--- a/common/V4L2Device.cpp
+++ b/common/V4L2Device.cpp
@@ -50,6 +50,11 @@
 #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4')
 #endif
 
+// HEVC parsed slices
+#ifndef V4L2_PIX_FMT_HEVC_SLICE
+#define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5')
+#endif
+
 namespace android {
 
 struct v4l2_format buildV4L2Format(const enum v4l2_buf_type type, uint32_t fourcc,
@@ -1237,6 +1242,13 @@
         } else {
             return V4L2_PIX_FMT_VP9;
         }
+    } else if (profile >= C2Config::PROFILE_HEVC_MAIN &&
+               profile <= C2Config::PROFILE_HEVC_3D_MAIN) {
+        if (sliceBased) {
+            return V4L2_PIX_FMT_HEVC_SLICE;
+        } else {
+            return V4L2_PIX_FMT_HEVC;
+        }
     } else {
         ALOGE("Unknown profile: %s", profileToString(profile));
         return 0;
@@ -1283,6 +1295,16 @@
             return C2Config::PROFILE_VP9_3;
         }
         break;
+    case VideoCodec::HEVC:
+        switch (profile) {
+        case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN:
+            return C2Config::PROFILE_HEVC_MAIN;
+        case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:
+            return C2Config::PROFILE_HEVC_MAIN_STILL;
+        case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10:
+            return C2Config::PROFILE_HEVC_MAIN_10;
+        }
+        break;
     default:
         ALOGE("Unknown codec: %u", codec);
     }
@@ -1305,6 +1327,9 @@
         case VideoCodec::VP9:
             queryId = V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
             break;
+        case VideoCodec::HEVC:
+            queryId = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
+            break;
         default:
             return false;
         }
@@ -1355,6 +1380,16 @@
             profiles = {C2Config::PROFILE_VP9_0};
         }
         break;
+    case V4L2_PIX_FMT_HEVC:
+    case V4L2_PIX_FMT_HEVC_SLICE:
+        if (!getSupportedProfiles(VideoCodec::HEVC, &profiles)) {
+            ALOGW("Driver doesn't support QUERY HEVC profiles, "
+                  "use default values, Main");
+            profiles = {
+                    C2Config::PROFILE_HEVC_MAIN,
+            };
+        }
+        break;
     default:
         ALOGE("Unhandled pixelformat %s", fourccToString(pixFmt).c_str());
         return {};
diff --git a/common/VideoTypes.cpp b/common/VideoTypes.cpp
index c123ad1..18ebfc9 100644
--- a/common/VideoTypes.cpp
+++ b/common/VideoTypes.cpp
@@ -19,6 +19,8 @@
         return "VP8";
     case VideoCodec::VP9:
         return "VP9";
+    case VideoCodec::HEVC:
+        return "HEVC";
     }
 }
 
diff --git a/common/include/v4l2_codec2/common/V4L2ComponentCommon.h b/common/include/v4l2_codec2/common/V4L2ComponentCommon.h
index b8cf031..a5fbdaf 100644
--- a/common/include/v4l2_codec2/common/V4L2ComponentCommon.h
+++ b/common/include/v4l2_codec2/common/V4L2ComponentCommon.h
@@ -18,9 +18,11 @@
     static const std::string kH264Decoder;
     static const std::string kVP8Decoder;
     static const std::string kVP9Decoder;
+    static const std::string kHEVCDecoder;
     static const std::string kH264SecureDecoder;
     static const std::string kVP8SecureDecoder;
     static const std::string kVP9SecureDecoder;
+    static const std::string kHEVCSecureDecoder;
 
     // Return true if |name| is a valid component name.
     static bool isValid(const char* name);
diff --git a/common/include/v4l2_codec2/common/VideoTypes.h b/common/include/v4l2_codec2/common/VideoTypes.h
index 076f096..54786e8 100644
--- a/common/include/v4l2_codec2/common/VideoTypes.h
+++ b/common/include/v4l2_codec2/common/VideoTypes.h
@@ -18,10 +18,11 @@
     H264,
     VP8,
     VP9,
+    HEVC,
 };
 
 constexpr std::initializer_list<VideoCodec> kAllCodecs = {VideoCodec::H264, VideoCodec::VP8,
-                                                          VideoCodec::VP9};
+                                                          VideoCodec::VP9, VideoCodec::HEVC};
 
 const char* VideoCodecToString(VideoCodec codec);
 const char* profileToString(C2Config::profile_t profile);
diff --git a/components/V4L2ComponentStore.cpp b/components/V4L2ComponentStore.cpp
index 4004ce5..feb5799 100644
--- a/components/V4L2ComponentStore.cpp
+++ b/components/V4L2ComponentStore.cpp
@@ -37,6 +37,9 @@
         name == V4L2ComponentName::kVP9Encoder) {
         return MEDIA_MIMETYPE_VIDEO_VP9;
     }
+    if (name == V4L2ComponentName::kHEVCDecoder || name == V4L2ComponentName::kHEVCSecureDecoder) {
+        return MEDIA_MIMETYPE_VIDEO_HEVC;
+    }
     return "";
 }
 
@@ -118,6 +121,8 @@
     ret.push_back(GetTraits(V4L2ComponentName::kVP9Encoder));
     ret.push_back(GetTraits(V4L2ComponentName::kVP9Decoder));
     ret.push_back(GetTraits(V4L2ComponentName::kVP9SecureDecoder));
+    ret.push_back(GetTraits(V4L2ComponentName::kHEVCDecoder));
+    ret.push_back(GetTraits(V4L2ComponentName::kHEVCSecureDecoder));
     return ret;
 }
 
diff --git a/components/V4L2DecodeInterface.cpp b/components/V4L2DecodeInterface.cpp
index 4bc4121..d22f77b 100644
--- a/components/V4L2DecodeInterface.cpp
+++ b/components/V4L2DecodeInterface.cpp
@@ -34,6 +34,8 @@
         return VideoCodec::VP8;
     if (name == V4L2ComponentName::kVP9Decoder || name == V4L2ComponentName::kVP9SecureDecoder)
         return VideoCodec::VP9;
+    if (name == V4L2ComponentName::kHEVCDecoder || name == V4L2ComponentName::kHEVCSecureDecoder)
+        return VideoCodec::HEVC;
 
     ALOGE("Unknown name: %s", name.c_str());
     return std::nullopt;
@@ -179,6 +181,35 @@
                         .withSetter(ProfileLevelSetter)
                         .build());
         break;
+
+    case VideoCodec::HEVC:
+        inputMime = MEDIA_MIMETYPE_VIDEO_HEVC;
+        addParameter(
+                DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+                        .withDefault(new C2StreamProfileLevelInfo::input(
+                                0u, C2Config::PROFILE_HEVC_MAIN, C2Config::LEVEL_HEVC_MAIN_5_1))
+                        .withFields({C2F(mProfileLevel, profile)
+                                             .oneOf({C2Config::PROFILE_HEVC_MAIN,
+                                                     C2Config::PROFILE_HEVC_MAIN_STILL}),
+                                     C2F(mProfileLevel, level)
+                                             .oneOf({C2Config::LEVEL_HEVC_MAIN_1,
+                                                     C2Config::LEVEL_HEVC_MAIN_2,
+                                                     C2Config::LEVEL_HEVC_MAIN_2_1,
+                                                     C2Config::LEVEL_HEVC_MAIN_3,
+                                                     C2Config::LEVEL_HEVC_MAIN_3_1,
+                                                     C2Config::LEVEL_HEVC_MAIN_4,
+                                                     C2Config::LEVEL_HEVC_MAIN_4_1,
+                                                     C2Config::LEVEL_HEVC_MAIN_5,
+                                                     C2Config::LEVEL_HEVC_MAIN_5_1,
+                                                     C2Config::LEVEL_HEVC_MAIN_5_2,
+                                                     C2Config::LEVEL_HEVC_HIGH_4,
+                                                     C2Config::LEVEL_HEVC_HIGH_4_1,
+                                                     C2Config::LEVEL_HEVC_HIGH_5,
+                                                     C2Config::LEVEL_HEVC_HIGH_5_1,
+                                                     C2Config::LEVEL_HEVC_HIGH_5_2})})
+                        .withSetter(ProfileLevelSetter)
+                        .build());
+        break;
     }
 
     addParameter(
@@ -346,6 +377,8 @@
         // codec2 framework that it should not stop queuing new work items until the maximum number
         // of frame reordering is reached, to avoid stalling the decoder.
         return 16;
+    case VideoCodec::HEVC:
+        return 16;
     case VideoCodec::VP8:
         return 0;
     case VideoCodec::VP9:
diff --git a/components/V4L2Decoder.cpp b/components/V4L2Decoder.cpp
index aa59e91..cc2c1d1 100644
--- a/components/V4L2Decoder.cpp
+++ b/components/V4L2Decoder.cpp
@@ -42,6 +42,8 @@
         return V4L2_PIX_FMT_VP8;
     case VideoCodec::VP9:
         return V4L2_PIX_FMT_VP9;
+    case VideoCodec::HEVC:
+        return V4L2_PIX_FMT_HEVC;
     }
 }