// Copyright 2017 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 <memory>
#include <vector>

#include <stdint.h>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/cxx17_backports.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/single_thread_task_runner.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "gpu/command_buffer/common/mailbox_holder.h"
#include "media/base/decode_status.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/media_log.h"
#include "media/base/mock_media_log.h"
#include "media/base/test_helpers.h"
#include "media/base/video_decoder.h"
#include "media/base/video_frame.h"
#include "media/base/waiting.h"
#include "media/mojo/clients/mojo_video_decoder.h"
#include "media/mojo/services/mojo_cdm_service_context.h"
#include "media/mojo/services/mojo_media_client.h"
#include "media/mojo/services/mojo_video_decoder_service.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/color_space.h"

using ::base::test::RunOnceCallback;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::HasSubstr;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::StrictMock;

namespace media {

namespace {

const int kMaxDecodeRequests = 4;
const int kErrorDataSize = 7;

// A mock VideoDecoder with helpful default functionality.
// TODO(sandersd): Determine how best to merge this with MockVideoDecoder
// declared in mock_filters.h.
class MockVideoDecoder : public VideoDecoder {
 public:
  MockVideoDecoder() {
    // Treat const getters like a NiceMock.
    EXPECT_CALL(*this, GetDecoderType())
        .WillRepeatedly(Return(VideoDecoderType::kTesting));
    EXPECT_CALL(*this, NeedsBitstreamConversion())
        .WillRepeatedly(Return(false));
    EXPECT_CALL(*this, CanReadWithoutStalling()).WillRepeatedly(Return(true));
    EXPECT_CALL(*this, GetMaxDecodeRequests())
        .WillRepeatedly(Return(kMaxDecodeRequests));

    // For regular methods, only configure a default action.
    ON_CALL(*this, Decode_(_, _))
        .WillByDefault(Invoke(this, &MockVideoDecoder::DoDecode));
    ON_CALL(*this, Reset_(_))
        .WillByDefault(Invoke(this, &MockVideoDecoder::DoReset));
  }

  MockVideoDecoder(const MockVideoDecoder&) = delete;
  MockVideoDecoder& operator=(const MockVideoDecoder&) = delete;

  // Re-declare as public.
  ~MockVideoDecoder() override {}

  // media::VideoDecoder implementation
  MOCK_CONST_METHOD0(GetDecoderType, VideoDecoderType());

  // Initialize() records values before delegating to the mock method.
  void Initialize(const VideoDecoderConfig& config,
                  bool /* low_delay */,
                  CdmContext* /* cdm_context */,
                  InitCB init_cb,
                  const OutputCB& output_cb,
                  const WaitingCB& waiting_cb) override {
    config_ = config;
    output_cb_ = output_cb;
    waiting_cb_ = waiting_cb;
    DoInitialize(init_cb);
  }

  void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB cb) override {
    Decode_(std::move(buffer), cb);
  }
  MOCK_METHOD2(Decode_, void(scoped_refptr<DecoderBuffer> buffer, DecodeCB&));
  void Reset(base::OnceClosure cb) override { Reset_(cb); }
  MOCK_METHOD1(Reset_, void(base::OnceClosure&));
  MOCK_CONST_METHOD0(NeedsBitstreamConversion, bool());
  MOCK_CONST_METHOD0(CanReadWithoutStalling, bool());
  MOCK_CONST_METHOD0(GetMaxDecodeRequests, int());

  // Mock helpers.
  MOCK_METHOD1(DoInitialize, void(InitCB&));
  VideoFrame::ReleaseMailboxCB GetReleaseMailboxCB() {
    DidGetReleaseMailboxCB();
    return std::move(release_mailbox_cb);
  }

  MOCK_METHOD0(DidGetReleaseMailboxCB, void());

  VideoFrame::ReleaseMailboxCB release_mailbox_cb;

