SkCodec: Add Android-only CodecPreference
This allows the Android framework to choose a priority for HW or
SW codecs for formats for which Android has both options (e.g.
HEIF).
Bug: b/240347107
Change-Id: Ia804027d729dc0ff3b2dea947642df64fbc32bbc
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/573639
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h
index 5af847a..fe34f94 100644
--- a/include/codec/SkCodec.h
+++ b/include/codec/SkCodec.h
@@ -284,6 +284,40 @@
};
/**
+ * Codec selection order for H/W first, H/W only, S/W first, or S/W only.
+ *
+ * Currently this is only used for HEIF decoding.
+ *
+ * The default is kNoPreference, representing no order preference and the decision order
+ * will be device specific.
+ */
+ enum class CodecPreference {
+ /**
+ * No order preference specified, and decoder/encoder will be selected according to the
+ * default order, which is decided by devices.
+ */
+ kNoPreference = 0,
+ /**
+ * Prefer software codec first. Software codec will be checked first, if no software
+ * codec can decode the given content format, hardware codec will then be checked.
+ */
+ kPreferSoftwareCodecs = 1,
+ /**
+ * Only use hardware codec.
+ */
+ kOnlyHardwareCodecs = 2,
+ /**
+ * Prefer hardware codec first. Hardware codec will be checked first, if no hardware
+ * codec can decode the given content format, software codec will then be checked.
+ */
+ kPreferHardwareCodecs = 4,
+ /**
+ * Only use software codec.
+ */
+ kOnlySoftwareCodecs = 8,
+ };
+
+ /**
* Additional options to pass to getPixels.
*/
struct Options {
@@ -292,6 +326,7 @@
, fSubset(nullptr)
, fFrameIndex(0)
, fPriorFrame(kNoFrame)
+ , fCodecPreference(CodecPreference::kNoPreference)
{}
ZeroInitialized fZeroInitialized;
@@ -335,6 +370,16 @@
* If set to kNoFrame, the codec will decode any necessary required frame(s) first.
*/
int fPriorFrame;
+
+ /**
+ * Codec selection order for H/W first, H/W only, S/W first, or S/W only.
+ *
+ * Currently this is only used for HEIF decoding.
+ *
+ * The default is kNoPreference, representing no order preference and the decision order
+ * will be device specific.
+ */
+ CodecPreference fCodecPreference;
};
/**
diff --git a/src/codec/SkHeifCodec.cpp b/src/codec/SkHeifCodec.cpp
index 63bd9bd..583e156 100644
--- a/src/codec/SkHeifCodec.cpp
+++ b/src/codec/SkHeifCodec.cpp
@@ -19,6 +19,17 @@
#define FOURCC(c1, c2, c3, c4) \
((c1) << 24 | (c2) << 16 | (c3) << 8 | (c4))
+static_assert((int)SkCodec::CodecPreference::kNoPreference ==
+ kHeifCodecPreference_none, "CodecPreference mismatch!");
+static_assert((int)SkCodec::CodecPreference::kPreferSoftwareCodecs ==
+ kHeifCodecPreference_preferSoftwareCodecs, "CodecPreference mismatch!");
+static_assert((int)SkCodec::CodecPreference::kOnlyHardwareCodecs ==
+ kHeifCodecPreference_onlyHardwareCodecs, "CodecPreference mismatch!");
+static_assert((int)SkCodec::CodecPreference::kPreferHardwareCodecs ==
+ kHeifCodecPreference_preferHardwareCodecs, "CodecPreference mismatch!");
+static_assert((int)SkCodec::CodecPreference::kOnlySoftwareCodecs ==
+ kHeifCodecPreference_onlySoftwareCodecs, "CodecPreference mismatch!");
+
bool SkHeifCodec::IsSupported(const void* buffer, size_t bytesRead,
SkEncodedImageFormat* format) {
// Parse the ftyp box up to bytesRead to determine if this is HEIF or AVIF.
@@ -390,6 +401,8 @@
return kUnimplemented;
}
+ fHeifDecoder->setCodecPreference((int)options.fCodecPreference);
+
bool success;
if (fUseAnimation) {
success = fHeifDecoder->decodeSequence(options.fFrameIndex, &fFrameInfo);
diff --git a/src/codec/SkStubHeifDecoderAPI.h b/src/codec/SkStubHeifDecoderAPI.h
index 3fcdc94..510efe6 100644
--- a/src/codec/SkStubHeifDecoderAPI.h
+++ b/src/codec/SkStubHeifDecoderAPI.h
@@ -22,6 +22,14 @@
kHeifColorFormat_RGBA_1010102,
};
+enum HeifCodecPreference {
+ kHeifCodecPreference_none = 0,
+ kHeifCodecPreference_preferSoftwareCodecs = 1,
+ kHeifCodecPreference_onlyHardwareCodecs = 2,
+ kHeifCodecPreference_preferHardwareCodecs = 4,
+ kHeifCodecPreference_onlySoftwareCodecs = 8,
+};
+
struct HeifStream {
virtual ~HeifStream() {}
@@ -74,6 +82,10 @@
uint32_t getColorDepth() {
return 0;
}
+
+ void setCodecPreference(int codecPreference) {
+
+ }
};
static inline HeifDecoder* createHeifDecoder() { return new HeifDecoder; }