summaryrefslogtreecommitdiff
path: root/chromium/media/webcodecs
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/webcodecs')
-rw-r--r--chromium/media/webcodecs/BUILD.gn39
-rw-r--r--chromium/media/webcodecs/wc_decoder_selector.cc142
-rw-r--r--chromium/media/webcodecs/wc_decoder_selector.h83
-rw-r--r--chromium/media/webcodecs/wc_decoder_selector_unittest.cc240
4 files changed, 0 insertions, 504 deletions
diff --git a/chromium/media/webcodecs/BUILD.gn b/chromium/media/webcodecs/BUILD.gn
deleted file mode 100644
index 325aa27053d..00000000000
--- a/chromium/media/webcodecs/BUILD.gn
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2020 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//testing/test.gni")
-
-source_set("webcodecs") {
- # Do not expand the visibility here without double-checking with OWNERS, this
- # is a roll-up target which is part of the //media component. Most other DEPs
- # should be using //media and not directly DEP this roll-up target.
- visibility = [ "//media" ]
-
- sources = [
- "wc_decoder_selector.cc",
- "wc_decoder_selector.h",
- ]
-
- public_deps = [
- "//base",
- "//media/base",
- "//media/filters",
- ]
-
- deps = []
-
- configs += [ "//media:subcomponent_config" ]
-}
-
-source_set("unit_tests") {
- testonly = true
- sources = [ "wc_decoder_selector_unittest.cc" ]
-
- deps = [
- "//base/test:test_support",
- "//media:test_support",
- "//testing/gmock",
- "//testing/gtest",
- ]
-}
diff --git a/chromium/media/webcodecs/wc_decoder_selector.cc b/chromium/media/webcodecs/wc_decoder_selector.cc
deleted file mode 100644
index 73b927dc4cc..00000000000
--- a/chromium/media/webcodecs/wc_decoder_selector.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/webcodecs/wc_decoder_selector.h"
-
-#include "base/bind.h"
-#include "base/check_op.h"
-#include "base/notreached.h"
-#include "base/single_thread_task_runner.h"
-#include "media/base/channel_layout.h"
-#include "media/base/demuxer_stream.h"
-#include "media/filters/decrypting_demuxer_stream.h"
-
-namespace media {
-
-// Demuxing isn't part of WebCodecs. This shim allows us to reuse decoder
-// selection logic from <video>.
-// TODO(chcunningham): Maybe refactor DecoderSelector to separate dependency on
-// DemuxerStream. DecoderSelection doesn't conceptually require a Demuxer. The
-// tough part is re-working DecryptingDemuxerStream.
-template <DemuxerStream::Type StreamType>
-class ShimDemuxerStream : public DemuxerStream {
- public:
- using DecoderConfigType =
- typename DecoderStreamTraits<StreamType>::DecoderConfigType;
-
- ~ShimDemuxerStream() override = default;
-
- void Read(ReadCB read_cb) override { NOTREACHED(); }
- bool IsReadPending() const override {
- NOTREACHED();
- return false;
- }
-
- void Configure(DecoderConfigType config);
-
- AudioDecoderConfig audio_decoder_config() override {
- DCHECK_EQ(type(), DemuxerStream::AUDIO);
- return audio_decoder_config_;
- }
-
- VideoDecoderConfig video_decoder_config() override {
- DCHECK_EQ(type(), DemuxerStream::VIDEO);
- return video_decoder_config_;
- }
-
- Type type() const override { return stream_type; }
-
- bool SupportsConfigChanges() override {
- NOTREACHED();
- return true;
- }
-
- private:
- static const DemuxerStream::Type stream_type = StreamType;
-
- AudioDecoderConfig audio_decoder_config_;
- VideoDecoderConfig video_decoder_config_;
-};
-
-template <>
-void ShimDemuxerStream<DemuxerStream::AUDIO>::Configure(
- DecoderConfigType config) {
- audio_decoder_config_ = config;
-}
-
-template <>
-void ShimDemuxerStream<DemuxerStream::VIDEO>::Configure(
- DecoderConfigType config) {
- video_decoder_config_ = config;
-}
-
-template <DemuxerStream::Type StreamType>
-WebCodecsDecoderSelector<StreamType>::WebCodecsDecoderSelector(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- CreateDecodersCB create_decoders_cb,
- typename Decoder::OutputCB output_cb)
- : impl_(std::move(task_runner),
- std::move(create_decoders_cb),
- &null_media_log_),
- demuxer_stream_(new ShimDemuxerStream<StreamType>()),
- stream_traits_(CreateStreamTraits()),
- output_cb_(output_cb) {
- impl_.Initialize(stream_traits_.get(), demuxer_stream_.get(),
- nullptr /*CdmContext*/, WaitingCB());
-}
-
-template <DemuxerStream::Type StreamType>
-WebCodecsDecoderSelector<StreamType>::~WebCodecsDecoderSelector() {}
-
-template <DemuxerStream::Type StreamType>
-void WebCodecsDecoderSelector<StreamType>::SelectDecoder(
- const DecoderConfig& config,
- SelectDecoderCB select_decoder_cb) {
- // |impl_| will internally use this the |config| from our ShimDemuxerStream.
- demuxer_stream_->Configure(config);
-
- // |impl_| uses a WeakFactory for its SelectDecoderCB, so we're safe to use
- // Unretained here.
- impl_.SelectDecoder(
- base::BindOnce(&WebCodecsDecoderSelector<StreamType>::OnDecoderSelected,
- base::Unretained(this), std::move(select_decoder_cb)),
- output_cb_);
-}
-
-template <>
-std::unique_ptr<WebCodecsAudioDecoderSelector::StreamTraits>
-WebCodecsDecoderSelector<DemuxerStream::AUDIO>::CreateStreamTraits() {
- // TODO(chcunningham): Consider plumbing real hw channel layout.
- return std::make_unique<WebCodecsDecoderSelector::StreamTraits>(
- &null_media_log_, CHANNEL_LAYOUT_NONE);
-}
-
-template <>
-std::unique_ptr<WebCodecsVideoDecoderSelector::StreamTraits>
-WebCodecsDecoderSelector<DemuxerStream::VIDEO>::CreateStreamTraits() {
- return std::make_unique<WebCodecsDecoderSelector::StreamTraits>(
- &null_media_log_);
-}
-
-template <DemuxerStream::Type StreamType>
-void WebCodecsDecoderSelector<StreamType>::OnDecoderSelected(
- SelectDecoderCB select_decoder_cb,
- std::unique_ptr<Decoder> decoder,
- std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
- DCHECK(!decrypting_demuxer_stream);
-
- // We immediately finalize decoder selection. From a spec POV we strongly
- // prefer to avoid replicating our internal design of having to wait for the
- // first frame to arrive before we consider configuration successful.
- // TODO(chcunningham): Measure first frame decode failures and find other ways
- // to solve (or minimize) the problem.
- impl_.FinalizeDecoderSelection();
-
- std::move(select_decoder_cb).Run(std::move(decoder));
-}
-
-template class WebCodecsDecoderSelector<DemuxerStream::VIDEO>;
-template class WebCodecsDecoderSelector<DemuxerStream::AUDIO>;
-
-} // namespace media
diff --git a/chromium/media/webcodecs/wc_decoder_selector.h b/chromium/media/webcodecs/wc_decoder_selector.h
deleted file mode 100644
index 207350f1a94..00000000000
--- a/chromium/media/webcodecs/wc_decoder_selector.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_WEBCODECS_WC_DECODER_SELECTOR_H_
-#define MEDIA_WEBCODECS_WC_DECODER_SELECTOR_H_
-
-#include <memory>
-
-#include "media/base/demuxer_stream.h"
-#include "media/base/media_export.h"
-#include "media/base/media_util.h"
-#include "media/filters/decoder_selector.h"
-#include "media/filters/decoder_stream_traits.h"
-
-namespace media {
-
-template <DemuxerStream::Type StreamType>
-class ShimDemuxerStream;
-
-template <DemuxerStream::Type StreamType>
-class MEDIA_EXPORT WebCodecsDecoderSelector {
- public:
- typedef DecoderStreamTraits<StreamType> StreamTraits;
- typedef typename StreamTraits::DecoderType Decoder;
- typedef typename StreamTraits::DecoderConfigType DecoderConfig;
-
- // Callback to create a list of decoders to select from.
- using CreateDecodersCB =
- base::RepeatingCallback<std::vector<std::unique_ptr<Decoder>>()>;
-
- // Emits the result of a single call to SelectDecoder(). Parameter is
- // the initialized Decoder. nullptr if selection failed. The caller owns the
- // Decoder.
- using SelectDecoderCB = base::OnceCallback<void(std::unique_ptr<Decoder>)>;
-
- WebCodecsDecoderSelector(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- CreateDecodersCB create_decoders_cb,
- typename Decoder::OutputCB output_cb);
-
- // Aborts any pending decoder selection.
- ~WebCodecsDecoderSelector();
-
- // Selects and initializes a decoder using |config|. Decoder will
- // be returned via |select_decoder_cb| posted to |task_runner_|. Subsequent
- // calls will again select from the full list of decoders.
- void SelectDecoder(const DecoderConfig& config,
- SelectDecoderCB select_decoder_cb);
-
- private:
- // Helper to create |stream_traits_|.
- std::unique_ptr<StreamTraits> CreateStreamTraits();
-
- // Proxy SelectDecoderCB from impl_ to our |select_decoder_cb|.
- void OnDecoderSelected(SelectDecoderCB select_decoder_cb,
- std::unique_ptr<Decoder> decoder,
- std::unique_ptr<DecryptingDemuxerStream>);
-
- // Implements heavy lifting for decoder selection.
- DecoderSelector<StreamType> impl_;
-
- // Shim to satisfy dependencies of |impl_|. Provides DecoderConfig to |impl_|.
- std::unique_ptr<ShimDemuxerStream<StreamType>> demuxer_stream_;
-
- // Helper to unify API for configuring audio/video decoders.
- std::unique_ptr<StreamTraits> stream_traits_;
-
- // Repeating callback for decoder outputs.
- typename Decoder::OutputCB output_cb_;
-
- // TODO(chcunningham): Route MEDIA_LOG for WebCodecs.
- NullMediaLog null_media_log_;
-};
-
-typedef WebCodecsDecoderSelector<DemuxerStream::VIDEO>
- WebCodecsVideoDecoderSelector;
-typedef WebCodecsDecoderSelector<DemuxerStream::AUDIO>
- WebCodecsAudioDecoderSelector;
-
-} // namespace media
-
-#endif // MEDIA_WEBCODECS_WC_DECODER_SELECTOR_H_
diff --git a/chromium/media/webcodecs/wc_decoder_selector_unittest.cc b/chromium/media/webcodecs/wc_decoder_selector_unittest.cc
deleted file mode 100644
index a14258468ee..00000000000
--- a/chromium/media/webcodecs/wc_decoder_selector_unittest.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <vector>
-
-#include "base/test/task_environment.h"
-#include "media/base/demuxer_stream.h"
-#include "media/base/media_util.h"
-#include "media/base/mock_filters.h"
-#include "media/base/status.h"
-#include "media/base/test_helpers.h"
-#include "media/base/video_decoder.h"
-#include "media/filters/decoder_stream.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include "media/webcodecs/wc_decoder_selector.h"
-
-using ::testing::_;
-using ::testing::IsNull;
-using ::testing::StrictMock;
-
-namespace media {
-
-namespace {
-
-enum DecoderCapability {
- kFail,
- kSucceed,
-};
-
-const char kNoDecoder[] = "";
-const char kDecoder1[] = "Decoder1";
-const char kDecoder2[] = "Decoder2";
-
-// Specializations for the AUDIO version of the test.
-class AudioDecoderSelectorTestParam {
- public:
- static constexpr DemuxerStream::Type kStreamType = DemuxerStream::AUDIO;
-
- using DecoderSelector = WebCodecsDecoderSelector<DemuxerStream::AUDIO>;
- using MockDecoder = MockAudioDecoder;
- using Output = AudioBuffer;
-
- static AudioDecoderConfig CreateConfig() { return TestAudioConfig::Normal(); }
-
- // Create a config that won't match the return of CreateConfig().
- static AudioDecoderConfig CreateAlternateConfig() {
- return TestAudioConfig::NormalEncrypted();
- }
-
- // Decoder::Initialize() takes different parameters depending on the type.
- static void ExpectInitialize(MockDecoder* decoder,
- DecoderCapability capability,
- AudioDecoderConfig expected_config) {
- EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _))
- .WillRepeatedly([capability, expected_config](
- const AudioDecoderConfig& config, CdmContext*,
- AudioDecoder::InitCB& init_cb,
- const AudioDecoder::OutputCB&, const WaitingCB&) {
- EXPECT_TRUE(config.Matches(expected_config));
- std::move(init_cb).Run(capability == kSucceed
- ? OkStatus()
- : StatusCode::kCodeOnlyForTesting);
- });
- }
-};
-
-// Specializations for the VIDEO version of the test.
-class VideoDecoderSelectorTestParam {
- public:
- static constexpr DemuxerStream::Type kStreamType = DemuxerStream::VIDEO;
-
- using DecoderSelector = WebCodecsDecoderSelector<DemuxerStream::VIDEO>;
- using MockDecoder = MockVideoDecoder;
- using Output = VideoFrame;
-
- static VideoDecoderConfig CreateConfig() { return TestVideoConfig::Normal(); }
-
- // Create a config that won't match the return of CreateConfig().
- static VideoDecoderConfig CreateAlternateConfig() {
- return TestVideoConfig::LargeEncrypted();
- }
-
- static void ExpectInitialize(MockDecoder* decoder,
- DecoderCapability capability,
- VideoDecoderConfig expected_config) {
- EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _, _))
- .WillRepeatedly([capability, expected_config](
- const VideoDecoderConfig& config, bool low_delay,
- CdmContext*, VideoDecoder::InitCB& init_cb,
- const VideoDecoder::OutputCB&, const WaitingCB&) {
- EXPECT_TRUE(config.Matches(expected_config));
- std::move(init_cb).Run(capability == kSucceed
- ? OkStatus()
- : StatusCode::kCodeOnlyForTesting);
- });
- }
-};
-
-// Allocate storage for the member variables.
-constexpr DemuxerStream::Type AudioDecoderSelectorTestParam::kStreamType;
-constexpr DemuxerStream::Type VideoDecoderSelectorTestParam::kStreamType;
-
-} // namespace
-
-// Note: The parameter is called TypeParam in the test cases regardless of what
-// we call it here. It's been named the same for convenience.
-// Note: The test fixtures inherit from this class. Inside the test cases the
-// test fixture class is called TestFixture.
-template <typename TypeParam>
-class WebCodecsDecoderSelectorTest : public ::testing::Test {
- public:
- // Convenience aliases.
- using Self = WebCodecsDecoderSelectorTest<TypeParam>;
- using Decoder = typename TypeParam::DecoderSelector::Decoder;
- using DecoderConfig = typename TypeParam::DecoderSelector::DecoderConfig;
- using MockDecoder = typename TypeParam::MockDecoder;
- using Output = typename TypeParam::Output;
-
- WebCodecsDecoderSelectorTest() { CreateDecoderSelector(); }
-
- void OnOutput(scoped_refptr<Output> output) { NOTREACHED(); }
-
- MOCK_METHOD1_T(OnDecoderSelected, void(std::string));
-
- void OnDecoderSelectedThunk(std::unique_ptr<Decoder> decoder) {
- // Report only the name of the decoder, since that's what the tests care
- // about. The decoder will be destructed immediately.
- OnDecoderSelected(decoder ? decoder->GetDisplayName() : kNoDecoder);
- }
-
- void AddMockDecoder(const std::string& decoder_name,
- DecoderCapability capability) {
- // Actual decoders are created in CreateDecoders(), which may be called
- // multiple times by the DecoderSelector.
- mock_decoders_to_create_.emplace_back(decoder_name, capability);
- }
-
- std::vector<std::unique_ptr<Decoder>> CreateDecoders() {
- std::vector<std::unique_ptr<Decoder>> decoders;
-
- for (const auto& info : mock_decoders_to_create_) {
- std::unique_ptr<StrictMock<MockDecoder>> decoder =
- std::make_unique<StrictMock<MockDecoder>>(info.first);
- TypeParam::ExpectInitialize(decoder.get(), info.second,
- last_set_decoder_config_);
- decoders.push_back(std::move(decoder));
- }
-
- return decoders;
- }
-
- void CreateDecoderSelector() {
- decoder_selector_ =
- std::make_unique<WebCodecsDecoderSelector<TypeParam::kStreamType>>(
- task_environment_.GetMainThreadTaskRunner(),
- base::BindRepeating(&Self::CreateDecoders, base::Unretained(this)),
- base::BindRepeating(&Self::OnOutput, base::Unretained(this)));
- }
-
- void SelectDecoder(DecoderConfig config = TypeParam::CreateConfig()) {
- last_set_decoder_config_ = config;
- decoder_selector_->SelectDecoder(
- config,
- base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)));
- RunUntilIdle();
- }
-
- void RunUntilIdle() { task_environment_.RunUntilIdle(); }
-
- base::test::TaskEnvironment task_environment_;
- NullMediaLog media_log_;
-
- DecoderConfig last_set_decoder_config_;
-
- std::unique_ptr<WebCodecsDecoderSelector<TypeParam::kStreamType>>
- decoder_selector_;
-
- std::vector<std::pair<std::string, DecoderCapability>>
- mock_decoders_to_create_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WebCodecsDecoderSelectorTest);
-};
-
-using WebCodecsDecoderSelectorTestParams =
- ::testing::Types<AudioDecoderSelectorTestParam,
- VideoDecoderSelectorTestParam>;
-TYPED_TEST_SUITE(WebCodecsDecoderSelectorTest,
- WebCodecsDecoderSelectorTestParams);
-
-TYPED_TEST(WebCodecsDecoderSelectorTest, NoDecoders) {
- EXPECT_CALL(*this, OnDecoderSelected(kNoDecoder));
- this->SelectDecoder();
-}
-
-TYPED_TEST(WebCodecsDecoderSelectorTest, OneDecoder) {
- this->AddMockDecoder(kDecoder1, kSucceed);
-
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectDecoder();
-}
-
-TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders) {
- this->AddMockDecoder(kDecoder1, kFail);
- this->AddMockDecoder(kDecoder2, kSucceed);
-
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
- this->SelectDecoder();
-}
-
-TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders_SelectAgain) {
- this->AddMockDecoder(kDecoder1, kSucceed);
- this->AddMockDecoder(kDecoder2, kSucceed);
-
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectDecoder();
-
- // Selecting again should give (a new instance of) the same decoder.
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectDecoder();
-}
-
-TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders_NewConfigSelectAgain) {
- this->AddMockDecoder(kDecoder1, kSucceed);
- this->AddMockDecoder(kDecoder2, kSucceed);
-
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- this->SelectDecoder(TypeParam::CreateConfig());
-
- // Selecting again should give (a new instance of) the same decoder.
- EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
- // Select again with a different config. Expected config verified during
- // CreateDecoders() the SelectDecoder() call.
- this->SelectDecoder(TypeParam::CreateAlternateConfig());
-}
-
-} // namespace media