blob: 1a94cf5b33979b4d27d8c41c380be9a832fa748d [file] [log] [blame]
// 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_BASE_ASYNC_DESTROY_VIDEO_ENCODER_H_
#define MEDIA_BASE_ASYNC_DESTROY_VIDEO_ENCODER_H_
#include <memory>
#include <type_traits>
#include "media/base/video_encoder.h"
namespace media {
// Some VideoEncoder implementations must do non-synchronous cleanup before
// they are destroyed. This wrapper implementation allows a VideoEncoder
// 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 AsyncDestroyVideoEncoder final : public VideoEncoder {
public:
explicit AsyncDestroyVideoEncoder(std::unique_ptr<T> wrapped_encoder)
: wrapped_encoder_(std::move(wrapped_encoder)) {
static_assert(std::is_base_of<VideoEncoder, T>::value,
"T must implement 'media::VideoEncoder'");
DCHECK(wrapped_encoder_);
}
~AsyncDestroyVideoEncoder() override {
if (wrapped_encoder_)
T::DestroyAsync(std::move(wrapped_encoder_));
}
void Initialize(VideoCodecProfile profile,
const Options& options,
OutputCB output_cb,
StatusCB done_cb) override {
DCHECK(wrapped_encoder_);
wrapped_encoder_->Initialize(profile, options, std::move(output_cb),
std::move(done_cb));
}
void Encode(scoped_refptr<VideoFrame> frame,
bool key_frame,
StatusCB done_cb) override {
DCHECK(wrapped_encoder_);
wrapped_encoder_->Encode(std::move(frame), key_frame, std::move(done_cb));
}
void ChangeOptions(const Options& options,
OutputCB output_cb,
StatusCB done_cb) override {
DCHECK(wrapped_encoder_);
wrapped_encoder_->ChangeOptions(options, std::move(output_cb),
std::move(done_cb));
}
void Flush(StatusCB done_cb) override {
DCHECK(wrapped_encoder_);
wrapped_encoder_->Flush(std::move(done_cb));
}
private:
std::unique_ptr<T> wrapped_encoder_;
};
} // namespace media
#endif // MEDIA_BASE_ASYNC_DESTROY_VIDEO_ENCODER_H_