  // Returns an output frame immediately.
  // TODO(sandersd): Extend to support tests of MojoVideoFrame frames.
  void DoDecode(scoped_refptr<DecoderBuffer> buffer, DecodeCB& decode_cb) {
    if (!buffer->end_of_stream()) {
      if (buffer->data_size() == kErrorDataSize) {
        // This size buffer indicates that decoder should return an error.
        // |decode_cb| must not be called from the same stack.
        base::ThreadTaskRunnerHandle::Get()->PostTask(
            FROM_HERE,
            base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR));
        return;
      }
      if (buffer->decrypt_config()) {
        // Simulate the case where outputs are only returned when key arrives.
        waiting_cb_.Run(WaitingReason::kNoDecryptionKey);
      } else {
        gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes];
        mailbox_holders[0].mailbox.name[0] = 1;
        scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTextures(
            PIXEL_FORMAT_ARGB, mailbox_holders, GetReleaseMailboxCB(),
            config_.coded_size(), config_.visible_rect(),
            config_.natural_size(), buffer->timestamp());
        frame->metadata().power_efficient = true;
        output_cb_.Run(frame);
      }
    }

    // |decode_cb| must not be called from the same stack.
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(std::move(decode_cb), DecodeStatus::OK));
  }

  void DoReset(base::OnceClosure& reset_cb) {
    // |reset_cb| must not be called from the same stack.
    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                  std::move(reset_cb));
  }

  base::WeakPtr<MockVideoDecoder> GetWeakPtr() {
    return weak_this_factory_.GetWeakPtr();
  }

 private:
  VideoDecoderConfig config_;
  OutputCB output_cb_;
  WaitingCB waiting_cb_;
  base::WeakPtrFactory<MockVideoDecoder> weak_this_factory_{this};
};

// Proxies CreateVideoDecoder() to a callback.
class FakeMojoMediaClient : public MojoMediaClient {
 public:
  using CreateVideoDecoderCB =
      base::RepeatingCallback<std::unique_ptr<VideoDecoder>(MediaLog*)>;

  explicit FakeMojoMediaClient(CreateVideoDecoderCB create_video_decoder_cb)
      : create_video_decoder_cb_(std::move(create_video_decoder_cb)) {}

  std::unique_ptr<VideoDecoder> CreateVideoDecoder(
      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
      MediaLog* media_log,
      mojom::CommandBufferIdPtr command_buffer_id,
      RequestOverlayInfoCB request_overlay_info_cb,
      const gfx::ColorSpace& target_color_space) override {
    return create_video_decoder_cb_.Run(media_log);
  }

 private:
  CreateVideoDecoderCB create_video_decoder_cb_;

  DISALLOW_COPY_AND_ASSIGN(FakeMojoMediaClient);
};

}  // namespace

class MojoVideoDecoderIntegrationTest : public ::testing::Test {
 public:
  MojoVideoDecoderIntegrationTest()
      : mojo_media_client_(base::BindRepeating(
            &MojoVideoDecoderIntegrationTest::CreateVideoDecoder,
            base::Unretained(this))) {}

  void TearDown() override {
    if (client_) {
      client_.reset();
      RunUntilIdle();
    }
  }

 protected:
  void RunUntilIdle() { task_environment_.RunUntilIdle(); }

  void SetWriterCapacity(uint32_t capacity) { writer_capacity_ = capacity; }

  mojo::PendingRemote<mojom::VideoDecoder> CreateRemoteVideoDecoder() {
    mojo::PendingRemote<mojom::VideoDecoder> remote_video_decoder;
    mojo::MakeSelfOwnedReceiver(
        std::make_unique<MojoVideoDecoderService>(&mojo_media_client_,
                                                  &mojo_cdm_service_context_),
        remote_video_decoder.InitWithNewPipeAndPassReceiver());
    return remote_video_decoder;
  }

