Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove specialization of std::default_delete for media::VideoDecoder
Some VideoDecoder implementations must do non-synchronous work besides resource reclamation during their destruction process, this CL allows them to do that more cleanly and safely via an 'AsyncDestroyVideoDecoder' wrapper. All they need to do is implement a static 'DestroyAsync' method that takes an instance by unique_ptr, and they can post whatever tasks they need within that function without worrying about being destroyed when it returns. Change-Id: I05f258a4cda90b9850e1c4a22c1084bae2dda563 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2191275 Commit-Queue: Will Cassella <cassew@google.com> Reviewed-by: Dan Sanders <sandersd@chromium.org> Reviewed-by: Frank Liberato <liberato@chromium.org> Cr-Commit-Position: refs/heads/master@{#782257}
- Loading branch information
1 parent
282efbe
commit 6212caf
Showing
17 changed files
with
266 additions
and
222 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Copyright (c) 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_BASE_ASYNC_DESTROY_VIDEO_DECODER_H_ | ||
#define MEDIA_BASE_ASYNC_DESTROY_VIDEO_DECODER_H_ | ||
|
||
#include <memory> | ||
#include <type_traits> | ||
#include "media/base/video_decoder.h" | ||
|
||
namespace media { | ||
|
||
// Some VideoDecoder implementations must do non-synchronous cleanup before | ||
// they are destroyed. This wrapper implementation allows a VideoDecoder | ||
// to schedule its own cleanup tasks before its memory is released. | ||
// The underlying type must implement a static | ||
// `DestroyAsync(std::unique_ptr<T>)` function which fires any pending | ||
// callbacks, stops and destroys the decoder. After this call, external | ||
// resources (e.g. raw pointers) held by the decoder might be invalidated | ||
// immediately. So if the decoder is destroyed asynchronously (e.g. DeleteSoon), | ||
// external resources must be released in this call. | ||
template <typename T> | ||
class AsyncDestroyVideoDecoder final : public VideoDecoder { | ||
public: | ||
explicit AsyncDestroyVideoDecoder(std::unique_ptr<T> wrapped_decoder) | ||
: wrapped_decoder_(std::move(wrapped_decoder)) { | ||
static_assert(std::is_base_of<VideoDecoder, T>::value, | ||
"T must implement 'media::VideoDecoder'"); | ||
DCHECK(wrapped_decoder_); | ||
} | ||
|
||
~AsyncDestroyVideoDecoder() override { | ||
if (wrapped_decoder_) | ||
T::DestroyAsync(std::move(wrapped_decoder_)); | ||
} | ||
|
||
std::string GetDisplayName() const override { | ||
DCHECK(wrapped_decoder_); | ||
return wrapped_decoder_->GetDisplayName(); | ||
} | ||
|
||
bool IsPlatformDecoder() const override { | ||
DCHECK(wrapped_decoder_); | ||
return wrapped_decoder_->IsPlatformDecoder(); | ||
} | ||
|
||
void Initialize(const VideoDecoderConfig& config, | ||
bool low_delay, | ||
CdmContext* cdm_context, | ||
InitCB init_cb, | ||
const OutputCB& output_cb, | ||
const WaitingCB& waiting_cb) override { | ||
DCHECK(wrapped_decoder_); | ||
wrapped_decoder_->Initialize(config, low_delay, cdm_context, | ||
std::move(init_cb), output_cb, waiting_cb); | ||
} | ||
|
||
void Decode(scoped_refptr<DecoderBuffer> buffer, | ||
DecodeCB decode_cb) override { | ||
DCHECK(wrapped_decoder_); | ||
wrapped_decoder_->Decode(std::move(buffer), std::move(decode_cb)); | ||
} | ||
|
||
void Reset(base::OnceClosure closure) override { | ||
DCHECK(wrapped_decoder_); | ||
wrapped_decoder_->Reset(std::move(closure)); | ||
} | ||
|
||
bool NeedsBitstreamConversion() const override { | ||
DCHECK(wrapped_decoder_); | ||
return wrapped_decoder_->NeedsBitstreamConversion(); | ||
} | ||
|
||
bool CanReadWithoutStalling() const override { | ||
DCHECK(wrapped_decoder_); | ||
return wrapped_decoder_->CanReadWithoutStalling(); | ||
} | ||
|
||
int GetMaxDecodeRequests() const override { | ||
DCHECK(wrapped_decoder_); | ||
return wrapped_decoder_->GetMaxDecodeRequests(); | ||
} | ||
|
||
private: | ||
std::unique_ptr<T> wrapped_decoder_; | ||
}; | ||
|
||
} // namespace media | ||
|
||
#endif // MEDIA_BASE_ASYNC_DESTROY_VIDEO_DECODER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.