blob: 95889cf6a0971ac2ed73cfd7f248bccaec901a1d [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.
#ifndef MEDIA_FILTERS_FUCHSIA_FUCHSIA_VIDEO_DECODER_H_
#define MEDIA_FILTERS_FUCHSIA_FUCHSIA_VIDEO_DECODER_H_
#include <deque>
#include <memory>
#include <vector>
#include <fuchsia/media/cpp/fidl.h>
#include "base/memory/scoped_refptr.h"
#include "media/base/media_export.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
#include "media/fuchsia/common/sysmem_buffer_stream.h"
#include "media/fuchsia/common/sysmem_client.h"
#include "ui/gfx/native_pixmap_handle.h"
namespace gfx {
class ClientNativePixmapFactory;
} // namespace gfx
namespace viz {
class RasterContextProvider;
} // namespace viz
namespace media {
class MEDIA_EXPORT FuchsiaVideoDecoder : public VideoDecoder,
public SysmemBufferStream::Sink,
public StreamProcessorHelper::Client {
public:
// Creates VideoDecoder that uses fuchsia.mediacodec API. The returned
// VideoDecoder instance will only try to use hardware video codecs.
MEDIA_EXPORT static std::unique_ptr<VideoDecoder> Create(
scoped_refptr<viz::RasterContextProvider> raster_context_provider);
// Same as above, but also allows to enable software codecs. This is useful
// for FuchsiaVideoDecoder tests that run on systems that don't have hardware
// decoder support.
MEDIA_EXPORT static std::unique_ptr<VideoDecoder> CreateForTests(
scoped_refptr<viz::RasterContextProvider> raster_context_provider,
bool enable_sw_decoding);
FuchsiaVideoDecoder(
scoped_refptr<viz::RasterContextProvider> raster_context_provider,
bool enable_sw_decoding);
~FuchsiaVideoDecoder() override;
FuchsiaVideoDecoder(const FuchsiaVideoDecoder&) = delete;
FuchsiaVideoDecoder& operator=(const FuchsiaVideoDecoder&) = delete;
// Decoder implementation.
bool IsPlatformDecoder() const override;
bool SupportsDecryption() const override;
VideoDecoderType GetDecoderType() const override;
// VideoDecoder implementation.
void Initialize(const VideoDecoderConfig& config,
bool low_delay,
CdmContext* cdm_context,
InitCB init_cb,
const OutputCB& output_cb,
const WaitingCB& waiting_cb) override;
void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override;
void Reset(base::OnceClosure closure) override;
bool NeedsBitstreamConversion() const override;
bool CanReadWithoutStalling() const override;
int GetMaxDecodeRequests() const override;
private:
class OutputMailbox;
StatusCode InitializeSysmemBufferStream(bool is_encrypted,
CdmContext* cdm_context,
bool* secure_mode);
// SysmemBufferStream::Sink implementation.
void OnSysmemBufferStreamBufferCollectionToken(
fuchsia::sysmem::BufferCollectionTokenPtr token) override;
void OnSysmemBufferStreamOutputPacket(
StreamProcessorHelper::IoPacket packet) override;
void OnSysmemBufferStreamEndOfStream() override;
void OnSysmemBufferStreamError() override;
void OnSysmemBufferStreamNoKey() override;
// StreamProcessorHelper::Client implementation.
void OnStreamProcessorAllocateOutputBuffers(
const fuchsia::media::StreamBufferConstraints& stream_constraints)
override;
void OnStreamProcessorEndOfStream() override;
void OnStreamProcessorOutputFormat(
fuchsia::media::StreamOutputFormat format) override;
void OnStreamProcessorOutputPacket(
StreamProcessorHelper::IoPacket packet) override;
void OnStreamProcessorNoKey() override;
void OnStreamProcessorError() override;
// Calls next callback in the |decode_callbacks_| queue.
void CallNextDecodeCallback();
// Drops all pending input buffers and then calls all pending DecodeCB with
// |status|. Returns true if the decoder still exists.
bool DropInputQueue(DecodeStatus status);
// Called on errors to shutdown the decoder and notify the client.
void OnError();
// Callback for SysmemBufferCollection::CreateSharedToken(), used to send the
// sysmem buffer collection token to the GPU process.
void SetBufferCollectionTokenForGpu(
fuchsia::sysmem::BufferCollectionTokenPtr token);
// Called by OutputMailbox to signal that the output buffer can be reused.
void ReleaseOutputPacket(StreamProcessorHelper::IoPacket packet);
// Releases BufferCollection used for output buffers if any.
void ReleaseOutputBuffers();
const scoped_refptr<viz::RasterContextProvider> raster_context_provider_;
const bool enable_sw_decoding_;
const bool use_overlays_for_video_;
OutputCB output_cb_;
WaitingCB waiting_cb_;
// Aspect ratio specified in container.
VideoAspectRatio container_aspect_ratio_;
std::unique_ptr<SysmemBufferStream> sysmem_buffer_stream_;
// Initialized in InitializeSysmemBufferStream()
size_t max_decoder_requests_ = 1;
VideoDecoderConfig current_config_;
std::unique_ptr<StreamProcessorHelper> decoder_;
SysmemAllocatorClient sysmem_allocator_;
std::unique_ptr<gfx::ClientNativePixmapFactory> client_native_pixmap_factory_;
// Callbacks for pending Decode() request.
std::deque<DecodeCB> decode_callbacks_;
// Input buffers for |decoder_|.
std::unique_ptr<SysmemCollectionClient> input_buffer_collection_;
// Output buffers for |decoder_|.
fuchsia::media::VideoUncompressedFormat output_format_;
std::unique_ptr<SysmemCollectionClient> output_buffer_collection_;
gfx::SysmemBufferCollectionId output_buffer_collection_id_;
std::vector<OutputMailbox*> output_mailboxes_;
size_t num_used_output_buffers_ = 0;
base::WeakPtr<FuchsiaVideoDecoder> weak_this_;
base::WeakPtrFactory<FuchsiaVideoDecoder> weak_factory_{this};
// WeakPtrFactory used to schedule CallNextDecodeCallbacks(). These pointers
// are discarded in DropInputQueue() in order to avoid calling
// Decode() callback when the decoder queue is discarded.
base::WeakPtrFactory<FuchsiaVideoDecoder> decode_callbacks_weak_factory_{
this};
};
} // namespace media
#endif // MEDIA_FILTERS_FUCHSIA_FUCHSIA_VIDEO_DECODER_H_