  void CreateClient() {
    DCHECK(!client_);
    // TODO(sandersd): Pass a GpuVideoAcceleratorFactories so that the cache can
    // be tested.
    client_ = std::make_unique<MojoVideoDecoder>(
        base::ThreadTaskRunnerHandle::Get(), nullptr, &client_media_log_,
        CreateRemoteVideoDecoder(), RequestOverlayInfoCB(), gfx::ColorSpace());
    if (writer_capacity_)
      client_->set_writer_capacity_for_testing(writer_capacity_);
  }

  bool Initialize() {
    CreateClient();

    EXPECT_CALL(*decoder_, DoInitialize(_))
        .WillOnce(RunOnceCallback<0>(OkStatus()));

    Status result = OkStatus();
    StrictMock<base::MockCallback<VideoDecoder::InitCB>> init_cb;
    EXPECT_CALL(init_cb, Run(_)).WillOnce(SaveArg<0>(&result));

    EXPECT_EQ(client_->GetDecoderType(), VideoDecoderType::kUnknown);
    client_->Initialize(TestVideoConfig::NormalH264(), false, nullptr,
                        init_cb.Get(), output_cb_.Get(), waiting_cb_.Get());
    RunUntilIdle();

    return result.is_ok();
  }

  Status Decode(scoped_refptr<DecoderBuffer> buffer,
                VideoFrame::ReleaseMailboxCB release_cb =
                    VideoFrame::ReleaseMailboxCB()) {
    Status result(DecodeStatus::DECODE_ERROR);

    if (!buffer->end_of_stream()) {
      decoder_->release_mailbox_cb = std::move(release_cb);
      EXPECT_CALL(*decoder_, DidGetReleaseMailboxCB());
    }
    EXPECT_CALL(*decoder_, Decode_(_, _));

    StrictMock<base::MockCallback<VideoDecoder::DecodeCB>> decode_cb;
    EXPECT_CALL(decode_cb, Run(_)).WillOnce(SaveArg<0>(&result));

    client_->Decode(buffer, decode_cb.Get());
    RunUntilIdle();

    return result;
  }

  scoped_refptr<DecoderBuffer> CreateKeyframe(int64_t timestamp_ms) {
    // Use 32 bytes to simulated chunked write (with capacity 10; see below).
    std::vector<uint8_t> data(32, 0);

    scoped_refptr<DecoderBuffer> buffer =
        DecoderBuffer::CopyFrom(data.data(), data.size());

    buffer->set_timestamp(base::Milliseconds(timestamp_ms));
    buffer->set_duration(base::Milliseconds(10));
    buffer->set_is_key_frame(true);

    return buffer;
  }

  scoped_refptr<DecoderBuffer> CreateErrorFrame(int64_t timestamp_ms) {
    std::vector<uint8_t> data(kErrorDataSize, 0);

    scoped_refptr<DecoderBuffer> buffer =
        DecoderBuffer::CopyFrom(data.data(), data.size());

    buffer->set_timestamp(base::Milliseconds(timestamp_ms));
    buffer->set_duration(base::Milliseconds(10));
    buffer->set_is_key_frame(true);

    return buffer;
  }

