blob: dfcd8faceba042896cee88fb24cf7f4e054a2861 [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 GARNET_BIN_MEDIA_CODECS_SW_OMX_CODEC_RUNNER_SW_OMX_CODEC_RUNNER_H_
#define GARNET_BIN_MEDIA_CODECS_SW_OMX_CODEC_RUNNER_SW_OMX_CODEC_RUNNER_H_
#include <threads.h>
#include <fuchsia/mediacodec/cpp/fidl.h>
#include "lib/fidl/cpp/binding.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/synchronization/thread_annotations.h"
namespace codec_runner {
// This is an abstract base class whose main purpose is to prevent us from
// assuming that all codecs run locally will be OMX codecs.
class CodecRunner : public fuchsia::media::StreamProcessor {
public:
// needs a virtual destructor because unique_ptr will be deleting via vtable
// entry instead of direct call to destructor
virtual ~CodecRunner();
// Load() will be called after the derived class constructor.
virtual bool Load() = 0;
// Only one of the following SetXXXParams() is called, corresponding to which
// codec type was requested via CodecFactory. These are meant to be an easy
// way to convey the most recent known version of complete codec creation
// parameters to the CodecRunner. As such they are not intended to be a
// complete CodecFactory implementation, nor does this class implement
// CodecFactory.
virtual void SetDecoderParams(
fuchsia::mediacodec::CreateDecoder_Params decoder_params) = 0;
// TODO(dustingreen):
// virtual void SetAudioEncoderParams(...) = 0;
// virtual void SetVideoEncoderParams(...) = 0;
// (or combined)
// Now that type-specific params are set, input_constraints_ can be computed.
// We want this done before binding the Codec channel so we can immediately
// send the input constraints as soon as BindAndOwnSelf(), to ensure that
// input constraints get sent first from server to client, per the Codec
// protocol.
virtual void ComputeInputConstraints() = 0;
// This call causes ownership of "this" to transfer to binding_, which
// essentially makes "this" self-owned (roughly speaking), or slightly more
// precisely, owned by the Codec channel via ImplPtr of the binding being
// std::unique_ptr<CodecRunner> here (instead of the default Codec*).
void BindAndOwnSelf(
fidl::InterfaceRequest<fuchsia::media::StreamProcessor> codec_request,
std::unique_ptr<CodecRunner> self);
// Some sub-classes want to send initial output constraints very early,
// instead of waiting for any input data. This can be because the codec
// implementation isn't capable of waiting until input data has arrived before
// demanding output buffers despite a tendency (but not guarantee) of forcing
// re-configuration of those initial output buffers (I'm looking at you OMX),
// or because the codec really does already know the output buffer constraints
// based on codec creation info, so doesn't need any input data before
// indicating output constraints.
//
// This intentionally gets called _before_ sending input constraints, so extra
// output re-config is avoided if the client processes this before sending
// input data.
//
// The default implementation does nothing.
virtual void onInputConstraintsReady(){};
// The Setup ordering domain is done. This allows the items in the Setup
// ordering domain to be completely separate from the StreamControl ordering
// domain.
virtual void onSetupDone(){};
void Exit(const char* format, ...);
protected:
CodecRunner(async_dispatcher_t* fidl_dispatcher, thrd_t fidl_thread);
// Lock that protects stuff.
//
// TODO(dustingreen): Figure out which locks and condition variables / events
// to use from FXL, or how to get FXL_GUARDED_BY() to understand std::mutex +
// std::unique_lock<> (including when a unique_lock& is passed into a method
// along the way but will definitely be locked again by the time that method
// returns) if that's possible. We should use FXL_GUARDED_BY() where its
// expressiveness is sufficient.
std::mutex lock_;
async_dispatcher_t* const fidl_dispatcher_;
const thrd_t fidl_thread_;
using BindingType = fidl::Binding<fuchsia::media::StreamProcessor,
std::unique_ptr<CodecRunner>>;
std::unique_ptr<BindingType> binding_;
bool input_constraints_sent_ = false;
// This must be set by derived class no later than the end of
// SetAudioDecoderParams() or analogous method, so that this will be
// guaranteed to be set before Codec binding occurs, so we can send these
// constraints during BindAndOwnSelf().
//
// This remains valid after CodecRunner sends OnInputConstraints(), in case
// a derived class wants to refer to the input constraints.
std::unique_ptr<const fuchsia::media::StreamBufferConstraints>
input_constraints_;
FXL_DISALLOW_IMPLICIT_CONSTRUCTORS(CodecRunner);
};
} // namespace codec_runner
#endif // GARNET_BIN_MEDIA_CODECS_SW_OMX_CODEC_RUNNER_SW_OMX_CODEC_RUNNER_H_