blob: 50568e53141ae58939e3daf26fd5fa19a7aebaaf [file] [log] [blame]
// Copyright 2018 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 <utility>
#include "base/bind.h"
#include "media/base/decoder_buffer.h"
#include "media/base/fallback_video_decoder.h"
#include "media/base/video_decoder_config.h"
namespace media {
FallbackVideoDecoder::FallbackVideoDecoder(
std::unique_ptr<VideoDecoder> preferred,
std::unique_ptr<VideoDecoder> fallback)
: preferred_decoder_(std::move(preferred)),
fallback_decoder_(std::move(fallback)),
weak_factory_(this) {}
void FallbackVideoDecoder::Initialize(
const VideoDecoderConfig& config,
bool low_delay,
CdmContext* cdm_context,
const InitCB& init_cb,
const OutputCB& output_cb,
const WaitingForDecryptionKeyCB& waiting_for_decryption_key_cb) {
// If we've already fallen back, just reinitialize the selected decoder.
if (selected_decoder_ && did_fallback_) {
selected_decoder_->Initialize(config, low_delay, cdm_context, init_cb,
output_cb, waiting_for_decryption_key_cb);
return;
}
InitCB fallback_initialize_cb = base::BindRepeating(
&FallbackVideoDecoder::FallbackInitialize, weak_factory_.GetWeakPtr(),
config, low_delay, cdm_context, init_cb, output_cb,
waiting_for_decryption_key_cb);
preferred_decoder_->Initialize(config, low_delay, cdm_context,
std::move(fallback_initialize_cb), output_cb,
waiting_for_decryption_key_cb);
}
void FallbackVideoDecoder::FallbackInitialize(
const VideoDecoderConfig& config,
bool low_delay,
CdmContext* cdm_context,
const InitCB& init_cb,
const OutputCB& output_cb,
const WaitingForDecryptionKeyCB& waiting_for_decryption_key_cb,
bool success) {
// The preferred decoder was successfully initialized.
if (success) {
selected_decoder_ = preferred_decoder_.get();
init_cb.Run(true);
return;
}
did_fallback_ = true;
preferred_decoder_.reset();
selected_decoder_ = fallback_decoder_.get();
fallback_decoder_->Initialize(config, low_delay, cdm_context, init_cb,
output_cb, waiting_for_decryption_key_cb);
}
void FallbackVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
const DecodeCB& decode_cb) {
DCHECK(selected_decoder_);
selected_decoder_->Decode(std::move(buffer), decode_cb);
}
void FallbackVideoDecoder::Reset(const base::RepeatingClosure& reset_cb) {
DCHECK(selected_decoder_);
selected_decoder_->Reset(reset_cb);
}
bool FallbackVideoDecoder::NeedsBitstreamConversion() const {
DCHECK(selected_decoder_);
return selected_decoder_->NeedsBitstreamConversion();
}
bool FallbackVideoDecoder::CanReadWithoutStalling() const {
DCHECK(selected_decoder_);
return selected_decoder_->CanReadWithoutStalling();
}
int FallbackVideoDecoder::GetMaxDecodeRequests() const {
DCHECK(selected_decoder_);
return selected_decoder_->GetMaxDecodeRequests();
}
std::string FallbackVideoDecoder::GetDisplayName() const {
// MojoVideoDecoder always identifies itself as such, and never asks for the
// name of the underlying decoder.
NOTREACHED();
return "FallbackVideoDecoder";
}
FallbackVideoDecoder::~FallbackVideoDecoder() = default;
} // namespace media