  // TODO(xhwang): Add a function to help create encrypted video buffers in
  // media/base/test_helpers.h.
  scoped_refptr<DecoderBuffer> CreateEncryptedKeyframe(int64_t timestamp_ms) {
    auto buffer = CreateKeyframe(timestamp_ms);

    const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44};
    const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0};
    buffer->set_decrypt_config(DecryptConfig::CreateCencConfig(
        std::string(reinterpret_cast<const char*>(kFakeKeyId),
                    base::size(kFakeKeyId)),
        std::string(reinterpret_cast<const char*>(kFakeIv),
                    base::size(kFakeIv)),
        {}));

    return buffer;
  }

  // Callback that |client_| will deliver VideoFrames to.
  StrictMock<base::MockCallback<VideoDecoder::OutputCB>> output_cb_;

  StrictMock<base::MockCallback<WaitingCB>> waiting_cb_;

  // MojoVideoDecoder (client) under test.
  std::unique_ptr<MojoVideoDecoder> client_;

  // MediaLog that |client_| will deliver log events to.
  StrictMock<MockMediaLog> client_media_log_;

  // VideoDecoder (impl used by service) under test.
  // |decoder_owner_| owns the decoder until ownership is transferred to the
  // |MojoVideoDecoderService|. |decoder_| references it for the duration of its
  // lifetime.
  std::unique_ptr<MockVideoDecoder> decoder_owner_ =
      std::make_unique<MockVideoDecoder>();
  base::WeakPtr<MockVideoDecoder> decoder_ = decoder_owner_->GetWeakPtr();

  // MediaLog that the service has provided to |decoder_|. This should be
  // proxied to |client_media_log_|.
  MediaLog* decoder_media_log_ = nullptr;

 private:
  // Passes |decoder_| to the service.
  std::unique_ptr<VideoDecoder> CreateVideoDecoder(MediaLog* media_log) {
    DCHECK(!decoder_media_log_);
    decoder_media_log_ = media_log;
    return std::move(decoder_owner_);
  }

  base::test::TaskEnvironment task_environment_;

  // Capacity that will be used for the MojoDecoderBufferWriter.
  uint32_t writer_capacity_ = 0;

  MojoCdmServiceContext mojo_cdm_service_context_;

  // Provides |decoder_| to the service.
  FakeMojoMediaClient mojo_media_client_;

  DISALLOW_COPY_AND_ASSIGN(MojoVideoDecoderIntegrationTest);
};

TEST_F(MojoVideoDecoderIntegrationTest, CreateAndDestroy) {}

TEST_F(MojoVideoDecoderIntegrationTest, GetSupportedConfigs) {
  mojo::Remote<mojom::VideoDecoder> remote_video_decoder(
      CreateRemoteVideoDecoder());
  StrictMock<
      base::MockCallback<mojom::VideoDecoder::GetSupportedConfigsCallback>>
      callback;

  // TODO(sandersd): Expect there to be an entry.
  EXPECT_CALL(callback, Run(_, _));
  remote_video_decoder->GetSupportedConfigs(callback.Get());
  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, Initialize) {
  ASSERT_TRUE(Initialize());
  EXPECT_EQ(client_->GetDecoderType(), VideoDecoderType::kTesting);
  EXPECT_EQ(client_->NeedsBitstreamConversion(), false);
  EXPECT_EQ(client_->CanReadWithoutStalling(), true);
  EXPECT_EQ(client_->GetMaxDecodeRequests(), kMaxDecodeRequests);
}

TEST_F(MojoVideoDecoderIntegrationTest, InitializeFailNoDecoder) {
  CreateClient();

  StrictMock<base::MockCallback<VideoDecoder::InitCB>> init_cb;
  EXPECT_CALL(init_cb,
              Run(HasStatusCode(StatusCode::kMojoDecoderNoWrappedDecoder)));

  // Clear |decoder_| so that Initialize() should fail.
  decoder_owner_.reset();
  client_->Initialize(TestVideoConfig::NormalH264(), false, nullptr,
                      init_cb.Get(), output_cb_.Get(), waiting_cb_.Get());
  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, InitializeFailNoCdm) {
  CreateClient();

  StrictMock<base::MockCallback<VideoDecoder::InitCB>> init_cb;
  EXPECT_CALL(
      init_cb,
      Run(HasStatusCode(StatusCode::kDecoderMissingCdmForEncryptedContent)));

  // CdmContext* (3rd parameter) is not provided but the VideoDecoderConfig
  // specifies encrypted video, so Initialize() should fail.
  client_->Initialize(TestVideoConfig::NormalEncrypted(), false, nullptr,
                      init_cb.Get(), output_cb_.Get(), waiting_cb_.Get());
  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, MediaLogIsProxied) {
  ASSERT_TRUE(Initialize());
  EXPECT_MEDIA_LOG_ON(client_media_log_, HasSubstr("\"test\""));
  MEDIA_LOG(DEBUG, decoder_media_log_) << "test";
  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, WaitingForKey) {
  ASSERT_TRUE(Initialize());

  auto buffer = CreateEncryptedKeyframe(0);
  StrictMock<base::MockCallback<VideoDecoder::DecodeCB>> decode_cb;

  EXPECT_CALL(*decoder_, Decode_(_, _));
  EXPECT_CALL(waiting_cb_, Run(WaitingReason::kNoDecryptionKey));
  EXPECT_CALL(decode_cb, Run(IsOkStatus()));

  client_->Decode(buffer, decode_cb.Get());
  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, Decode) {
  ASSERT_TRUE(Initialize());

  EXPECT_CALL(output_cb_, Run(_));
  ASSERT_TRUE(Decode(CreateKeyframe(0)).is_ok());
  Mock::VerifyAndClearExpectations(&output_cb_);

  ASSERT_TRUE(Decode(DecoderBuffer::CreateEOSBuffer()).is_ok());
}

