blob: f1b3dd0ffdfc03889b6424c56ffab1968bc0cac4 [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_LOCAL_CODEC_FACTORY_H_
#define GARNET_BIN_MEDIA_CODECS_SW_OMX_CODEC_RUNNER_SW_OMX_LOCAL_CODEC_FACTORY_H_
#include <threads.h>
#include <functional>
#include <fuchsia/mediacodec/cpp/fidl.h>
#include <lib/fit/function.h>
#include "lib/fidl/cpp/binding.h"
// The LocalCodecFactory implements CodecFactory, but it's a very limited local
// implementation. The main implementation of CodecFactory is in
// codec_codec_factory_impl.h/cc.
//
// The point of the implementation here is to do some basic sanity checks,
// accept config info, and call the owner of this class back to achieve the
// actual binding of the server end of a Codec channel to a Codec implementation
// provided by the owner. That way the owner can wire up the details however
// the owner wants.
//
// This class does not need to deal with every potential version of a codec
// creation request. Instead, this class only needs to deal with requests made
// by the latest main CodecFactory implementation, as the main CodecFactory will
// have already converted any older-style requests to the latest style.
//
// Any given instance of this class is only capable of creating the codec type
// for which it was instantiated, based on which constructor was called. This
// de-fans the CodecFactory interface for the owning code. It's fairly
// mechanical which is why it's a separate class to deal with the de-fan without
// really applying any real strategy in this class.
//
// The interaction between the main CodecFactory and built-in SW codec isolates
// is something that only needs to handle the same build version on both sides.
namespace codec_runner {
class CodecRunner;
} // namespace codec_runner
namespace codec_factory {
class LocalCodecFactory : public fuchsia::mediacodec::CodecFactory {
public:
using BindAudioDecoderCallback = fit::function<void(
fidl::InterfaceRequest<fuchsia::media::StreamProcessor>,
fuchsia::mediacodec::CreateDecoder_Params audio_params)>;
// This creates a self-owned CodecFactory instance that knows how to create
// any of the codecs supported by this isolate process, regardless of which
// codec type.
static void CreateSelfOwned(
async_dispatcher_t* fidl_dispatcher, thrd_t fidl_thread,
fidl::InterfaceRequest<fuchsia::mediacodec::CodecFactory> request);
virtual void CreateDecoder(
fuchsia::mediacodec::CreateDecoder_Params audio_decoder_params,
::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> audio_decoder)
override;
virtual void CreateDecoder2(
fuchsia::mediacodec::CreateDecoder_Params audio_decoder_params,
::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> audio_decoder)
override;
virtual void CreateEncoder(
fuchsia::mediacodec::CreateEncoder_Params encoder_params,
::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> encoder_request)
override;
// TODO(dustingreen): Implement interface methods for:
// audio encoder
// video encoder
// (or combined)
private:
// We let CreateSelfOwned() deal with setting up the binding_ directly, which
// means the constructor doesn't need to stash the
// InterfaceRequest<CodecFactory>
LocalCodecFactory(async_dispatcher_t* fidl_dispatcher, thrd_t fidl_thread);
void CreateCommon(
::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> codec_request,
fuchsia::mediacodec::CodecType codec_type, std::string mime_type,
fit::function<void(codec_runner::CodecRunner* codec_runner)>
set_type_specific_params);
// Some combinations of mime type and codec lib need a wrapper to compensate
// for the OMX lib's behavior - to ensure that the overall Codec served by
// this process conforms to the Codec interface rules. For now this is
// primarily about the OMX AAC decoder lib not dealing with split ADTS
// headers, which the Codec interface requires.
struct CodecStrategy {
fuchsia::mediacodec::CodecType codec_type;
std::string_view mime_type;
std::string_view lib_filename;
fit::function<std::unique_ptr<codec_runner::CodecRunner>(
async_dispatcher_t* dispatcher, thrd_t fidl_thread,
const CodecStrategy& codec_strategy)>
create_runner;
};
// Appropriate for use with any mime_type where the raw OMX codec doesn't have
// any known open issues.
static std::unique_ptr<codec_runner::CodecRunner> CreateRawOmxRunner(
async_dispatcher_t* fidl_dispatcher, thrd_t fidl_thread,
const CodecStrategy& codec_strategy);
static std::unique_ptr<codec_runner::CodecRunner> CreateCodec(
async_dispatcher_t* fidl_dispatcher, thrd_t fidl_thread,
fuchsia::mediacodec::CodecType codec_type, std::string mime_type);
async_dispatcher_t* fidl_dispatcher_;
thrd_t fidl_thread_ = 0;
// The LocalCodecFactory instance is self-owned via binding_:
typedef fidl::Binding<CodecFactory, std::unique_ptr<LocalCodecFactory>>
BindingType;
std::unique_ptr<BindingType> binding_;
static CodecStrategy codec_strategies[];
};
} // namespace codec_factory
#endif // GARNET_BIN_MEDIA_CODECS_SW_OMX_CODEC_RUNNER_SW_OMX_LOCAL_CODEC_FACTORY_H_