diff --git a/README.md b/README.md index b2bb9d1f..bfb0dc5a 100644 --- a/README.md +++ b/README.md @@ -154,15 +154,15 @@ If you press 'Benchmark', you should see something like the following in logcat on a Pixel 6 Pro when running the benchmark: ```shell -lyra_benchmark: feature_extractor: max: 0.685 ms min: 0.206 ms mean: 0.219 ms stdev: 0.000 ms -lyra_benchmark: quantizer_quantize: max: 0.250 ms min: 0.076 ms mean: 0.082 ms stdev: 0.000 ms -lyra_benchmark: quantizer_decode: max: 0.152 ms min: 0.027 ms mean: 0.030 ms stdev: 0.001 ms -lyra_benchmark: model_decode: max: 0.560 ms min: 0.223 ms mean: 0.237 ms stdev: 0.000 ms -lyra_benchmark: total: max: 1.560 ms min: 0.541 ms mean: 0.569 ms stdev: 0.005 ms +lyra_benchmark: feature_extractor: max: 0.575 ms min: 0.131 ms mean: 0.139 ms stdev: 0.004 ms +lyra_benchmark: quantizer_quantize: max: 0.304 ms min: 0.105 ms mean: 0.109 ms stdev: 0.002 ms +lyra_benchmark: quantizer_decode: max: 0.103 ms min: 0.025 ms mean: 0.026 ms stdev: 0.000 ms +lyra_benchmark: model_decode: max: 0.462 ms min: 0.187 ms mean: 0.197 ms stdev: 0.001 ms +lyra_benchmark: total: max: 1.160 ms min: 0.452 ms mean: 0.473 ms stdev: 0.009 ms ``` This shows that decoding a 50Hz frame (each frame is 20 milliseconds) takes -0.569 milliseconds on average. So decoding is performed at around 35 (20/0.569) +0.473 milliseconds on average. So decoding is performed at around 42 (20/0.473) times faster than realtime. To build your own android app, you can either use the cc_library target outputs @@ -262,9 +262,10 @@ class LyraEncoder : public LyraEncoderInterface { The static `Create` method instantiates a `LyraEncoder` with the desired sample rate in Hertz, number of channels and bitrate, as long as those parameters are -supported. Else it returns a nullptr. The `Create` method also needs to know if -DTX should be enabled and where the model weights are stored. It also checks -that these weights exist and are compatible with the current Lyra version. +supported (see `lyra_encoder.h` for supported parameters). Otherwise it returns +a nullptr. The `Create` method also needs to know if DTX should be enabled and +where the model weights are stored. It also checks that these weights exist and +are compatible with the current Lyra version. Given a `LyraEncoder`, any audio stream can be compressed using the `Encode` method. The provided span of int16-formatted samples is assumed to contain 20ms diff --git a/WORKSPACE b/WORKSPACE index 81960b79..d659d079 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -39,7 +39,7 @@ git_repository( tag = "20211102.0", # Remove after https://github.com/abseil/abseil-cpp/issues/326 is solved. patches = [ - "@//third_party:com_google_absl_f863b622fe13612433fdf43f76547d5edda0c93001.diff" + "@//patches:com_google_absl_f863b622fe13612433fdf43f76547d5edda0c93001.diff" ], patch_args = [ "-p1", @@ -174,12 +174,8 @@ git_repository( ) # Check bazel version requirement, which is stricter than TensorFlow's. -load( - "@org_tensorflow//tensorflow:version_check.bzl", - "check_bazel_version_at_least", -) - -check_bazel_version_at_least("3.7.2") +load("@bazel_skylib//lib:versions.bzl", "versions") +versions.check("3.7.2") # TF WORKSPACE Loading functions # This section uses a subset of the tensorflow WORKSPACE loading by reusing its contents. diff --git a/android_example/BUILD b/android_example/BUILD index 893a82b0..9aab3da0 100644 --- a/android_example/BUILD +++ b/android_example/BUILD @@ -1,5 +1,7 @@ load("@rules_android//android:rules.bzl", "android_binary", "android_library") +# Placeholder for jni import + package(default_visibility = ["//visibility:public"]) licenses(["notice"]) diff --git a/decoder_main.cc b/decoder_main.cc index 7098fcca..72e80adc 100644 --- a/decoder_main.cc +++ b/decoder_main.cc @@ -52,8 +52,10 @@ ABSL_FLAG(chromemedia::codec::PacketLossPattern, fixed_packet_loss_pattern, "|packet_loss_rate| and |average_burst_length|."); ABSL_FLAG(std::string, model_path, "model_coeffs", "Path to directory containing TFLite files. For mobile this is the " - "absolute path, like '/sdcard/model_coeffs/'. For desktop this is " - "the path relative to the binary."); + "absolute path, like " + "'/data/local/tmp/model_coeffs/'. For " + "desktop " + "this is the path relative to the binary."); int main(int argc, char** argv) { absl::SetProgramUsageMessage(argv[0]); diff --git a/encoder_main.cc b/encoder_main.cc index ad49c993..fda27ab0 100644 --- a/encoder_main.cc +++ b/encoder_main.cc @@ -32,7 +32,8 @@ ABSL_FLAG(std::string, output_dir, "", "name as the wav file they come from with a '.lyra' postfix. Will " "overwrite existing files."); ABSL_FLAG(int, bitrate, 3200, - "The bitrate in bps with which to quantize the file."); + "The bitrate in bps with which to quantize the file. The " + "bitrate options can be seen in lyra_encoder.h"); ABSL_FLAG(bool, enable_preprocessing, false, "If enabled runs the input signal through the preprocessing " "module before encoding."); @@ -41,8 +42,10 @@ ABSL_FLAG(bool, enable_dtx, false, "when noise is detected."); ABSL_FLAG(std::string, model_path, "model_coeffs", "Path to directory containing TFLite files. For mobile this is the " - "absolute path, like '/sdcard/model_coeffs/'. For desktop this is " - "the path relative to the binary."); + "absolute path, like " + "'/data/local/tmp/model_coeffs/'. For " + "desktop " + "this is the path relative to the binary."); int main(int argc, char** argv) { absl::SetProgramUsageMessage(argv[0]); diff --git a/lyra_benchmark.cc b/lyra_benchmark.cc index 427632bd..219fb66e 100644 --- a/lyra_benchmark.cc +++ b/lyra_benchmark.cc @@ -27,8 +27,10 @@ ABSL_FLAG(int, num_cond_vectors, 2000, ABSL_FLAG(std::string, model_path, "model_coeffs", "Path to directory containing TFLite files. For mobile this is the " - "absolute path, like '/sdcard/model_coeffs/'. For desktop this is " - "the path relative to the binary."); + "absolute path, like " + "'/data/local/tmp/model_coeffs/'. For " + "desktop " + "this is the path relative to the binary."); ABSL_FLAG(bool, benchmark_feature_extraction, true, "Whether to benchmark the feature extraction."); diff --git a/lyra_benchmark_lib.cc b/lyra_benchmark_lib.cc index 2debb50c..5e217757 100644 --- a/lyra_benchmark_lib.cc +++ b/lyra_benchmark_lib.cc @@ -159,8 +159,8 @@ std::optional> MaybeRunGenerativeModel( return decoded; } -// Prints stats and writes CSV for the runtime information in |timings| to file -// under /{sdcard,tmp}/benchmark/lyra/. +// Prints stats for the runtime information in |timings|. For desktop, also +// writes to CSV files under /tmp/benchmark/. void PrintStatsAndWriteCSV(const std::vector& timings, const absl::string_view title) { constexpr absl::string_view stats_template = @@ -210,19 +210,15 @@ int lyra_benchmark(const int num_cond_vectors, const std::string model_path = GetCompleteArchitecturePath(model_base_path); std::unique_ptr feature_extractor = - benchmark_feature_extraction - ? CreateFeatureExtractor( - kInternalSampleRateHz, kNumFeatures, num_samples_per_hop, - GetNumSamplesPerWindow(kInternalSampleRateHz), model_path) - : nullptr; + benchmark_feature_extraction ? CreateFeatureExtractor(model_path) + : nullptr; std::unique_ptr vector_quantizer = - benchmark_quantizer ? CreateQuantizer(kNumFeatures, model_path) : nullptr; + benchmark_quantizer ? CreateQuantizer(model_path) : nullptr; std::unique_ptr model = benchmark_generative_model - ? CreateGenerativeModel(GetNumSamplesPerHop(kInternalSampleRateHz), - kNumFeatures, model_path) + ? CreateGenerativeModel(kNumFeatures, model_path) : nullptr; std::vector feature_extractor_timings; diff --git a/lyra_components.cc b/lyra_components.cc index 156b7621..ba3361ee 100644 --- a/lyra_components.cc +++ b/lyra_components.cc @@ -40,19 +40,17 @@ constexpr int kMaxNumPacketBits = 184; } // namespace std::unique_ptr CreateQuantizer( - int num_output_features, const ghc::filesystem::path& model_path) { + const ghc::filesystem::path& model_path) { return ResidualVectorQuantizer::Create(model_path); } std::unique_ptr CreateGenerativeModel( - int num_samples_per_hop, int num_output_features, - const ghc::filesystem::path& model_path) { + int num_output_features, const ghc::filesystem::path& model_path) { return LyraGanModel::Create(model_path, num_output_features); } std::unique_ptr CreateFeatureExtractor( - int sample_rate_hz, int num_features, int num_samples_per_hop, - int num_samples_per_window, const ghc::filesystem::path& model_path) { + const ghc::filesystem::path& model_path) { return SoundStreamEncoder::Create(model_path); } diff --git a/lyra_components.h b/lyra_components.h index 9804a288..5277258a 100644 --- a/lyra_components.h +++ b/lyra_components.h @@ -30,15 +30,13 @@ namespace chromemedia { namespace codec { std::unique_ptr CreateQuantizer( - int num_output_features, const ghc::filesystem::path& model_path); + const ghc::filesystem::path& model_path); std::unique_ptr CreateGenerativeModel( - int num_samples_per_hop, int num_output_features, - const ghc::filesystem::path& model_path); + int num_output_features, const ghc::filesystem::path& model_path); std::unique_ptr CreateFeatureExtractor( - int sample_rate_hz, int num_features, int num_samples_per_hop, - int num_samples_per_window, const ghc::filesystem::path& model_path); + const ghc::filesystem::path& model_path); std::unique_ptr CreatePacket(int num_header_bits, int num_quantized_bits); diff --git a/lyra_config.cc b/lyra_config.cc index 5e113846..5bfba0ad 100644 --- a/lyra_config.cc +++ b/lyra_config.cc @@ -24,23 +24,23 @@ namespace codec { // The Lyra version is |kVersionMajor|.|kVersionMinor|.|kVersionMicro| // The version is not used internally, but clients may use it to configure // behavior, such as checking for version bumps that break the bitstream. -// The major version should be bumped whenever the bitstream breaks. +// The major version should be bumped for major architectural changes. const int kVersionMajor = 1; -// |kVersionMinor| needs to be increased every time a new version requires a +// The minor version needs to be increased every time a new version requires a // simultaneous change in code and weights or if the bit stream is modified. The // |identifier| field needs to be set in lyra_config.textproto to match this. -const int kVersionMinor = 2; +const int kVersionMinor = 3; // The micro version is for other things like a release of bugfixes. const int kVersionMicro = 0; const int kNumFeatures = 64; const int kNumMelBins = 160; const int kNumChannels = 1; -const int kFrameRate = 50; const int kOverlapFactor = 2; // LINT.IfChange const int kNumHeaderBits = 0; +const int kFrameRate = 50; const std::vector& GetSupportedQuantizedBits() { static const std::vector* const supported_quantization_bits = new std::vector{64, 120, 184}; @@ -48,6 +48,7 @@ const std::vector& GetSupportedQuantizedBits() { } // LINT.ThenChange( // lyra_components.cc, +// lyra_encoder.h, // residual_vector_quantizer.h, // ) diff --git a/lyra_decoder.cc b/lyra_decoder.cc index f3a7851f..e7593329 100644 --- a/lyra_decoder.cc +++ b/lyra_decoder.cc @@ -114,8 +114,7 @@ std::unique_ptr LyraDecoder::Create( return nullptr; } // All internal components operate at |kInternalSampleRateHz|. - auto model = - CreateGenerativeModel(kNumSamplesPerHop, kNumFeatures, model_path); + auto model = CreateGenerativeModel(kNumFeatures, model_path); if (model == nullptr) { LOG(ERROR) << "New model could not be instantiated."; return nullptr; @@ -134,7 +133,7 @@ std::unique_ptr LyraDecoder::Create( LOG(ERROR) << "Could not create Noise Estimator."; return nullptr; } - auto vector_quantizer = CreateQuantizer(kNumFeatures, model_path); + auto vector_quantizer = CreateQuantizer(model_path); if (vector_quantizer == nullptr) { LOG(ERROR) << "Could not create Vector Quantizer."; return nullptr; diff --git a/lyra_encoder.cc b/lyra_encoder.cc index b6a783bc..573ebbe9 100644 --- a/lyra_encoder.cc +++ b/lyra_encoder.cc @@ -64,19 +64,13 @@ std::unique_ptr LyraEncoder::Create( } } - const int internal_samples_per_hop = - GetNumSamplesPerHop(kInternalSampleRateHz); - const int internal_samples_per_window = - GetNumSamplesPerWindow(kInternalSampleRateHz); - auto feature_extractor = CreateFeatureExtractor( - kInternalSampleRateHz, kNumFeatures, internal_samples_per_hop, - internal_samples_per_window, model_path); + auto feature_extractor = CreateFeatureExtractor(model_path); if (feature_extractor == nullptr) { LOG(ERROR) << "Could not create Features Extractor."; return nullptr; } - auto vector_quantizer = CreateQuantizer(kNumFeatures, model_path); + auto vector_quantizer = CreateQuantizer(model_path); if (vector_quantizer == nullptr) { LOG(ERROR) << "Could not create Vector Quantizer."; return nullptr; @@ -84,9 +78,9 @@ std::unique_ptr LyraEncoder::Create( std::unique_ptr noise_estimator = nullptr; if (enable_dtx) { - noise_estimator = - NoiseEstimator::Create(sample_rate_hz, internal_samples_per_hop, - internal_samples_per_window, kNumMelBins); + noise_estimator = NoiseEstimator::Create( + sample_rate_hz, GetNumSamplesPerHop(kInternalSampleRateHz), + GetNumSamplesPerWindow(kInternalSampleRateHz), kNumMelBins); if (noise_estimator == nullptr) { LOG(ERROR) << "Could not create Noise Estimator."; return nullptr; @@ -127,9 +121,7 @@ std::optional> LyraEncoder::Encode( audio_for_encoding = absl::MakeConstSpan(processed); } - const int internal_samples_per_hop = - GetNumSamplesPerHop(kInternalSampleRateHz); - if (audio_for_encoding.size() != internal_samples_per_hop) { + if (audio_for_encoding.size() != GetNumSamplesPerHop(kInternalSampleRateHz)) { LOG(ERROR) << "The number of audio samples has to be exactly " << GetNumSamplesPerHop(sample_rate_hz_) << ", but is " << audio.size() << "."; diff --git a/lyra_encoder_test.cc b/lyra_encoder_test.cc index a60e37cc..a91969d5 100644 --- a/lyra_encoder_test.cc +++ b/lyra_encoder_test.cc @@ -220,7 +220,6 @@ TEST_P(LyraEncoderTest, ReceiveSamplesSucceeds) { LyraEncoderPeer encoder_peer( std::move(mock_resampler_), std::move(mock_feature_extractor_), - std::move(mock_noise_estimator_), std::move(mock_vector_quantizer_), external_sample_rate_hz_, num_quantized_bits_, /*enable_dtx=*/true); diff --git a/lyra_gan_model.cc b/lyra_gan_model.cc index f6bd8b1a..1f573516 100644 --- a/lyra_gan_model.cc +++ b/lyra_gan_model.cc @@ -35,7 +35,9 @@ namespace codec { std::unique_ptr LyraGanModel::Create( const ghc::filesystem::path& model_path, int num_features) { - auto model = TfLiteModelWrapper::Create(model_path / "lyragan.tflite", true); + auto model = + TfLiteModelWrapper::Create(model_path / "lyragan.tflite", + /*use_xnn=*/true, /*int8_quantized=*/true); if (model == nullptr) { LOG(ERROR) << "Unable to create LyraGAN TFLite model wrapper."; return nullptr; @@ -52,11 +54,6 @@ bool LyraGanModel::RunConditioning(const std::vector& features) { absl::Span input = model_->get_input_tensor(0); std::copy(features.begin(), features.end(), input.begin()); model_->Invoke(); - for (int i = 1; i < model_->num_input_tensors(); ++i) { - absl::Span input_state = model_->get_input_tensor(i); - absl::Span output_state = model_->get_output_tensor(i); - std::copy(output_state.begin(), output_state.end(), input_state.begin()); - } return true; } diff --git a/model_coeffs/lyra_config.binarypb b/model_coeffs/lyra_config.binarypb index 009a24fe..d65dd8f1 100644 --- a/model_coeffs/lyra_config.binarypb +++ b/model_coeffs/lyra_config.binarypb @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/model_coeffs/lyragan.tflite b/model_coeffs/lyragan.tflite index 83391e53..1cb98cb6 100644 Binary files a/model_coeffs/lyragan.tflite and b/model_coeffs/lyragan.tflite differ diff --git a/model_coeffs/quantizer.tflite b/model_coeffs/quantizer.tflite index 274153a7..e72dc0af 100644 Binary files a/model_coeffs/quantizer.tflite and b/model_coeffs/quantizer.tflite differ diff --git a/model_coeffs/soundstream_encoder.tflite b/model_coeffs/soundstream_encoder.tflite index bc4916d0..d6594f83 100644 Binary files a/model_coeffs/soundstream_encoder.tflite and b/model_coeffs/soundstream_encoder.tflite differ diff --git a/patches/BUILD b/patches/BUILD new file mode 100644 index 00000000..124e5a8b --- /dev/null +++ b/patches/BUILD @@ -0,0 +1,3 @@ +licenses(["notice"]) + +package(default_visibility = ["//visibility:public"]) diff --git a/patches/com_google_absl_f863b622fe13612433fdf43f76547d5edda0c93001.diff b/patches/com_google_absl_f863b622fe13612433fdf43f76547d5edda0c93001.diff new file mode 100644 index 00000000..46a28270 --- /dev/null +++ b/patches/com_google_absl_f863b622fe13612433fdf43f76547d5edda0c93001.diff @@ -0,0 +1,14 @@ +diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel +index 9fceffe..e7f9d01 100644 +--- a/absl/time/internal/cctz/BUILD.bazel ++++ b/absl/time/internal/cctz/BUILD.bazel +@@ -69,8 +69,5 @@ cc_library( + "include/cctz/zone_info_source.h", + ], + linkopts = select({ +- ":osx": [ +- "-framework Foundation", +- ], + ":ios": [ + "-framework Foundation", + ], diff --git a/residual_vector_quantizer.cc b/residual_vector_quantizer.cc index 5f5ca1eb..75bcff81 100644 --- a/residual_vector_quantizer.cc +++ b/residual_vector_quantizer.cc @@ -36,7 +36,8 @@ namespace codec { std::unique_ptr ResidualVectorQuantizer::Create( const ghc::filesystem::path& model_path) { auto quantizer_model = - TfLiteModelWrapper::Create(model_path / "quantizer.tflite", false); + TfLiteModelWrapper::Create(model_path / "quantizer.tflite", + /*use_xnn=*/false, /*int8_quantized=*/false); if (quantizer_model == nullptr) { LOG(ERROR) << "Unable to create the quantizer TfLite model wrapper."; return nullptr; diff --git a/residual_vector_quantizer_test.cc b/residual_vector_quantizer_test.cc index dbe6e037..a897dcf0 100644 --- a/residual_vector_quantizer_test.cc +++ b/residual_vector_quantizer_test.cc @@ -107,7 +107,7 @@ TEST_P(ResidualVectorQuantizerTest, EncodeDecodeResultsInSimilarFeatures) { auto decoded_features = quantizer_->DecodeToLossyFeatures(quantized.value()); ASSERT_TRUE(decoded_features.has_value()); EXPECT_EQ(decoded_features.value().size(), features_.size()); - EXPECT_LT(FeatureDistance(decoded_features.value()), 1.1); + EXPECT_LT(FeatureDistance(decoded_features.value()), 1.11); } INSTANTIATE_TEST_SUITE_P(NumQuantizedBits, ResidualVectorQuantizerTest, diff --git a/soundstream_encoder.cc b/soundstream_encoder.cc index 59bf3923..c0a0de61 100644 --- a/soundstream_encoder.cc +++ b/soundstream_encoder.cc @@ -35,8 +35,9 @@ namespace codec { std::unique_ptr SoundStreamEncoder::Create( const ghc::filesystem::path& model_path) { - auto model = TfLiteModelWrapper::Create( - model_path / "soundstream_encoder.tflite", true); + auto model = + TfLiteModelWrapper::Create(model_path / "soundstream_encoder.tflite", + /*use_xnn=*/true, /*int8_quantized=*/true); if (model == nullptr) { LOG(ERROR) << "Unable to create SoundStream encoder TFLite model wrapper."; return nullptr; @@ -58,11 +59,6 @@ std::optional> SoundStreamEncoder::Extract( LOG(ERROR) << "Unable to invoke SoundStream encoder TFLite model wrapper."; return std::nullopt; } - for (int i = 1; i < model_->num_input_tensors(); ++i) { - absl::Span input_state = model_->get_input_tensor(i); - absl::Span output_state = model_->get_output_tensor(i); - std::copy(output_state.begin(), output_state.end(), input_state.begin()); - } absl::Span output = model_->get_output_tensor(0); return std::vector(output.begin(), output.end()); } diff --git a/tflite_model_wrapper.cc b/tflite_model_wrapper.cc index 3d253704..0f884294 100644 --- a/tflite_model_wrapper.cc +++ b/tflite_model_wrapper.cc @@ -34,7 +34,8 @@ namespace chromemedia { namespace codec { std::unique_ptr TfLiteModelWrapper::Create( - const ghc::filesystem::path& model_file, bool use_xnn) { + const ghc::filesystem::path& model_file, bool use_xnn, + bool int8_quantized) { auto model = tflite::FlatBufferModel::BuildFromFile(model_file.c_str()); if (model == nullptr) { LOG(ERROR) << "Could not build TFLite FlatBufferModel for file: " @@ -62,6 +63,9 @@ std::unique_ptr TfLiteModelWrapper::Create( if (use_xnn) { // Enable XXNPack. auto options = TfLiteXNNPackDelegateOptionsDefault(); + if (int8_quantized) { + options.flags |= TFLITE_XNNPACK_DELEGATE_FLAG_QS8; + } options.num_threads = 1; auto delegate = std::unique_ptr >( diff --git a/tflite_model_wrapper.h b/tflite_model_wrapper.h index 8c54b1ab..b9647f3a 100644 --- a/tflite_model_wrapper.h +++ b/tflite_model_wrapper.h @@ -32,7 +32,8 @@ namespace codec { class TfLiteModelWrapper { public: static std::unique_ptr Create( - const ghc::filesystem::path& model_file, bool use_xnn); + const ghc::filesystem::path& model_file, bool use_xnn, + bool int8_quantized); bool Invoke(); diff --git a/tflite_model_wrapper_test.cc b/tflite_model_wrapper_test.cc index 3bcc65df..3f6822b2 100644 --- a/tflite_model_wrapper_test.cc +++ b/tflite_model_wrapper_test.cc @@ -30,12 +30,17 @@ namespace codec { namespace { TEST(TfLiteModelWrapperTest, CreateFailsWithInvalidModelFile) { - EXPECT_EQ(TfLiteModelWrapper::Create("invalid/model/path", true), nullptr); + EXPECT_EQ(TfLiteModelWrapper::Create("invalid/model/path", true, false), + nullptr); } -TEST(TfliteUtilsTest, CreateSucceedsAndMethodsRun) { +class TfLiteModelWrapperTest : public testing::TestWithParam {}; + +TEST_P(TfLiteModelWrapperTest, CreateSucceedsAndMethodsRun) { + const bool int8_quantized = GetParam(); auto model_wrapper = TfLiteModelWrapper::Create( - ghc::filesystem::current_path() / "model_coeffs/lyragan.tflite", true); + ghc::filesystem::current_path() / "model_coeffs/lyragan.tflite", true, + int8_quantized); ASSERT_NE(model_wrapper, nullptr); absl::Span input = model_wrapper->get_input_tensor(0); std::fill(input.begin(), input.end(), 0); @@ -43,6 +48,9 @@ TEST(TfliteUtilsTest, CreateSucceedsAndMethodsRun) { EXPECT_TRUE(model_wrapper->ResetVariableTensors()); } +INSTANTIATE_TEST_SUITE_P(Int8QuantizedOrNot, TfLiteModelWrapperTest, + testing::Bool()); + } // namespace } // namespace codec } // namespace chromemedia