TEST_F(MojoVideoDecoderIntegrationTest, Release) {
  ASSERT_TRUE(Initialize());

  StrictMock<base::MockCallback<VideoFrame::ReleaseMailboxCB>> release_cb;
  scoped_refptr<VideoFrame> frame;

  EXPECT_CALL(output_cb_, Run(_)).WillOnce(SaveArg<0>(&frame));
  ASSERT_TRUE(Decode(CreateKeyframe(0), release_cb.Get()).is_ok());
  Mock::VerifyAndClearExpectations(&output_cb_);

  EXPECT_CALL(release_cb, Run(_));
  frame = nullptr;
  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, ReleaseAfterShutdown) {
  ASSERT_TRUE(Initialize());

  StrictMock<base::MockCallback<VideoFrame::ReleaseMailboxCB>> release_cb;
  scoped_refptr<VideoFrame> frame;

  EXPECT_CALL(output_cb_, Run(_)).WillOnce(SaveArg<0>(&frame));
  ASSERT_TRUE(Decode(CreateKeyframe(0), release_cb.Get()).is_ok());
  Mock::VerifyAndClearExpectations(&output_cb_);

  client_.reset();
  RunUntilIdle();

  EXPECT_CALL(release_cb, Run(_));
  frame = nullptr;
  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, ResetDuringDecode) {
  ASSERT_TRUE(Initialize());

  StrictMock<base::MockCallback<VideoDecoder::DecodeCB>> decode_cb;
  StrictMock<base::MockCallback<base::OnceClosure>> reset_cb;

  EXPECT_CALL(*decoder_, DidGetReleaseMailboxCB()).Times(AtLeast(0));
  EXPECT_CALL(output_cb_, Run(_)).Times(kMaxDecodeRequests);
  EXPECT_CALL(*decoder_, Decode_(_, _)).Times(kMaxDecodeRequests);
  EXPECT_CALL(*decoder_, Reset_(_));

  InSequence s;  // Make sure all callbacks are fired in order.
  EXPECT_CALL(decode_cb, Run(_)).Times(kMaxDecodeRequests);
  EXPECT_CALL(reset_cb, Run());

  int64_t timestamp_ms = 0;
  for (int j = 0; j < kMaxDecodeRequests; ++j) {
    client_->Decode(CreateKeyframe(timestamp_ms++), decode_cb.Get());
  }

  client_->Reset(reset_cb.Get());

  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, ResetDuringDecode_ChunkedWrite) {
  // Use a small writer capacity to force chunked write.
  SetWriterCapacity(10);
  ASSERT_TRUE(Initialize());

  VideoFrame::ReleaseMailboxCB release_cb = VideoFrame::ReleaseMailboxCB();
  StrictMock<base::MockCallback<VideoDecoder::DecodeCB>> decode_cb;
  StrictMock<base::MockCallback<base::OnceClosure>> reset_cb;

  EXPECT_CALL(*decoder_, DidGetReleaseMailboxCB()).Times(AtLeast(0));
  EXPECT_CALL(output_cb_, Run(_)).Times(kMaxDecodeRequests);
  EXPECT_CALL(*decoder_, Decode_(_, _)).Times(kMaxDecodeRequests);
  EXPECT_CALL(*decoder_, Reset_(_));

  InSequence s;  // Make sure all callbacks are fired in order.
  EXPECT_CALL(decode_cb, Run(_)).Times(kMaxDecodeRequests);
  EXPECT_CALL(reset_cb, Run());

  int64_t timestamp_ms = 0;
  for (int j = 0; j < kMaxDecodeRequests; ++j) {
    client_->Decode(CreateKeyframe(timestamp_ms++), decode_cb.Get());
  }

  client_->Reset(reset_cb.Get());

  RunUntilIdle();
}

TEST_F(MojoVideoDecoderIntegrationTest, InitialPlaybackUMASuccess) {
  base::HistogramTester histogram_tester_;
  const int frames_to_decode = kMojoDecoderInitialPlaybackFrameCount;

  ASSERT_TRUE(Initialize());

  StrictMock<base::MockCallback<VideoDecoder::DecodeCB>> decode_cb;

  EXPECT_CALL(*decoder_, DidGetReleaseMailboxCB()).Times(AnyNumber());
  EXPECT_CALL(output_cb_, Run(_)).Times(frames_to_decode);
  EXPECT_CALL(*decoder_, Decode_(_, _)).Times(frames_to_decode);

  EXPECT_CALL(decode_cb, Run(IsOkStatus())).Times(frames_to_decode);

  for (int i = 0; i < frames_to_decode - 1; i++)
    client_->Decode(CreateKeyframe(i * 16), decode_cb.Get());

  RunUntilIdle();
  histogram_tester_.ExpectBucketCount(
      kMojoVideoDecoderInitialPlaybackSuccessCodecCounterUMA, 1, 0);

  client_->Decode(CreateKeyframe(0), decode_cb.Get());

  RunUntilIdle();
  histogram_tester_.ExpectBucketCount(
      kMojoVideoDecoderInitialPlaybackSuccessCodecCounterUMA, 1, 1);
}

TEST_F(MojoVideoDecoderIntegrationTest, InitialPlaybackUMAError) {
  base::HistogramTester histogram_tester_;
  const int frames_to_decode = kMojoDecoderInitialPlaybackFrameCount;

  ASSERT_TRUE(Initialize());

  StrictMock<base::MockCallback<VideoDecoder::DecodeCB>> decode_cb;

  EXPECT_CALL(*decoder_, DidGetReleaseMailboxCB()).Times(AnyNumber());
  EXPECT_CALL(output_cb_, Run(_)).Times(frames_to_decode - 1);
  EXPECT_CALL(*decoder_, Decode_(_, _)).Times(frames_to_decode);

  EXPECT_CALL(decode_cb, Run(IsOkStatus())).Times(frames_to_decode - 1);

  EXPECT_CALL(decode_cb, Run(IsDecodeErrorStatus())).Times(1);

  for (int i = 0; i < frames_to_decode - 1; i++)
    client_->Decode(CreateKeyframe(i * 16), decode_cb.Get());

  RunUntilIdle();
  histogram_tester_.ExpectBucketCount(
      kMojoVideoDecoderInitialPlaybackErrorCodecCounterUMA, 1, 0);
  histogram_tester_.ExpectBucketCount(
      kMojoVideoDecoderInitialPlaybackSuccessCodecCounterUMA, 1, 0);

  client_->Decode(CreateErrorFrame(0), decode_cb.Get());

  RunUntilIdle();
  histogram_tester_.ExpectBucketCount(
      kMojoVideoDecoderInitialPlaybackErrorCodecCounterUMA, 1, 1);
  histogram_tester_.ExpectBucketCount(
      kMojoVideoDecoderInitialPlaybackSuccessCodecCounterUMA, 1, 0);
}

}  // namespace media
