diff --git a/garnet/bin/media/codec_factory/codec_factory_impl.cc b/garnet/bin/media/codec_factory/codec_factory_impl.cc index be64946fb8899a96390f77edf1e265459ee1f6a3..ee6e8507c30206e4959093e11aff4dfe64d206e9 100644 --- a/garnet/bin/media/codec_factory/codec_factory_impl.cc +++ b/garnet/bin/media/codec_factory/codec_factory_impl.cc @@ -67,7 +67,7 @@ void CodecFactoryImpl::OwnSelf(std::unique_ptr<CodecFactoryImpl> self) { void CodecFactoryImpl::CreateDecoder( fuchsia::mediacodec::CreateDecoder_Params params, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> decoder) { + ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> decoder) { // We don't have any need to bind the codec_request locally to this process. // Instead, we find where to delegate the request to. @@ -156,89 +156,7 @@ void CodecFactoryImpl::CreateDecoder( void CodecFactoryImpl::CreateDecoder2( fuchsia::mediacodec::CreateDecoder_Params params, ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> decoder) { - // We don't have any need to bind the codec_request locally to this process. - // Instead, we find where to delegate the request to. - - // First, try to find a hw-accelerated codec to satisfy the request. - const fuchsia::mediacodec::CodecFactoryPtr* factory = - app_->FindHwDecoder([¶ms](const fuchsia::mediacodec::CodecDescription& - hw_codec_description) -> bool { - // TODO(dustingreen): pay attention to the bool constraints of the - // params vs. the hw_codec_description bools. For the moment we just - // match the codec_type, mime_type. - constexpr fuchsia::mediacodec::CodecType codec_type = - fuchsia::mediacodec::CodecType::DECODER; - return (codec_type == hw_codec_description.codec_type) && - (params.input_details.mime_type == - hw_codec_description.mime_type); - }); - if (factory) { - // prefer HW-accelerated - (*factory)->CreateDecoder2(std::move(params), std::move(decoder)); - return; - } - - if (params.require_hw) { - FXL_LOG(WARNING) - << "require_hw, but no matching HW decoder factory found; closing"; - // TODO(dustingreen): Send epitaph when possible. - // ~decoder - return; - } - - fuchsia::sys::ComponentControllerPtr component_controller; - component::Services services; - fuchsia::sys::LaunchInfo launch_info{}; - std::string url; - if (params.input_details.mime_type == kFfmpegMimeType) { - url = kIsolateUrlFfmpeg; - } else { - url = kIsolateUrlOmx; - } - launch_info.url = url; - launch_info.directory_request = services.NewRequest(); - startup_context_->launcher()->CreateComponent( - std::move(launch_info), component_controller.NewRequest()); - component_controller.set_error_handler([url](zx_status_t status) { - FXL_LOG(ERROR) << "app_controller_ error connecting to CodecFactoryImpl of " - << url; - }); - fuchsia::mediacodec::CodecFactoryPtr factory_delegate; - services.ConnectToService( - factory_delegate.NewRequest().TakeChannel(), - // TODO(dustingreen): Might be helpful (for debugging maybe) to change - // this name to distinguish these delegate CodecFactory(s) from the main - // CodecFactory service. - CodecFactory::Name_); - - // Forward the request to the factory_delegate_ as-is. This avoids conversion - // to command-line parameters and back, and avoids creating a separate - // interface definition for the delegated call. The downside is potential - // confusion re. why we have several implementations of CodecFactory, but we - // can comment why. The presently-running implementation is the main - // implementation that clients use directly. - factory_delegate->CreateDecoder2(std::move(params), std::move(decoder)); - - // We don't want to be forced to keep component_controller around. When using - // an isolate, we trust that the ComponentController will kill the app if we - // crash before this point, as this process crashing will kill the server side - // of the component_controller. If we crash after this point, we trust that - // the isolate will receive the CreateDecoder() message sent just above, and - // will either exit on failure to create the Codec server-side, or will exit - // later when the client side of the Codec channel closes, or will exit later - // when the Codec fails asynchronously in whatever way. Essentially the Codec - // channel owns the isolate at this point, and we trust the isolate to exit - // when the Codec channel closes. - // - // TODO(dustingreen): Double-check the above description with someone who is - // likely to be more sure that this is plausible and reasonable for now. - component_controller->Detach(); - - // TODO(dustingreen): Determine if ~factory_delegate occurring immediately at - // the end of this method is completely ok - that the CreateAudioDecoder() - // message will be sent and delivered strictly in-order with respect to the - // ~factory_delegate channel closure. Seems like it plausibly _should_ be - // fine, but make sure. + CreateDecoder(std::move(params), std::move(decoder)); } void CodecFactoryImpl::CreateEncoder( diff --git a/garnet/bin/media/codec_factory/codec_factory_impl.h b/garnet/bin/media/codec_factory/codec_factory_impl.h index 1a608915ecc5d2143fe5d75e93e19a07284cfb40..d8c001a0a4736eb069b5418ab7e4c5350c265275 100644 --- a/garnet/bin/media/codec_factory/codec_factory_impl.h +++ b/garnet/bin/media/codec_factory/codec_factory_impl.h @@ -23,9 +23,9 @@ class CodecFactoryImpl : public fuchsia::mediacodec::CodecFactory { zx::channel request); // See .fidl file comments. - void CreateDecoder( - fuchsia::mediacodec::CreateDecoder_Params params, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> decoder) override; + void CreateDecoder(fuchsia::mediacodec::CreateDecoder_Params params, + ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> + decoder) override; void CreateDecoder2(fuchsia::mediacodec::CreateDecoder_Params params, ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> diff --git a/garnet/bin/media/codecs/sw/ffmpeg/local_single_codec_factory.cc b/garnet/bin/media/codecs/sw/ffmpeg/local_single_codec_factory.cc index 1b71ae95e80cf6a95106ec8b5edfbb9c80e71c3e..79f603db06ce6dc584778256d8801d2ec84bb9bc 100644 --- a/garnet/bin/media/codecs/sw/ffmpeg/local_single_codec_factory.cc +++ b/garnet/bin/media/codecs/sw/ffmpeg/local_single_codec_factory.cc @@ -25,7 +25,7 @@ LocalSingleCodecFactory::LocalSingleCodecFactory( void LocalSingleCodecFactory::CreateDecoder( fuchsia::mediacodec::CreateDecoder_Params decoder_params, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> decoder_request) { + ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> decoder_request) { codec_admission_control_->TryAddCodec( /*multi_instance=*/false, [this, decoder_params = std::move(decoder_params), @@ -56,30 +56,7 @@ void LocalSingleCodecFactory::CreateDecoder( void LocalSingleCodecFactory::CreateDecoder2( fuchsia::mediacodec::CreateDecoder_Params decoder_params, ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> decoder_request) { - codec_admission_control_->TryAddCodec( - /*multi_instance=*/false, - [this, decoder_params = std::move(decoder_params), - decoder_request = std::move(decoder_request)]( - std::unique_ptr<CodecAdmission> codec_admission) mutable { - if (!codec_admission) { - // ~decoder_request closes channel. - return; - } - - auto codec_impl = std::make_unique<CodecImpl>( - std::move(codec_admission), fidl_dispatcher_, thrd_current(), - std::make_unique<fuchsia::mediacodec::CreateDecoder_Params>( - std::move(decoder_params)), - std::move(decoder_request)); - - codec_impl->SetCoreCodecAdapter( - std::make_unique<CodecAdapterFfmpegDecoder>(codec_impl->lock(), - codec_impl.get())); - - // This hands off the codec impl to the creator of |this| and is - // expected to |~this|. - factory_done_callback_(std::move(codec_impl)); - }); + CreateDecoder(std::move(decoder_params), std::move(decoder_request)); } void LocalSingleCodecFactory::CreateEncoder( diff --git a/garnet/bin/media/codecs/sw/ffmpeg/local_single_codec_factory.h b/garnet/bin/media/codecs/sw/ffmpeg/local_single_codec_factory.h index 922cdaaace334be02fb23e65a0f421af6f698873..c8336970a506728d4122db8ac817ba41863e7ccb 100644 --- a/garnet/bin/media/codecs/sw/ffmpeg/local_single_codec_factory.h +++ b/garnet/bin/media/codecs/sw/ffmpeg/local_single_codec_factory.h @@ -25,7 +25,7 @@ class LocalSingleCodecFactory : public fuchsia::mediacodec::CodecFactory { virtual void CreateDecoder( fuchsia::mediacodec::CreateDecoder_Params decoder_params, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> decoder_request) + ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> decoder_request) override; virtual void CreateDecoder2( diff --git a/garnet/bin/media/codecs/sw/omx/codec_runner_sw_omx/local_codec_factory.cc b/garnet/bin/media/codecs/sw/omx/codec_runner_sw_omx/local_codec_factory.cc index 5c323140ed001c6e67c481ee6440c20662a83414..92113969e961d1cbd58c5336d988a40d8b517e74 100644 --- a/garnet/bin/media/codecs/sw/omx/codec_runner_sw_omx/local_codec_factory.cc +++ b/garnet/bin/media/codecs/sw/omx/codec_runner_sw_omx/local_codec_factory.cc @@ -59,12 +59,6 @@ LocalCodecFactory::LocalCodecFactory(async_dispatcher_t* fidl_dispatcher, // Decoder: void LocalCodecFactory::CreateDecoder( - fuchsia::mediacodec::CreateDecoder_Params decoder_params, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> decoder_request) { - // No longer supported, Omx users should switch to StreamProcessor. -} - -void LocalCodecFactory::CreateDecoder2( fuchsia::mediacodec::CreateDecoder_Params decoder_params, ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> decoder_request) { CreateCommon(std::move(decoder_request), @@ -76,6 +70,12 @@ void LocalCodecFactory::CreateDecoder2( }); } +void LocalCodecFactory::CreateDecoder2( + fuchsia::mediacodec::CreateDecoder_Params decoder_params, + ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> decoder_request) { + CreateDecoder(std::move(decoder_params), std::move(decoder_request)); +} + void LocalCodecFactory::CreateEncoder( fuchsia::mediacodec::CreateEncoder_Params encoder_params, ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> encoder_request) { diff --git a/garnet/bin/media/codecs/sw/omx/codec_runner_sw_omx/local_codec_factory.h b/garnet/bin/media/codecs/sw/omx/codec_runner_sw_omx/local_codec_factory.h index f1b3dd0ffdfc03889b6424c56ffab1968bc0cac4..515b137582518fad97335059e44ce5b1fec7c98c 100644 --- a/garnet/bin/media/codecs/sw/omx/codec_runner_sw_omx/local_codec_factory.h +++ b/garnet/bin/media/codecs/sw/omx/codec_runner_sw_omx/local_codec_factory.h @@ -59,7 +59,7 @@ class LocalCodecFactory : public fuchsia::mediacodec::CodecFactory { virtual void CreateDecoder( fuchsia::mediacodec::CreateDecoder_Params audio_decoder_params, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> audio_decoder) + ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> audio_decoder) override; virtual void CreateDecoder2( diff --git a/garnet/bin/mediaplayer/fidl/fidl_decoder_factory.cc b/garnet/bin/mediaplayer/fidl/fidl_decoder_factory.cc index ff228f0a57a16bdf10ecd2bff7de63c81feb48d1..2779b5236ffff5bdf80b615df880097692688ea5 100644 --- a/garnet/bin/mediaplayer/fidl/fidl_decoder_factory.cc +++ b/garnet/bin/mediaplayer/fidl/fidl_decoder_factory.cc @@ -45,7 +45,7 @@ void FidlDecoderFactory::CreateDecoder( decoder_params.require_hw = true; fuchsia::media::StreamProcessorPtr decoder; - codec_factory_->CreateDecoder2(std::move(decoder_params), + codec_factory_->CreateDecoder(std::move(decoder_params), decoder.NewRequest()); FXL_DCHECK(decoder); diff --git a/garnet/drivers/video/amlogic-decoder/local_codec_factory.cc b/garnet/drivers/video/amlogic-decoder/local_codec_factory.cc index 38746cdb76edb56664268090186f717058e20a2b..b97c9a92f8f9d0ab6960158c9d7f8c53e8b0b71b 100644 --- a/garnet/drivers/video/amlogic-decoder/local_codec_factory.cc +++ b/garnet/drivers/video/amlogic-decoder/local_codec_factory.cc @@ -173,7 +173,7 @@ void LocalCodecFactory::Bind(zx::channel server_endpoint) { void LocalCodecFactory::CreateDecoder( fuchsia::mediacodec::CreateDecoder_Params video_decoder_params, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> video_decoder) { + ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> video_decoder) { const CodecAdapterFactory* factory = nullptr; for (const CodecAdapterFactory& candidate_factory : kCodecFactories) { if (candidate_factory.description.mime_type == @@ -230,57 +230,7 @@ void LocalCodecFactory::CreateDecoder( void LocalCodecFactory::CreateDecoder2( fuchsia::mediacodec::CreateDecoder_Params video_decoder_params, ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> video_decoder) { - const CodecAdapterFactory* factory = nullptr; - for (const CodecAdapterFactory& candidate_factory : kCodecFactories) { - if (candidate_factory.description.mime_type == - video_decoder_params.input_details.mime_type) { - factory = &candidate_factory; - break; - } - } - if (!factory) { - // This shouldn't really happen since the main CodecFactory shouldn't be - // asking this LocalCodecFactory for a codec fitting a description that's - // not a description this factory previously delivered to the main - // CodecFactory via OnCodecList(). - // - // TODO(dustingreen): epitaph for video_decoder. - // - // ~video_decoder here will take care of closing the channel - return; - } - - // We also post to the same queue in the set_error_handler() lambda, so that - // we know the LocalCodecFactory will remain alive until after this lambda - // completes. - // - // The factory pointer remains valid for whole lifetime of this devhost - // process. - device_->codec_admission_control()->TryAddCodec( - factory->multi_instance, - [this, video_decoder_params = std::move(video_decoder_params), - video_decoder = std::move(video_decoder), - factory](std::unique_ptr<CodecAdmission> codec_admission) mutable { - if (!codec_admission) { - // We can't create another Codec presently. - // - // ~video_decoder will take care of closing the channel. - return; - } - - std::unique_ptr<CodecImpl> codec = std::make_unique<CodecImpl>( - std::move(codec_admission), - device_->driver()->shared_fidl_loop()->dispatcher(), - device_->driver()->shared_fidl_thread(), - std::make_unique<fuchsia::mediacodec::CreateDecoder_Params>( - std::move(video_decoder_params)), - std::move(video_decoder)); - - codec->SetCoreCodecAdapter( - factory->create(codec->lock(), codec.get(), device_)); - - device_->device_fidl()->BindCodecImpl(std::move(codec)); - }); + CreateDecoder(std::move(video_decoder_params), std::move(video_decoder)); } void LocalCodecFactory::CreateEncoder( diff --git a/garnet/drivers/video/amlogic-decoder/local_codec_factory.h b/garnet/drivers/video/amlogic-decoder/local_codec_factory.h index 4745d2c137b8ced65d860a85d5526ef69bd40e75..31b19d5f4809465a57d1ff4d76c38045a9246e98 100644 --- a/garnet/drivers/video/amlogic-decoder/local_codec_factory.h +++ b/garnet/drivers/video/amlogic-decoder/local_codec_factory.h @@ -71,7 +71,7 @@ class LocalCodecFactory : public fuchsia::mediacodec::CodecFactory { void CreateDecoder( fuchsia::mediacodec::CreateDecoder_Params video_decoder_params, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> video_decoder) + ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> video_decoder) override; void CreateDecoder2( diff --git a/garnet/drivers/video/amlogic-decoder/tests/manual/test_amlogic_codec_factory.cc b/garnet/drivers/video/amlogic-decoder/tests/manual/test_amlogic_codec_factory.cc index d5aadfcf5e7ba1363f6b7968d441428e57588e22..b39629716ae06e6140a3ebb749c54a8fbf986e0f 100644 --- a/garnet/drivers/video/amlogic-decoder/tests/manual/test_amlogic_codec_factory.cc +++ b/garnet/drivers/video/amlogic-decoder/tests/manual/test_amlogic_codec_factory.cc @@ -81,7 +81,7 @@ void test_factory() { .promise_separate_access_units_on_input = true, .require_hw = true, }]() mutable { - codec_factory->CreateDecoder2(std::move(params), std::move(request)); + codec_factory->CreateDecoder(std::move(params), std::move(request)); }); // Use FIDL thread to check that codec can communicate to the driver diff --git a/garnet/examples/media/use_media_decoder/use_aac_decoder.cc b/garnet/examples/media/use_media_decoder/use_aac_decoder.cc index a4a1af7981183c391446f591e702cc02b49359fc..9644a95a8fc387627d69267d78a4f6512b2fd418 100644 --- a/garnet/examples/media/use_media_decoder/use_aac_decoder.cc +++ b/garnet/examples/media/use_media_decoder/use_aac_decoder.cc @@ -250,7 +250,7 @@ void use_aac_decoder(async::Loop* main_loop, [&codec_factory, create_params = std::move(create_params), codec_client_request = codec_client.GetTheRequestOnce()]() mutable { VLOGF("before codec_factory->CreateDecoder() (async)\n"); - codec_factory->CreateDecoder2(std::move(create_params), + codec_factory->CreateDecoder(std::move(create_params), std::move(codec_client_request)); }); VLOGF("before codec_client.Start()...\n"); diff --git a/garnet/examples/media/use_media_decoder/use_video_decoder.cc b/garnet/examples/media/use_media_decoder/use_video_decoder.cc index f13e5f85c29b9bfbceeb36b969222ced5125b918..b91a0e8e66b6eb793f8d46a1b3482bcb75a94d45 100644 --- a/garnet/examples/media/use_media_decoder/use_video_decoder.cc +++ b/garnet/examples/media/use_media_decoder/use_video_decoder.cc @@ -289,8 +289,8 @@ static void use_video_decoder( main_loop->dispatcher(), [&codec_factory, codec_client_request = codec_client.GetTheRequestOnce(), mime_type]() mutable { - VLOGF("before codec_factory->CreateDecoder2() (async)\n"); - codec_factory->CreateDecoder2( + VLOGF("before codec_factory->CreateDecoder() (async)\n"); + codec_factory->CreateDecoder( fuchsia::mediacodec::CreateDecoder_Params{ .input_details.format_details_version_ordinal = 0, .input_details.mime_type = mime_type, diff --git a/garnet/lib/media/codec_impl/codec_impl.cc b/garnet/lib/media/codec_impl/codec_impl.cc index 2ac90b6a0d6a5c446fb2237872a92d88da72e0aa..d9168a71acab32aef79b5f00b70c7e748f4f4af8 100644 --- a/garnet/lib/media/codec_impl/codec_impl.cc +++ b/garnet/lib/media/codec_impl/codec_impl.cc @@ -139,32 +139,6 @@ uint32_t BufferCountFromPortSettings( } // namespace -// TODO(rjascani): Remove after soft transition complete. -CodecImpl::CodecImpl( - std::unique_ptr<CodecAdmission> codec_admission, - async_dispatcher_t* shared_fidl_dispatcher, thrd_t shared_fidl_thread, - std::unique_ptr<fuchsia::mediacodec::CreateDecoder_Params> decoder_params, - fidl::InterfaceRequest<fuchsia::mediacodec::Codec> codec_request) - // The parameters to CodecAdapter constructor here aren't important. - : CodecAdapter(lock_, this), - codec_admission_(std::move(codec_admission)), - shared_fidl_dispatcher_(shared_fidl_dispatcher), - shared_fidl_thread_(shared_fidl_thread), - // TODO(dustingreen): Maybe have another parameter for encoder params, or - // maybe separate constructor. - decoder_params_(std::move(decoder_params)), - binding_(this, std::move(codec_request)), - stream_control_loop_(&kAsyncLoopConfigNoAttachToThread) { - // For now, decoder_params is required. - // - // TODO(dustingreen): Make decoder_params || encoder_params required. - ZX_DEBUG_ASSERT(decoder_params_); - // This is the binding_'s error handler, not the owner_error_handler_ which - // is related but separate. - binding_.set_error_handler([this](zx_status_t status) { this->Unbind(); }); - initial_input_format_details_ = &decoder_params_->input_details; -} - CodecImpl::CodecImpl( std::unique_ptr<CodecAdmission> codec_admission, async_dispatcher_t* shared_fidl_dispatcher, thrd_t shared_fidl_thread, @@ -198,10 +172,11 @@ CodecImpl::CodecImpl( // maybe separate constructor. decoder_params_(std::move(decoder_params)), encoder_params_(std::move(encoder_params)), - // tmp_interface_request_(std::move(codec_request)), - binding_(this, std::move(codec_request)), + tmp_interface_request_(std::move(codec_request)), + binding_(this), stream_control_loop_(&kAsyncLoopConfigNoAttachToThread) { ZX_DEBUG_ASSERT(!!decoder_params_ ^ !!encoder_params_); + ZX_DEBUG_ASSERT(tmp_interface_request_); // This is the binding_'s error handler, not the owner_error_handler_ which // is related but separate. binding_.set_error_handler([this](zx_status_t status) { this->Unbind(); }); @@ -249,8 +224,7 @@ void CodecImpl::BindAsync(fit::closure error_handler) { // Up to once only. No re-use. ZX_DEBUG_ASSERT(!was_bind_async_called_); ZX_DEBUG_ASSERT(!binding_.is_bound()); - // TODO(rjascani): Uncomment after soft transition complete. - // ZX_DEBUG_ASSERT(tmp_interface_request_); + ZX_DEBUG_ASSERT(tmp_interface_request_); was_bind_async_called_ = true; zx_status_t start_thread_result = stream_control_loop_.StartThread( @@ -293,17 +267,13 @@ void CodecImpl::BindAsync(fit::closure error_handler) { // of that dispatching would tend to land in FailLocked(). The concurrency // is just worth keeping in mind for the rest of the current lambda is all. PostToSharedFidl([this] { - // TODO(rjascani): Uncomment after soft transition complete. - // zx_status_t bind_result = - // binding_.Bind(std::move(tmp_interface_request_), - // shared_fidl_dispatcher_); - zx_status_t bind_result = binding_.Bind(shared_fidl_dispatcher_); + zx_status_t bind_result = binding_.Bind(std::move(tmp_interface_request_), + shared_fidl_dispatcher_); if (bind_result != ZX_OK) { Fail("binding_.Bind() failed"); return; } - // TODO(rjascani): Uncomment after soft transition complete. - // ZX_DEBUG_ASSERT(!tmp_interface_request_); + ZX_DEBUG_ASSERT(!tmp_interface_request_); }); input_constraints_ = diff --git a/garnet/lib/media/codec_impl/include/lib/media/codec_impl/codec_impl.h b/garnet/lib/media/codec_impl/include/lib/media/codec_impl/codec_impl.h index 5e39fa950264d9b601dfd28b0acc0deee3f1ce0d..fb1fa74a427eec89754c642a6d01550e2c394e28 100644 --- a/garnet/lib/media/codec_impl/include/lib/media/codec_impl/codec_impl.h +++ b/garnet/lib/media/codec_impl/include/lib/media/codec_impl/codec_impl.h @@ -73,14 +73,6 @@ class CodecImpl : public fuchsia::media::StreamProcessor, std::unique_ptr<fuchsia::mediacodec::CreateEncoder_Params> encoder_params, fidl::InterfaceRequest<fuchsia::media::StreamProcessor> codec_request); - // TODO(rjascani): Remove after soft transition - CodecImpl(std::unique_ptr<CodecAdmission> codec_admission, - async_dispatcher_t* shared_fidl_dispatcher, - thrd_t shared_fidl_thread, - std::unique_ptr<fuchsia::mediacodec::CreateDecoder_Params> - video_decoder_params, - fidl::InterfaceRequest<fuchsia::mediacodec::Codec> codec_request); - ~CodecImpl(); // This is only intended for use by LocalCodecFactory in creating the @@ -248,99 +240,6 @@ class CodecImpl : public fuchsia::media::StreamProcessor, bool failure_seen_ = false; }; - // TODO(rjascani): Remove after soft transition complete. - // This looks scary because it is. The vtables of Codec/Codec_EventSender and - // StreamProcessor/StreamProcessor_EventSender *should* match. At least for - // the duration of this soft transition. - class BindingWrapper { - public: - // The Codec and StreamProcessor vtable entries must line up perfectly for - // this to work as intended. The intent is for Codec dispatching code to - // dispatch to StreamProcessor Stub methods, despite the lack of base class - // in common. This is temporary. - BindingWrapper( - CodecImpl* codec_impl, - ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> request) - : stream_interface_request_(std::move(request)), - codec_interface_request_(), - stream_binding_(codec_impl), - codec_binding_(reinterpret_cast<fuchsia::mediacodec::Codec*>( - static_cast<fuchsia::media::StreamProcessor*>(codec_impl))) { - ZX_DEBUG_ASSERT(stream_interface_request_); - } - - BindingWrapper(CodecImpl* codec_impl, - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> request) - : stream_interface_request_(), - codec_interface_request_(std::move(request)), - stream_binding_(codec_impl), - codec_binding_(reinterpret_cast<fuchsia::mediacodec::Codec*>( - static_cast<fuchsia::media::StreamProcessor*>(codec_impl))) { - ZX_DEBUG_ASSERT(codec_interface_request_); - } - - zx_status_t Bind(async_dispatcher_t* dispatcher = nullptr) { - ZX_DEBUG_ASSERT(!!stream_interface_request_ ^ !!codec_interface_request_); - if (stream_interface_request_.is_valid()) { - return stream_binding_.Bind(std::move(stream_interface_request_), - dispatcher); - } else { - return codec_binding_.Bind(std::move(codec_interface_request_), - dispatcher); - } - } - - ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> Unbind() { - if (stream_binding_.is_bound()) { - return stream_binding_.Unbind(); - } else { - return ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor>( - codec_binding_.Unbind().TakeChannel()); - } - } - - void set_error_handler(fit::function<void(zx_status_t)> error_handler) { - ZX_DEBUG_ASSERT(stream_interface_request_.is_valid() || - codec_interface_request_.is_valid()); - if (stream_interface_request_.is_valid()) { - stream_binding_.set_error_handler(std::move(error_handler)); - } else { - codec_binding_.set_error_handler(std::move(error_handler)); - } - } - - fuchsia::media::StreamProcessor_EventSender& events() { - if (stream_binding_.is_bound()) { - return stream_binding_.events(); - } else { - // Force calling to the Codec_EventSender vtable despite the caller - // believing it's calling StreamProcessor_EventSender. This is - // temporary. - return reinterpret_cast<fuchsia::media::StreamProcessor_EventSender&>( - static_cast<fuchsia::mediacodec::Codec_EventSender&>( - codec_binding_.events())); - } - } - - bool is_bound() const { - return stream_binding_.is_bound() || codec_binding_.is_bound(); - } - - private: - ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> - stream_interface_request_; - ::fidl::InterfaceRequest<fuchsia::mediacodec::Codec> - codec_interface_request_; - - ::fidl::Binding<fuchsia::media::StreamProcessor, CodecImpl*> - stream_binding_; - // When used, this binding will dispatch per Codec interface message - // ordinals, but the actual dispatch is forced to call via the vtable of a - // StreamProcessor instead of a Codec. This only works because the vtable - // entries line up perfectly. This is temporary. - ::fidl::Binding<fuchsia::mediacodec::Codec> codec_binding_; - }; - // While we list this first in the member variables to hint that this gets // destructed last, the actual mechanism of destruction of the CodecAdmission // is via posting to the shared_fidl_thread(), because if we add more stuff in @@ -433,17 +332,16 @@ class CodecImpl : public fuchsia::media::StreamProcessor, // Held here temporarily until DeviceFidl is ready to handle errors so we can // bind. - /* fidl::InterfaceRequest<fuchsia::media::StreamProcessor> */ - /* tmp_interface_request_; */ + fidl::InterfaceRequest<fuchsia::media::StreamProcessor> + tmp_interface_request_; // This binding doesn't channel-own this CodecImpl. The DeviceFidl owns all // the CodecImpl(s). The DeviceFidl will SetErrorHandler() such that its // ownership drops if the channel fails. The CodecImpl takes care of cleaning // itself up before calling the DeviceFidl's error handler, so that CodecImpl // is ready for destruction by the time DeviceFidl's error handler is called. - /* fidl::Binding<fuchsia::media::StreamProcessor, CodecImpl*> binding_; */ + fidl::Binding<fuchsia::media::StreamProcessor, CodecImpl*> binding_; - BindingWrapper binding_; // This is the zx::channel we get indirectly from binding_.Unbind() (we only // need the zx::channel part). We delay closing the Codec zx::channel until // after removing the concurrency tally in ~CodecAdmission, so that a Codec diff --git a/garnet/public/fidl/fuchsia.mediacodec/BUILD.gn b/garnet/public/fidl/fuchsia.mediacodec/BUILD.gn index 4b564bb3bad5e7155e62156e4c71e088e0d337b2..8e1d0a9fe4f97107e6086c8c0b8f2414254fd79a 100644 --- a/garnet/public/fidl/fuchsia.mediacodec/BUILD.gn +++ b/garnet/public/fidl/fuchsia.mediacodec/BUILD.gn @@ -8,8 +8,6 @@ fidl("fuchsia.mediacodec") { sdk_category = "partner" sources = [ - "codec.fidl", - "codec_common.fidl", "codec_factory.fidl", ] diff --git a/garnet/public/fidl/fuchsia.mediacodec/codec.fidl b/garnet/public/fidl/fuchsia.mediacodec/codec.fidl deleted file mode 100644 index 7afaf8d843822f19fbb8200ff74a651f9a40f806..0000000000000000000000000000000000000000 --- a/garnet/public/fidl/fuchsia.mediacodec/codec.fidl +++ /dev/null @@ -1,1315 +0,0 @@ -// 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. - -library fuchsia.mediacodec; - -// See codec.md for detailed interface documentation. The comments here are a -// summary only. Client implementers should see codec.md for more detail on any -// message that doesn't seem sufficiently-described here. Codec server -// implementers should probably read codec.md before implementing. - -// Overview of operation: -// -// 1. Create -// * create via CodecFactory - see CodecFactory -// 2. Get input constraints -// * OnInputConstraints() - sent unsolicited by codec shortly after codec -// creation. -// 3. Provide input buffers -// * SetInputBufferSettings() / AddInputBuffer() -// 4. Deliver input data -// * QueueInputPacket() + OnFreeInputPacket(), for as long as it takes, -// possibly working through all input packets repeatedly before... -// 5. Get output constraints and format -// * OnOutputConfig() - may be delivered as early as before -// OnInputConstraints() by some codecs, but a client must tolerate as late -// as after substantial input data has been delivered including lots of -// input packet recycling via OnFreeInputPacket(). -// * This message can arrive more than once before the first output data. -// 6. Provide output buffers -// * SetOutputBufferSettings() / AddOutputBuffer() -// 7. Data flows, with optional EndOfStream -// * OnOutputPacket() / RecycleOutputPacket() / QueueInputPacket() / -// OnFreeInputPacket() / QueueInputEndOfStream() / OnOutputEndOfStream() -// -// It's possible to re-use a Codec instance for another stream, and doing so -// can sometimes skip over re-allocation of buffers. This can be a useful thing -// to do for cases like seeking to a new location - at the Codec interface that -// can look like switching to a new stream. - -// CodecBufferConstraints -// -// This struct helps ensure that packet count and buffer space are sufficient -// to avoid major problems. For example, a video decoder needs sufficient -// video frame buffers to hold all potential reference frames concurrently + -// one more video buffer to decode into. Else, the whole video decode pipe can -// easily deadlock. -// -// The secondary purpose of this struct is to help ensure that packet count and -// buffer space are sufficient to achieve reasonably performant operation. -// -// There are separate instances of this struct for codec input and codec output. -struct CodecBufferConstraints { - // This is a version number the server sets on the constraints to allow the - // server to determine when the client has caught up with the latest - // constraints sent by the server. The server won't emit output data until - // the client has configured output settings and buffers with a - // buffer_constraints_version_ordinal >= the latest - // buffer_constraints_version_ordinal that had - // buffer_constraints_action_required true. See - // buffer_constraints_action_required comments for more. - // - // A buffer_constraints_version_ordinal of 0 is not permitted, to simplify - // initial state handling. Other than 0, both odd and even version ordinals - // are allowed (in contrast to the stream_lifetime_ordinal, neither the - // client nor server ever has a reason to consider the latest version to be - // stale, so there would be no benefit to disallowing even values). - uint64 buffer_constraints_version_ordinal; - - // default_settings - // - // These settings are "default" settings, not "recommended" settings. - // - // These "default" settings can be passed to SetInputBufferSettings() / - // SetOutputBufferSettings() as-is without modification, but a client doing - // that must still obey the semantics of packet_count_for_client, despite the - // codec server not having any way to really know the proper setting for - // that field. - // - // For CodecBufferConstraints fields whose names end in "recommended", the - // default_settings will have the corresponding setting field set to that - // recommended value. - // - // The codec promises that these default settings as-is (except for - // buffer_lifetime_ordinal) are guaranteed to - // satisfy the constraints indicated by the other fields of - // CodecBufferConstraints. While client-side checking that these - // settings are within the constraints is likely unnecessary in the client, - // the client should still check that these values are within client-side - // reasonable-ness bounds before using these values, to avoid letting a codec - // server cause problems for the client. - // - // This structure will always have single_buffer_mode false. See - // single_buffer_mode_allowed for whether single_buffer_mode true is allowed. - // - // The client must set the buffer_lifetime_ordinal field to a proper value - // before sending back to the server. The 0 initially in this field will be - // rejected by the server if sent back as-is. See comments on - // CodecPortBufferSettings.buffer_lifetime_ordinal. - CodecPortBufferSettings default_settings; - - // For uncompressed video, separate and complete frames, each in its own - // separate buffer (buffer-per-packet mode), is always a requirement. - - // per_packet_buffer_bytes.*: - // - // These per-packet buffer bytes constraints apply to both buffer-per-packet - // mode and single-buffer mode (see single_buffer_mode). If - // buffer-per-packet mode, the constraints apply to each buffer separately. - // If single-buffer mode, the constraints need to be multiplied by the number - // of packets to determine the constraints on the single buffer. - - // per_packet_buffer_bytes_min: - // - // If a client is using buffer per packet mode, each buffer must be at least - // this large. If a client is using single-buffer mode, the one buffer must - // be at least per_packet_buffer_bytes_min * packet_count_for_codec_min in - // size. - uint32 per_packet_buffer_bytes_min; - // Must be >= per_packet_buffer_bytes_min. Delivering more than - // this per input packet might not perform any better, and in fact might - // perform worse. - uint32 per_packet_buffer_bytes_recommended; - // Must be >= per_packet_buffer_bytes_recommended. Can be 0xFFFFFFFF if there - // is no explicitly-enforced limit. - uint32 per_packet_buffer_bytes_max; - - // Minimum number of packet_count_for_codec. - // - // Re. input and output: - // - // This is a strict min for packet_count_for_codec, but a client can use more - // packets overall if the client wants to, by using a larger value for - // packet_count_for_codec and/or using a non-zero packets_for_client. A good - // reason to do the former would be if the client might tend to deliver a few - // not-very-full buffers occasionally - or to have a few extra packets within - // which to satisfy codec_input_bytes_min. A good reason to do the latter - // would be if a client needs to hold onto some packets for any "extra" - // duration. - // - // If a client specifies a larger packet_count_for_codec value than - // packet_count_for_codec_min, a server is permitted (but not encouraged) to - // not make progress until packet_count_for_codec are with the server, - // not merely packet_count_for_codec_min. - // - // For decoder input and audio encoder input: The packet_count_for_codec_min - // may or may not contain enough data to allow the codec to make progress - // without copying into an internal side buffer. If there isn't enough data - // delivered in packet_count_for_codec_min packets to permit progress, the - // codec must copy into its own side buffer internally to make progress. - // - // If a client intends to use extra packets for client-side purposes, the - // client should specify the extra packets in packets_for_client instead of - // packet_count_for_codec, but packet_count_for_codec must still be >= - // packet_count_for_codec_min. - // - // See codec.md for more on packet_count_for_codec_min. - uint32 packet_count_for_codec_min; - - // This must be at least packet_count_for_codec_min and at most - // packet_count_for_codec_recommended_max. - // - // This value is likely to be used as-is by most clients, so if having one - // additional packet is a big performance win in a large percentage of - // scenarios, it can be good for the server to include that additional packet - // in this value. - uint32 packet_count_for_codec_recommended; - - // This can be the same as packet_count_for_codec_max or can be lower. - // Values above this value and <= packet_count_for_codec_max are not - // recommended by the codec, but should still work given sufficient resources - // available to both the client and the codec. - uint32 packet_count_for_codec_recommended_max; - - // This can be 0xFFFFFFFF if there's no codec-enforced max, but codecs are - // encouraged to set a large but still plausibly-workable max, and clients - // are encouraged to request a number of packets that isn't excessively large - // for the client's scenario. - uint32 packet_count_for_codec_max; - - // Normally this would be an implicit 0, but for now we have a min so we can - // force the total number of packets to be a specific number that we know - // works for the moment. - uint32 packet_count_for_client_min; - - // packet_count_for_client_max - // - // The client must set packet_count_for_client to be <= - // packet_count_for_client_max. - // - // This value must be at least 1. This can be 0xFFFFFFFF if there's no - // codec-enforced max. Clients are encouraged to request a number of - // packets that isn't excessively large for the client's scenario. - uint32 packet_count_for_client_max; - - // single_buffer_mode_allowed false allows a codec that's not required to - // support single-buffer mode for a given input or output the ability to - // decline to support single-buffer mode on that input/output. - // - // All encoder output, regardless of audio or video: server support for - // single-buffer mode is optional. Please see codec.md for all the rules - // regarding single-buffer mode on output before using single-buffer mode on - // an output. - // - // Audio decoder output: server support for single-buffer mode is required. - // - // Video decoder output: There is little reason for a video decoder to - // support single-buffer mode on output. Nearly all video decoders will set - // this to false for their output. - // - // All decoder inputs: Servers must support single-buffer mode on input. The - // client is responsible for managing the input buffer space such that - // filling an input packet doesn't over-write any portion of an input packet - // already in flight to the codec. - // - // Encoder inputs: Server support for single-buffer mode on encoder input is - // optional. This is more often useful for audio than for video. - // - // Support for buffer-per-packet mode is always required on both input and - // output, regardless of codec type. - bool single_buffer_mode_allowed; - - // If true, the buffers need to be physically contiguous pages, such as can be - // allocated using zx_vmo_create_contiguous(). - bool is_physically_contiguous_required; - // VERY TEMPORARY HACK / KLUDGE - we want the BufferAllocator (or one of the - // participant drivers that needs physically contiguous buffers) to call - // zx_vmo_create_contiguous(), definitely not the Codec client, but until the - // BufferAllocator can be reached from a driver, this is to grant the client - // special powers it really shouldn't have, very temporarily until - // BufferAllocator is hooked up properly at which point this can be removed. - // Strictly speaking we could reverse which end allocates buffers in the Codec - // interface to avoid this hack even before BufferAllocator, but the overall - // path seems shorter if we jump directly from this to using BufferAllocator. - handle? very_temp_kludge_bti_handle; -}; - -// CodecOutputConfig -// -// The codec-controlled output configuration, including both -// CodecBufferConstraints for the output and CodecFormatDetails for the output. -// -// TODO(dustingreen): Need a better name for this struct, but still short -// hopefully. It's stuff the codec gets to control, not the client. It's -// different than output buffer settings, which the client does get to control -// to some extent. It's different than any configurable output settings the -// client might specify for output of an encoder. -struct CodecOutputConfig { - // A client which always immediately re-configures output buffers on receipt - // of OnOutputConfig() with buffer_constraints_action_required true can safely - // ignore this field. - // - // A client is permitted to ignore an OnOutputConfig() message even with - // buffer_constraints_action_required true if the client knows the server has - // already been told to discard the remainder of the stream with the same - // stream_lifetime_ordinal or if this stream_lifetime_ordinal field is set to - // 0. The server is required to re-send needed output config via - // OnOutputConfig() with new stream_lifetime_ordinal and - // buffer_constraints_action_required true, if the most recent completed - // server-side output config isn't what the server wants/needs yet for the - // new stream. - uint64 stream_lifetime_ordinal; - - // buffer_constraints_action_required - // - // When the buffer constraints are delivered, they indicate whether action is - // required. A false value here permits delivery of constraints which are - // fresher without forcing a buffer reconfiguration. If this is false, a - // client cannot assume that it's safe to immediately re-configure output - // buffers. If this is true, the client can assume it's safe to immediately - // configure output buffers once. - // - // A client is permitted to ignore buffer constraint versions which have - // buffer_constraints_action_required false. The server is not permitted to - // change buffer_constraints_action_required from false to true for the same - // buffer_constraints_version_ordinal. - // - // For each configuration, a client must use new buffers, never buffers that - // were previously used for anything else, and never buffers previously used - // for any other Codec purposes. This rule exists for multiple good reasons, - // relevant to both mid-stream changes, and changes on stream boundaries. - // A client should just use new buffers each time. - // - // When this is true, the server has already de-refed as many low-level - // output buffers as the server can while still performing efficient - // transition to the new buffers and will de-ref the rest asap. A Sync() is - // not necessary to achieve non-overlap of resource usage to the extent - // efficiently permitted by the formats involved. - // - // If buffer_constraints_action_required is true, the server _must_ not - // deliver more output data until after output buffers have been configured - // (or re-configured) by the client. - // - // See codec.md for more on buffer_constraints_action_required. - bool buffer_constraints_action_required; - CodecBufferConstraints buffer_constraints; - - // format_details - // - // It's up to the client to determine if a change in - // format_details.format_details_version_ordinal implies any client action is - // required, based on particular fields in format_details vs. any old value. - // The server guarantees that if the format has changed, then - // format_details.format_details_version_ordinal will change, but a change to - // format_details.format_details_version_ordinal does not guarantee that the - // format details actually changed. Servers are strongly encouraged to not - // change format_details.format_details_version_ordinal other than before the - // first output data of a stream unless there is a real mid-stream format - // change in the stream. Unnecessary mid-stream format changes can cause - // simpler clients that have no need to handle mid-stream format changes to - // just close the channel. Format changes before the first output data of a - // stream are not "mid-stream" in this context - those can be useful for - // stream format detection / setup reasons. - // - // Note that in case output buffers don't really need to be re-configured - // despite a format change, a server is encouraged, but not required, to - // set buffer_constraints_action_required false on the message that conveys - // the new format details. Simpler servers may just treat the whole output - // situation as one big thing and demand output buffer reconfiguration on any - // change in the output situation. - // - // A client may or may not actually handle a new buffer_constraints with - // buffer_constraints_action_required false, but the client should always - // track the latest format_details. - // - // An updated format_details is ordered with respect to emitted output - // packets, and applies to all subsequent packets until the next - // format_details with larger version_ordinal. A simple client that does not - // intend to handle mid-stream format changes should still keep track of the - // most recently received format_details until the first output packet - // arrives, then lock down the format details, handle those format details, - // and verify that any format_details.format_details_version_ordinal received - // from the server is the same as the locked-down format_details, until the - // client is done with the stream. Even such a simple client must tolerate - // format_details.format_details_version_ordinal changing multiple times - // before the start of data output from a stream (any stream - the first - // stream or a subsequent stream). This allows a codec to request that - // output buffers and output format be configured speculatively, and for the - // output config to be optionally adjusted by the server before the first - // data output from a stream after the server knows everything it needs to - // know to fully establish the initial output format details. This - // simplifies codec server implementation, and allows a clever codec server - // to guess it's output config for lower latency before any input data, while - // still being able to fix the output config (including format details) if - // the guess turns out to be wrong. - // - // Whether the format_details.format_details_version_ordinal will actually - // change mid-stream is a per-codec and per-stream detail that is not - // specified in comments here, and in most cases also depends on whether the - // format changes on the input to the codec. Probably it'll be fairly common - // for a client to use a format which technically supports mid-stream format - // change, but the client happens to know that none of the streams the client - // intends to process will ever have a mid-stream format change. - CodecFormatDetails format_details; -}; - -// Default values for input and output -// CodecBufferConstraints.default_settings.packet_count_for_codec. -// -// These are defined as "const" in FIDL to avoid all server implementations -// needing to separately define their own values, and these should be -// reasonable as default values, but strictly speaking this is not intended to -// promise that this value won't change from build to build. If a client cares -// about a specific number, the client should separately define what that -// number is and ensure that CodecPortBufferSettings.packet_count_for_client is -// at least large enough. -// -// In contrast to packet_count_for_client, the packet_count_for_codec is much -// more codec-specific, so this file has no numbers for that - each codec will -// set those as appropriate for the specific codec. -// -// These are not "recommended" values, only "default" values, in the sense that -// the codec doesn't really know what the correct setting for these values is -// for a given client, and if the default is not appropriate for a client, -// large problems could result such as deadlock. See the comments on -// packet_count_for_client. -// -// Despite these defaults, every client should ideally care about the -// packet_count_for_client setting and should ensure that the setting is at -// least large enough to cover the number of packets the client might ever need -// to camp on for any non-transient duration concurrently. The defaults are -// only intended to be plausible for some clients, not all clients. -// -// One for the client to be filling and one in transit. -const uint32 kDefaultInputPacketCountForClient = 2; -// One for the client to be rendering, and one in transit. -const uint32 kDefaultOutputPacketCountForClient = 2; - -// For input, this is the default on a fairly arbitrary basis. -// -// TODO(dustingreen): Do we want the default for audio encoding to be -// single_buffer_mode true instead? If so, we may split this up by audio/video -// encoder/decoder. -const bool kDefaultInputIsSingleBufferMode = false; -const bool kDefaultOutputIsSingleBufferMode = false; - -// CodecPortBufferSettings -// -// See relevant corresponding constraints in CodecBufferConstraints. The -// settings must satisfy the constraints. -// -// The client informs the codec of these settings and then separately informs -// the codec of each buffer. -// -// TODO(dustingreen): Rename from CodecPortBufferSettings to CodecBufferSettings -// in a separate CL (after some other stuff is out of the way first). -struct CodecPortBufferSettings { - // buffer_lifetime_ordinal - // - // The containing message starts a new buffer_lifetime_ordinal. - // - // There is a separate buffer_lifetime_ordinal for input vs. output. - // - // Re-use of the same value is not allowed. Values must be odd. Values must - // only increase (increasing by more than 2 is permitted). - // - // A buffer_lifetime_ordinal lifetime starts at SetInputBufferSettings() or - // SetOutputBufferSettings(), and ends at the earlier of - // CloseCurrentStream() with release_input_buffers/release_output_buffers set - // or SetOutputBufferSettings() with new buffer_lifetime_ordinal in the case - // of mid-stream output config change. - // - // See codec.md for more on buffer_lifetime_ordinal. - uint64 buffer_lifetime_ordinal; - - // buffer_constraints_version_ordinal - // - // This value indicates which version of constraints the client is/was aware - // of so far. - // - // For input, this must always be 0 because constraints don't change for - // input (settings can change, but there's no settings vs current constraints - // synchronization issue on input). - // - // For output, this allows the server to know when the client is sufficiently - // caught up before the server will generate any more output. - // - // When there is no active stream, a client is permitted to re-configure - // buffers again using the same buffer_constraints_version_ordinal. - // - // See codec.md for more on buffer_constraints_version_ordinal. - uint64 buffer_constraints_version_ordinal; - - // The total packet count is split into two pieces to disambiguate how many - // packets are allocated for the client to hold onto for whatever reason, vs. - // how many packets are allocated for the server to hold onto for whatever - // reason. - // - // Extra packets to provide slack for performance reasons can be in either - // category, but typically packet_count_for_codec_recommended will already - // include any performance-relevant slack for the server's benefit. - - // packet_count_for_codec - // - // How many packets the client is allocating for the codec server's use. - // This must be >= CodecBufferConstraints.packet_count_for_codec_min. If - // constraints change such that this would no longer be true, the server will - // send an OnOutputConfig() event. - // - // The codec server is allowed to demand that all of packet_count_for_codec - // become free before making further progress, even if - // packet_count_for_codec is > packet_count_for_codec_min. - // - // A reasonable value for this is - // CodecBufferConstraints.packet_count_for_codec_recommended. - // - // See codec.md for more on packet_count_for_codec. - uint32 packet_count_for_codec; - - // packet_count_for_client - // - // This must be at least 1. The server will close the channel if this is 0. - // - // How many packets the client is allocating for the client's use. The - // client may hold onto this many packets for arbitrarily-long duration - // without handing these packets to the codec, and despite doing so, the - // codec will continue to make progress and function normally without getting - // stuck. The client holding onto additional packets transiently is ok, but - // the client needs to hand those additional packets back to the codec - // eventually if the client wants the codec to make further progress. - // - // In addition to this value needing to include at least as many packets as - // the client ever intends to concurrently camp on indefinitely, any extra - // slack to benefit client-side performance should also be included here. - // - // A typical value for this could be at least 2, but it depends strongly on - // client implementation and overall client buffering goals. It is up to the - // client to determine how many packets are needed in this category by any - // parts of the overall system that will be holding onto packets for any - // reason. Those parts of the system should have a documented and possibly - // queryable defined value to help determine this number. Setting this value - // lower than it actually needs to be can result in the codec not making - // progress as it sits waiting for packets, with the client unable to recycle - // any more packets to the codec. That situation can be difficult to - // diagnose, while excessively-large values here are wasteful, so care is - // warranted to set this value properly. - uint32 packet_count_for_client; - - // per_packet_buffer_bytes - // - // In buffer-per-packet mode, we require that each buffer have usable bytes - // equal to per_packet_buffer_bytes. Use of differently-sized low-level - // buffers is possible, but the size of the portion used via the Codec - // interface per CodecBuffer must be the same for all the buffers. - // - // In single-buffer mode, we require the portion of the low-level buffer used - // via the Codec interface to be size (packet_count_for_codec + - // packet_count_for_client) * per_packet_buffer_bytes. - // - // TODO(dustingreen): determine if we need to relax these restrictions a bit - // for convenience when using gralloc video buffers. - uint32 per_packet_buffer_bytes; - - // If true, there is only one buffer with index 0 which all packets - // implicitly refer to. If false, the packet_index and buffer_index are 1:1, - // and each packet refers to its corresponding buffer. - // - // While it's possible to set up single_buffer_mode false with each buffer - // referring to the same underlying VMO, single_buffer_mode true is more - // efficient for that case since only one mapping is created. - bool single_buffer_mode; -}; - -// CodecBuffer -// -// The CodecBuffer struct represents a pre-configured buffer. -// -// Both input and output uses CodecBuffer(s), but the two sets of buffers are -// separate. -// -// The client uses SetInputBufferSettings() + AddInputBuffer() * N to inform -// the codec about all the input buffers. -// -// The client uses SetOutputBufferSettings() + AddOutputBuffer() * N to inform -// the codec about all the output buffers. -// -// When single_buffer_mode is true, there is only buffer_index 0 shared by all -// CodecPacket(s) of the relevant input or output. When single_buffer_mode is -// false, the buffer_index equals the packet_index. -struct CodecBuffer { - // When using AddOutputBuffer()/AddInputBuffer(), this must match the - // buffer_lifetime_ordinal of the most recent - // SetOutputBufferSettings()/SetInputBufferSettings(). - uint64 buffer_lifetime_ordinal; - - // Buffers must be added via AddOutputBuffer() / AddInputBuffer() in order by - // buffer_index, and the buffer_index is always equal to 0 or equal to the - // packet_index (depending on single_buffer_mode true or false), but it's - // still nice to have CodecBuffer include the buffer_index if only for easier - // debugging. - uint32 buffer_index; - - // For each new buffer_lifetime_ordinal, a client must use new low-level - // buffers. This rule exists for multiple very good reasons, and is relevant - // to mid-stream changes, changes on stream boundaries, and both input and - // output buffers. A new buffer_lifetime_ordinal needs new low-level - // buffers, not just new CodecBuffer(s). If you find yourself copying - // compressed input data into new low-level input buffers solely due to this - // rule, consider asking the source of the data for the ability to directly - // fill new VMOs. The rule exists for good reasons, even for input buffers. - // - // The previous paragraph does not prohibit carving up VMOs into sub-pieces - // and using different sub-pieces as different CodecBuffer(s), with some VMOs - // used for more than one CodecBuffer and possibly others used for only one - // CodecBuffer. While this is permitted and enables some optimizations, it's - // not expected to be particularly common. - // - // See codec.md for more on CodecBufferData, and more on why we never re-use - // the same low-level buffers for different buffer_lifetime_ordinal(s). - CodecBufferData data; -}; - -// CodecBufferData -// -// For the moment, a VMO per buffer is the only type of buffer. -// -// This is extremely likely to change significantly when adding gralloc stuff, -// but the idea with this union is to have a struct per logical way of storing -// the data. Any multi-domain storage within a gralloc buffer will likely be -// only indirectly represented here. -union CodecBufferData { - CodecBufferDataVmo vmo; - - // TODO(dustingreen): add the gralloc way -}; - -// CodecBufferDataVmo -// -// Details for a buffer backed by a VMO. -struct CodecBufferDataVmo { - // The same VMO can be used by more than one CodecBuffer (only of the same - // buffer_lifetime_ordinal), but each vmo_handle must be a separate handle. - handle<vmo> vmo_handle; - - // Offset within the VMO of the first usable byte. Must be < the VMO's size - // in bytes. - uint64 vmo_usable_start; - - // VMO-relative offset that's one past the last usable byte. This can point - // one byte beyond the end of the VMO if desired. In other words, this can - // be equal to the VMO's size, to indicate that the last byte of the VMO is - // usable (and possibly many byte before that, depending on - // vmo_usable_start). - uint64 vmo_usable_size; -}; - -// CodecPacketHeader -// -// When referring to a free packet, we use CodecPacketHeader alone instead of -// CodecPacket, since while a packet is free it doesn't really have meaningful -// offset or length etc. -// -// A populated CodecPacket also has a CodecPacketHeader. -struct CodecPacketHeader { - // This is which buffer configuration lifetime this header is referring to. - // - // A packet_index is only really meaningful with respect to a particular - // buffer_lifetime_ordinal. - // - // See CodecPortBufferSettings.buffer_lifetime_ordinal. - // - // For QueueInputPacket(), a server receiving a buffer_lifetime_ordinal that - // isn't the current input buffer_lifetime_ordinal will close the channel. - // - // For OnFreeInputPacket() and RecycleOutputPacket(), the receiver (client or - // server) must ignore a message with stale buffer_lifetime_ordinal. - uint64 buffer_lifetime_ordinal; - - // The overall set of packet_index values is densely packed from 0..count-1 - // for input and output separately. They can be queued in any order. - // - // Both the client and server should validate the packet_index against the - // known bound and disconnect if it's out of bounds. - // - // When running in buffer-per-packet mode, the packet_index is also the - // buffer index. When running in single-buffer mode, the buffer index is - // always 0 referring to the single buffer. - // - // The packet_index values don't imply anything about order of use of - // packets. The client should not expect the ordering to remain the same over - // time - the codec is free to hold on to an input or output packet for a - // while during which other packet_index values may be used multiple times. - // - // For a given properly-functioning Codec instance, packet_index values will - // be unique among concurrently-outstanding packets. Servers should validate - // that a client isn't double-using a packet and clients should validate as - // necessary to avoid undefined or unexpected client behavior. - uint32 packet_index; -}; - -// CodecPacket -// -// A CodecPacket represents a chunk of input or output data to or from a codec. -// -// codec output: -// While the CodecPacket is outstanding with the client via OnOutputPacket(), -// the codec will avoid modifying the referenced output data. After the client -// calls RecycleOutputPacket(packet_index), the codec is notified that the -// client is again ok with the referenced data changing. -// -// codec input: -// The client initially has all packet_index(es) available to fill, and later -// gets packet_index(s) that are again ready to fill via OnFreeInputPacket(). -// The client must not modify the referenced data in between QueueInputPacket() -// and OnFreeInputPacket(). -struct CodecPacket { - CodecPacketHeader header; - - // Which buffer this packet refers to. For single-buffer mode this will - // always be 0, but for multi-buffer mode, a given in-flight interval of a - // packet can refer to any buffer. The packet has an associated buffer only - // while the packet is in-flight, not while the packet is free. - // - // The default value makes accidental inappropriate use of index 0 less - // likely (will tend to complain in an obvious way if not filled out instead - // of a non-obvious data corruption when decoding buffer 0 repeatedly instead - // of the correct buffers). - uint32 buffer_index = 0x80000000; - - // stream_lifetime_ordinal - // - // The value 1 is the lowest permitted value after codec creation. Values - // sent by the client must be odd. Values must only increase. - // - // A stream_lifetime_ordinal represents the lifetime of a stream. All - // messages that are specific to a stream have the stream_lifetime_ordinal - // value and the value is the same for all messages relating to a given - // stream. - // - // See codec.md for more on stream_lifetime_ordinal. - uint64 stream_lifetime_ordinal; - - // start_offset and valid_length_bytes - // - // Which part of the relevant buffer is this packet using. These are valid - // for input data that's in-flight to the codec, and are valid for output data - // from the codec. - // - // For compressed formats and uncompressed audio, the data in - // [start_offset, start_offset + valid_length_bytes) is the contiguously valid - // data referred to by this packet. - // - // For uncompressed video frames, CodecFormatDetails is the primary means of - // determining which bytes are relevant. The offsets in CodecFormatDetails - // are relative to the start_offset here. The valid_length_bytes must be - // large enough to include the full last line of pixel data, including the - // full line stride of the last line (not just the width in pixels of the - // last line). - // - // Despite these being filled out, some uncompressed video buffers are of - // types that are not readable by the CPU. These fields being here don't - // imply there's any way for the CPU to read an uncompressed frame. - // - // TODO(dustingreen): Do we have any reason to require that these be filled - // out for opaque uncompressed video frames that the CPU can't read? In that - // case do we want to require them just so they can be potentially passed on - // to a HW renderer in case the HW renderer has any use for them? Or more - // likely, it may just be that these tend to refer to the whole size of an - // uncompressed buffer, with format_details taking care of specifying which - // bytes are actually relevant. - uint32 start_offset; - - // valid_length_bytes - // - // This must be > 0. - // - // The semantics for valid data per packet vary depending on data type as - // follows. - // - // uncompressed video - A video frame can't be split across packets. Each - // packet is one video frame. - // - // uncompressed audio - Regardless of float or int, linear or uLaw, or number - // of channels, a packet must contain an non-negative number of complete - // audio frames, where a single audio frame consists of data for all the - // channels for the same single point in time. Any codec-specific internal - // details re. lower rate sampling for LFE channel or the like should be - // hidden by the Codec server implementation. - // - // compressed data input - A packet must contain at least one byte of data. - // See also codec_input_bytes_min. Splitting AUs at arbitrary byte - // boundaries is permitted, including at boundaries that are in AU headers. - // - // compressed data output - The codec is not required to fully fill each - // output packet's buffer. - uint32 valid_length_bytes; - - // This value is not strictly speaking a timestamp. It is an arbitrary - // unsigned 64-bit number that, under some circumstances, will be passed by a - // codec unmodified from an input packet to the exactly-corresponding output - // packet. - // - // For timestamp_ish values to be propagated from input to output the - // following conditions must be true: - // * promise_separate_access_units_on_input must be true - // * has_timestamp_ish must be true for a given input packet, to have that - // timestamp_ish value (potentially) propagate through to an output - // * the Codec instance itself decides (async) that the input packet - // generates an output packet - if a given input never generates an output - // packet then the timestamp_ish value on the input will never show up on - // any output packet - depending on the characteristics of the input and - // output formats, and whether a decoder is willing to join mid-stream, etc - // this can be more or less likely to occur, but clients should be written - // to accommodate timestamp_ish values that are fed on input but never show - // up on output, at least to a reasonable degree (not crashing, not - // treating as an error). - // - // See codec.md for more on timestamp_ish. - bool has_timestamp_ish; - uint64 timestamp_ish; - - // start_access_unit - // - // If promise_separate_access_units_on_input (TODO(dustingreen): or any - // similar mode for output) is true, this bool must be set appropriately - // depending on whether byte 0 _is_ or _is not_ the start of an access unit. - // The client is required to know, and required to set this boolean properly. - // The server is allowed to infer that when this boolean is false, byte 0 is - // the first byte of a continuation of a previously-started AU. (The byte at - // start_offset is "byte 0".) - // - // If promise_separate_access_units_on_input is false, this boolean is - // ignored. - bool start_access_unit; - - // known_end_access_unit - // - // A client is never required to set this boolean to true. - // - // If promise_separate_access_units_on_input is true, for input data, this - // boolean must be false if the last byte of this packet is not the last byte - // of an AU, and this boolean _may_ be true if the last byte of this packet - // is the last byte of an AU. A client delivering one AU at a time that's - // interested in the lowest possible latency via the decoder should set this - // boolean to true when it can be set to true. - // - // If promise_separate_access_units_on_input is false, this boolean is - // ignored. - bool known_end_access_unit; -}; - -// Codec -// -// The Codec interface exists to anchor the configuration of input and output -// buffers, and depending on Codec server hosting strategy, the Codec interface -// can, in some configurations, be 1:1 with a codec isolate (process), -// especially when using SW codecs. The Codec can be used to process up to one -// stream at a time. -// -// Descriptions of actions taken by methods of this interface and the states of -// things are given as if the methods are synchronously executed by the codec -// server, but in reality, as is typical of FIDL interfaces, the message -// processing is async. The states described are to be read as the state from -// the client's point of view unless otherwise stated. Events coming back from -// the server are of course delivered async, and a client that processes more -// than one stream per Codec instance needs to care whether a given event is -// from the current stream vs. some older soon-to-be-gone stream. -// -// The Sync() method's main purpose is to enable the client to robustly prevent -// having both old and new buffers allocated in the system at the same time, -// since media buffers can be significantly large, depending. The Sync() method -// achieves this by only delivering it's response when all previous calls to -// the Codec interface have actually taken effect in the StreamControl ordering -// domain. Sync() can also be used to wait for the codec server to catch up if -// there's a possibility that a client might otherwise get too far ahead of the -// Codec server, by for example requesting creation of a large number of -// streams in a row. It can also be used during debugging to ensure that a -// codec server hasn't gotten stuck. Calling Sync() is entirely optional and -// never required for correctness - only potentially required to de-overlap -// resource usage. -// -// Semi-trusted Codec server - SW decoders run in an isolate (with very few -// capabilities) just in case the decoding SW has a vulnerability which could -// be used to take over the Codec server. Clients of the codec interface using -// decoders and processing streams of separate security contexts, to a greater -// extent than some other interfaces, need to protect themselves against -// invalid server behavior, such as double-free of a packet_index and any other -// invalid server behavior. Having fed in compressed data of one security -// context, don't place too much trust in a single Codec instance to not mix -// data among any buffers that Codec server has ever been told about. Instead, -// create separate Codec instances for use by security-separate client-side -// contexts. While the picture for HW-based decoders looks somewhat different -// and is out of scope of this paragraph, the client should always use separate -// Codec instances for security-separate client-side contexts. -interface Codec { - // EnableOnStreamFailed() - // - // Permit the server to use OnStreamFailed() instead of the server just - // closing the whole Codec channel on stream failure. - // - // If the server hasn't seen this message by the time a stream fails, the - // server will close the Codec channel instead of sending OnStreamFailed(). - EnableOnStreamFailed(); - - // OnStreamFailed() - // - // The stream has failed, but the Codec instance is still usable for a new - // stream. - // - // This message is only ever sent by the server if the client previously sent - // EnableOnStreamFailed(). If the client didn't send EnableOnStreamFailed() - // then the server closes the Codec channel instead. - // - // Codec server implementations are encouraged to handle stream errors (and - // ideally to also report them via error_ bools of OnOutputPacket() and - // OnOutputEndOfStream()) without failing the whole stream, but if a codec - // server is unable to do that, but still can cleanly contain the failure to - // the stream, the codec server can (assuming EnableOnStreamFailed() was - // called) use OnStreamFailed() to indicate the stream failure to the client - // without closing the Codec channel. - // - // An ideal Codec server handles problems with input data without sending - // this message, but sending this message is preferred vs. closing the server - // end of the Codec channel if the Codec server can 100% reliably contain the - // stream failure to the stream, without any adverse impact to any later - // stream. - // - // No further messages will arrive from the server regarding the failed - // stream. This includes any OnOutputEndOfStream() that the client would - // have otherwise expected. - // - // TODO(dustingreen): Add at least an error_message string and _maybe_ a - // zx_status_t, though that might tend to encourage mis-use of zx_status_t so - // maybe just error_message for quicker debugging on the client side. Also - // plumb from CodecAdapterH264 and similar. - -> OnStreamFailed(uint64 stream_lifetime_ordinal); - - // OnInputConstraints() - // - // The server sends this shortly after Codec creation to indicate input - // buffer constraints. The "min" and "max" input constraints don't change - // for the life of the Codec. - // - // The "max" values for buffer size and count are large enough to support the - // most demanding format the server supports on input. The "recommended" - // values should be workable for use with the input CodecFormatDetails - // conveyed during Codec creation. The "recommended" values are not - // necessarily suitable if the client uses QueueInputFormatDetails() to - // change the input format. In that case it's up to the client to determine - // suitable values, either by creating a new Codec instance instead, or - // knowing suitable values outside the scope of this protocol. - // - // See comments on CodecBufferConstraints. - // - // This message is guaranteed to be sent unsolicited to the Codec client - // during or shortly after Codec creation. Clients should not depend on this - // being the very first message to arrive at the client. OnOutputConfig() - // may be sent first by some codecs that already know their initial output - // config without any input data, to encourage (but not strictly require) the - // client to configure output buffers before feeding the first input, to - // avoid a wasteful OnOutputConfig() being generated for that first stream if - // the client has started configuring output but isn't done configuring - // output before the client sends the first input data for the first stream. - // A client is free to ignore OnOutputConfig() with a stale - // stream_lifetime_ordinal, but handling OnOutputConfig() with - // stream_lifetime_ordinal 0 (if any are sent) can help reduce latency to - // first output. See OnOutputConfig() for more details. - // - // The "min" and "max" input constraints are guaranteed not to change for a - // given Codec instance. The "recommended" values may effectively change - // when the server processes QueueInputFormatDetails(). There is not any way - // in the protocol short of creating a new Codec instance for the client to - // get those new "recommended" values. - // - // TODO(dustingreen): Maybe provide a way for the client to get updated - // "recommended" values for input, maybe only on request rather than via this - // event, to keep things simpler for simpler clients. Maybe separate the - // recommendations from the constraints. - -> OnInputConstraints(CodecBufferConstraints input_constraints); - - // SetInputBufferSettings() and AddInputBuffer() - // - // Configuring input buffers consists of calling SetInputBufferSettings() - // followed by a number of calls to AddInputBuffer() equal to the number of - // buffers set via SetInputBufferSettings(). In buffer-per-packet mode, this - // is the same as the number of packets. In single-buffer mode, this is 1. - // - // After OnInputConstraints(), the client uses these two methods to set up - // input buffers and packets. - // - // Configuring input buffers is required before QueueInputPacket(). - // - // The client can also re-set-up input buffers any time there is no current - // stream. The client need not wait until all previously-set-up input - // buffers are with the client via OnFreeInputPacket(). The old - // buffer_lifetime_ordinal just ends. See codec.md for more info on "buffer - // lifetime". - // - // The recommended way to de-overlap resource usage (when/if the client wants - // to) is to send CloseCurrentStream() with release_input_buffers true then - // send Sync() and wait for its response before allocating any new buffers. - // How to cause other parts of the system to release their references on - // low-level buffers is outside the scope of this interface. - // - // This call ends any previous buffer_lifetime_ordinal, and starts a new one. - SetInputBufferSettings(CodecPortBufferSettings input_settings); - - // The client is required to add all the input buffers before sending any - // message that starts a new stream else the codec will close the Codec - // channel. - // - // When the last buffer is added with this message, all the input packets - // effectively jump from non-existent to free with the client. The Codec - // will not generate an OnFreeInputPacket() for each new input packet. The - // client can immediately start sending QueueInputPacket() after sending the - // last AddInputBuffer(). - AddInputBuffer(CodecBuffer buffer); - - // OnOutputConfig() - // - // This event informs the client of new output config. The server will send - // at least one of these messages before the first output packet of a stream, - // but that message might not have buffer_constraints_action_required true. - // - // If buffer_constraints_action_required is true and the - // stream_lifetime_ordinal matches the current stream, the client must react - // by configuring or re-configuring output buffers. - // - // Some clients may prefer not to support mid-stream output config changes, - // but even those clients are required to process OnOutputConfig() messages - // up to the first output packet of each stream, as OnOutputConfig() is used - // for stream format detection as well as for potential mid-stream output - // config changes. - // - // For more on OnOutputConfig(), see cocec.md. - -> OnOutputConfig(CodecOutputConfig output_config); - - // SetOutputBufferSettings() and AddOutputBuffer() - // - // These are not permitted until after the first OnOutputConfig(). - // - // Roughly speaking, these messages are sent in response to OnOutputConfig() - // with buffer_constraints_action_required true. - // - // Configuring output buffers consists of calling SetOutputBufferSettings() - // followed by a number of calls to AddOutputBuffer() equal to the number of - // buffers set via SetOutputBufferSettings(). In buffer-per-packet mode, this - // is the same as the number of packets. In single-buffer mode, this is 1. - // - // Configuring output buffers is _required_ after OnOutputConfig() is - // received by the client with buffer_constraints_action_required true and - // stream_lifetime_ordinal equal to the client's current - // stream_lifetime_ordinal (even if there is an active stream), and is - // _permitted_ any time there is no current stream. - // - // For more on SetOutputBufferSettings() and AddOutputBuffer(), see codec.md. - SetOutputBufferSettings(CodecPortBufferSettings output_settings); - AddOutputBuffer(CodecBuffer buffer); - - // FlushEndOfStreamAndCloseStream() - // - // This message is optional. - // - // This message is only valid after QueueInputEndOfStream() for this stream. - // The stream_lifetime_ordinal input parameter must match the - // stream_lifetime_ordinal of the QueueInputEndOfStream(), else the server - // will close the channel. - // - // A client can use this message to flush through (not discard) the last - // input data of a stream so that the codec server generates corresponding - // output data for all the input data before the server moves on to the next - // stream, without forcing the client to wait for OnOutputEndOfStream() - // before queueing data of another stream. - // - // The difference between QueueInputEndOfStream() and - // FlushEndOfStreamAndCloseStream(): QueueInputEndOfStream() is a promise - // from the client that there will not be any more input data for the stream - // (and this info is needed by some codecs for the codec to ever emit the very - // last output data). The QueueInputEndOfStream() having been sent doesn't - // prevent the client from later completely discarding the rest of the - // current stream by closing the current stream (with or without a stream - // switch). In contrast, FlushEndOfStreamAndCloseStream() is a request from - // the client that all the previously-queued input data be processed - // including the logical "EndOfStream" showing up as OnOutputEndOfStream() - // (in success case) before moving on to any newer stream - this essentially - // changes the close-stream handling from discard to flush-through for this - // stream only. - // - // A client using this message can start providing input data for a new - // stream without that causing discard of old stream data. That's the purpose - // of this message - to allow a client to flush through (not discard) the old - // stream's last data (instead of the default when closing or switching - // streams which is discard). - // - // Because the old stream is not done processing yet and the old stream's - // data is not being discarded, the client must be prepared to continue to - // process OnOutputConfig() messages until the stream_lifetime_ordinal is - // done. The client will know the stream_lifetime_ordinal is done when - // OnOutputEndOfStream(), OnStreamFailed(), or the Codec channel closes. - // - // For more on FlushEndOfStreamAndCloseStream(), see codec.md. - FlushEndOfStreamAndCloseStream(uint64 stream_lifetime_ordinal); - - // CloseCurrentStream() - // - // This "closes" the current stream, leaving no current stream. In addition, - // this message can optionally release input buffers or output buffers. - // - // If there has never been any active stream, the stream_lifetime_ordinal must - // be zero or the server will close the channel. If there has been an active - // stream, the stream_lifetime_ordinal must be the most recent active stream - // whether that stream is still active or not. Else the server will close the - // channel. - // - // Multiple of this message without any new active stream in between is not - // to be considered an error, which allows a client to use this message to - // close the current stream to stop wasting processing power on a stream the - // user no longer cares about, then later decide that buffers should be - // released and send this message again with release_input_buffers and/or - // release_output_buffers true to get the buffers released, if the client is - // interested in trying to avoid overlap in resource usage between old - // buffers and new buffers (not all clients are). - // - // See also Sync(). - // - // For more on CloseCurrentStream(), see codec.md. - CloseCurrentStream( - uint64 stream_lifetime_ordinal, - bool release_input_buffers, - bool release_output_buffers); - - // Sync() -> () - // - // On completion, all previous Codec calls have done what they're going to do - // server-side, _except_ for processing of data queued using - // QueueInputPacket(). - // - // The main purpose of this call is to enable the client to wait until - // CloseCurrentStream() with release_input_buffers and/or - // release_output_buffers set to true to take effect, before the client - // allocates new buffers and re-sets-up input and/or output buffers. This - // de-overlapping of resource usage can be worthwhile for media buffers which - // can consume resource types whose overall pools aren't necessarily vast in - // comparison to resources consumed. Especially if a client is reconfiguring - // buffers multiple times. - // - // Note that Sync() prior to allocating new media buffers is not alone - // sufficient to achieve non-overlap of media buffer resource usage system - // wide, but it can be a useful part of achieving that. - // - // The Sync() transits the Output ordering domain and the StreamControl - // ordering domain, but not the InputData ordering domain. For more on - // ordering domains see codec.md. - // - // This request can be used to avoid hitting kMaxInFlightStreams which is - // presently 10. A client that stays <= 8 in-flight streams will comfortably - // stay under the limit of 10. While the protocol permits repeated - // SetInputBufferSettings() and the like, a client that spams the channel - // can expect that the channel will just close if the server or the channel - // itself gets too far behind. - Sync() -> (); - - // OnOutputPacket() - // - // This is how the codec emits an output packet to the codec client. - // - // Order is significant. - // - // The client should eventually call RecycleOutputPacket() (possibly after - // switching streams multiple times), unless the buffer_lifetime_ordinal has - // moved on. A stream change doesn't change which packets are busy with - // the client vs. free with the server. See "packet lifetime" in codec.md for - // more. - // - // The relevant buffer is buffer 0 if running in single-buffer mode, or the - // buffer index is the same as packet_index if running in buffer-per-packet - // mode. - // - // For low-level buffer types that support it, a Codec is free to emit an - // output packet before the low-level buffer actually has any usable data in - // the buffer, with the mechanism for signalling the presence of data - // separate from the OnOutputPacket() message. For such low-level buffer - // types, downstream consumers of data from the emitted packet must - // participate in the low-level buffer signalling mechanism to know when it's - // safe to consume the data. This is most likely to be relevant when using a - // video decoder and gralloc-style buffers. - // - // The error_ bool(s) allow (but do not require) a Codec server to report - // errors that happen during an AU or between AUs. - // - // The scope of error_detected_before starts at the end of the last delivered - // output packet on this stream, or the start of stream if there were no - // previous output packets on this stream. The scope ends at the start of - // the output_packet. - // - // The error_detected_before bool is separate so that discontinuities can be - // indicated separately from whether the current packet is damaged. - // - // The scope of error_detected_during is from the start to the end of this - // output_packet. - -> OnOutputPacket( - CodecPacket output_packet, - bool error_detected_before, - bool error_detected_during); - - // RecycleOutputPacket() - // - // After the client is done with an output packet, the client needs to tell - // the codec that the output packet can be re-used for more output, via this - // method. - // - // It's not permitted to recycle an output packet that's already free with the - // codec server. It's permitted but discouraged for a client to recycle an - // output packet that has been deallocated by an explicit or implicit output - // buffer de-configuration(). See buffer_lifetime_ordinal for more on that. - // A server must ignore any such stale RecycleOutputPacket() calls. - // - // For more on RecycleOutputPacket(), see codec.md. - RecycleOutputPacket(CodecPacketHeader available_output_packet); - - // OnOutputEndOfStream() - // - // After QueueInputEndOfStream() is sent by the Codec client, within a - // reasonable duration the corresponding OnOutputEndOfStream() will be sent by - // the Codec server. Similar to QueueInputEndOfStream(), - // OnOutputEndOfStream() is sent a maximum of once per stream. - // - // No more stream data for this stream will be sent after this message. All - // input data for this stream was processed. - // - // While a Codec client is not required to QueueInputEndOfStream() (unless - // the client wants to use FlushEndOfStreamAndCloseStream()), if a Codec - // server receives QueueInputEndOfStream(), and the client hasn't closed the - // stream, the Codec server must generate a corresponding - // OnOutputEndOfStream() if nothing went wrong, or must send - // OnStreamFailed(), or must close the server end of the Codec channel. An - // ideal Codec server would handle and report stream errors via the error_ - // flags and complete stream processing without sending OnStreamFailed(), but - // in any case, the above-listed options are the only ways that an - // OnOutputEndOfStream() won't happen after QueueInputEndOfStream(). - // - // There will be no more OnOutputPacket() or OnOutputConfig() messages for - // this stream_lifetime_ordinal after this message - if a server doesn't - // follow this rule, a client should close the Codec channel. - // - // The error_detected_before bool has the same semantics as the - // error_detected_before bool in OnOutputPacket(). - -> OnOutputEndOfStream( - uint64 stream_lifetime_ordinal, - bool error_detected_before); - - // - // Stream specific messages: - // - - // QueueInputFormatDetails() - // - // If the input format details are still the same as specified during Codec - // creation, this message is unnecessary and does not need to be sent. - // - // If the stream doesn't exist yet, this message creates the stream. - // - // All servers must permit QueueInputFormatDetails() at the start of a stream - // without failing, as long as the new format is supported by the Codec - // instance. Technically this allows for a server to only support the exact - // input format set during Codec creation, and that is by design. A client - // that tries to switch formats and gets a Codec channel failure should try - // again one more time with a fresh Codec instance created with CodecFactory - // using the new input format during creation, before giving up. - // - // These format details override the format details - // specified during codec creation for this stream only. The next stream will - // default back to the format details set during codec creation. - // - // For now, QueueInputFormatDetails() sent mid-stream will fail the Codec - // channel. Clients shouldn't do this for now. - // - // This message is permitted at the start of the first stream (just like at - // the start of any stream). The format specified need not match what was - // specified during codec creation, but if it doesn't match, the Codec channel - // might close as described above. - QueueInputFormatDetails( - uint64 stream_lifetime_ordinal, CodecFormatDetails format_details); - - // QueueInputPacket() - // - // This message queues input data to the codec for processing. - // - // If the stream doesn't exist yet, this message creates the new stream. - // - // The client is required to be willing to send QueueInputPacket() prior to - // the server's first OnOutputConfig(), and is permitted to start a new stream - // without output buffers configured yet. - // - // The client must continue to deliver input data via this message even if the - // codec has not yet generated the first OnOutputConfig(), and even if the - // Codec is generating OnFreeInputPacket() for previously-queued input - // packets. The input data must continue as long as there are free packets - // to be assured that the server will ever generate the first - // OnOutputConfig(). - // - // For more on QueueInputPacket(), see codec.md. - QueueInputPacket(CodecPacket packet); - - // OnFreeInputPacket() - // - // The server sends this message when the codec is done consuming this packet - // and the packet can be re-filled by the client. - // - // This is not sent for all packets when a new buffer_lifetime_ordinal starts - // as in that case all the packets are initially free with the client. - // - // See comments on QueueInputBuffer() and "packet lifetime" in codec.md for - // for description of buffer lifetime and packet lifetime. - // - // After receiving the available input buffer via this event, the codec - // client can call later call QueueInputBuffer with appropriate offset and - // length set. - // - // TODO(dustingreen): At the moment, there is no guarantee re. the order of - // these messages with respect to the order of QueueInputPacket(), but at - // least for decoders, it might be worthwhile to require that servers preserve - // the order vs. QueueInputPacket(), to make it easier to feed input from a - // ring buffer or similar. For audio encoders it might still make sense. For - // video encoders probably not. - -> OnFreeInputPacket(CodecPacketHeader free_input_packet); - - // Inform the server that all QueueInputPacket() messages for this stream - // have been sent. - // - // If the stream isn't closed first (by the client, or by OnStreamFailed(), or - // Codec channel closing), there will later be a corresponding - // OnOutputEndOfStream(). - // - // The corresponding OnOutputEndOfStream() message will be generated only if - // the server finishes processing the stream before the server sees the - // client close the stream (such as by starting a new stream). A way to - // force the server to finish the stream before closing is to use - // FlushEndOfStreamAndCloseStream() after QueueInputEndOfStream() before any - // new stream. Another way to force the server to finish the stream before - // closing is to wait for the OnOutputEndOfStream() before taking any action - // that closes the stream. - // - // In addition to serving as an "EndOfStream" marker to make it obvious - // client-side when all input data has been processed, if a client never - // sends QueueInputEndOfStream(), no amount of waiting will necessarily - // result in all input data getting processed through to the output. Some - // codecs have some internally-delayed data which only gets pushed through by - // additional input data _or_ by this EndOfStream marker. In that sense, - // this message can be viewed as a flush-through at InputData domain level, - // but the flush-through only takes effect if the codec even gets that far - // before the stream is just closed at StreamControl domain level. This - // message is not alone sufficient to act as an overall flush-through at - // StreamControl level. For that, send this message first and then send - // FlushEndOfStreamAndCloseStream() (at which point it becomes possible to - // queue input data for a new stream without causing discard of this older - // stream's data), or wait for the OnOutputEndOfStream() before closing the - // current stream. - // - // If a client sends QueueInputPacket(), QueueInputFormatDetails(), - // QueueInputEndOfStream() for this stream after the first - // QueueInputEndOfStream() for this stream, a server should close the Codec - // channel. - QueueInputEndOfStream(uint64 stream_lifetime_ordinal); -}; diff --git a/garnet/public/fidl/fuchsia.mediacodec/codec_common.fidl b/garnet/public/fidl/fuchsia.mediacodec/codec_common.fidl deleted file mode 100644 index 1db3b115c95831f328bc34fc306a153bdfebd5cb..0000000000000000000000000000000000000000 --- a/garnet/public/fidl/fuchsia.mediacodec/codec_common.fidl +++ /dev/null @@ -1,513 +0,0 @@ -// 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. - -library fuchsia.mediacodec; - -// Value -// -// Generic "value" for use within generic "Parameter" struct. -union Value { - bool bool_value; - uint64 uint64_value; - int64 int64_value; - string string_value; - // Prefer using codec_oob_bytes instead. - vector<uint8> bytes_value; -}; - -// Parameter -// -// Generic parameter. -// -// We want to minimize use of this generic "Parameter" structure by natively -// defining as many codec-specific parameter semantics as we can. -// -// TODO: When possible, describe the very limited scenarios in which it would -// still be reasonable to use a generic Parameter. -struct Parameter { - // Some indication of the scope of applicability of this Parameter. - string scope; - // Specific name of this parameter, without the scope prefix. - string name; - // The particular value of this parameter. - Value value; -}; - -// CodecFormatDetails -// -// The purpose of CodecFormatDetails is to fill in additional details not -// conveyed via other means. -// -// TODO(dustingreen): Where at all possible, definitions for the concepts -// within CodecFormatDetails should go in media_types.fidl or another location -// that's widely shared. Maybe some encoder settings could remain -// codec-specific. -// -// For decoders input, the format details tend to be fairly sparse, since most -// compressed formats tend to be mostly self-describing. -// -// For decoder output and encoder input, the format details need to include all -// the out-of-band information regarding the uncompressed data, which tends not -// to be self-describing. -// -// For encoder output, we also include in CodecFormatDetails some additional -// encoding parameters which are needed to configure the encoder. These are not -// really needed by any downstream decoder under most circumstances, but these -// encoder config settings are legitimate optional format details, so we use -// the same overall structure, but name them "Encoder" to make it more obvious -// that these are mostly relevant to the encoder. A downstream consumer could -// potentially benefit from knowing these settings, but most won't look at them. -// -// Settings that are completely redundant with the data in the format itself -// should not be in a required field here. Some encoder parameters may also be -// represented in codec_oob_bytes on the output of an encoder - a downstream -// consumer can assume the codec_oob_bytes are correct and not check for whether -// encoder settings are present or consistent. -// -// With some exceptions made for encoder settings on output of an encoder, this -// stuff should be limited to things we need to know to properly process the -// data which we can't already determine from the data itself, and which isn't -// already covered by a format's defined OOB binary config blob, which is -// conveyed in codec_oob_bytes. -// -// TODO(dustingreen): Consider whether to split encoder settings into a -// separate struct - the main counter-argument would be if a consumer -// immediately downstream of an encoder may have good reason to know encoder -// settings to help process the data. For example, the nominal bit-rate. - -// Compressed formats tend to be much more self-describing than uncompressed -// formats. (The "self" in "self-describing" includes the codec_oob_bytes.) -// -// Most decoders can have CodecFormatDetails.domain null. - -// AudioCompressedFormat -// -// Format details relevant to compressed audio, mostly for encoder settings. -// -// Unless otherwise specified in a comment on a field in this structure, -// CodecFormatDetails.domain is null for a decoder. A sub-structure whose name -// ends in "Encoder" is for encoder output settings. -// -// TODO(dustingreen): Consider whether splitting encoder settings out separately -// would be better. -union AudioCompressedFormat { - // For an aac encoder, this field has settings the encoder needs which are - // specific to AAC encoding. - AudioCompressedFormatAacEncoder aac; -}; - -enum AudioBitrateMode { - // Used mainly when a client is configuring an encoder's output format. May - // also be present in an OnOutputConfig() message from an encoder, but should - // not be relied upon to be present by any consumer downstream of an encoder. - UNSPECIFIED = 0; - CBR = 1; - VBR = 2; -}; - -// AudioCompressedFormatAacEncoder -// -// Encoder settings for an AAC encoder. -struct AudioCompressedFormatAacEncoder { - // In SetOutputConfig(): - // - // If zero, an encoder should generate 256 kbps, and a consumer should not - // assume any particular bitrate. - // - // If not zero, the encoder should not exceed this bitrate. In CBR the - // encoder should use the highest available bitrate that doesn't exceed this - // value, or if there is no such bitrate, the lowest available bitrate. In - // VBR, the encoder should stay at or below this bitrate. - // - // In VBR it's left up to the encoder to choose a reasonable ratio between - // max bits per second and min bits per second, with the aim in VBR being - // constant perceived quality. - // - // In OnOutputConfig(): - // - // In CBR, the nominal bits per second. In VBR, the nominal max bits per - // second. - uint32 bits_per_second; - - // In SetOutputConfig(): - // - // If UNSPECIFIED, up to the encoder. If CBR or VBR, a hint to the encoder - // to use that mode. - // - // In OnOutputConfig(): - // - // Actual mode being used. UNSPECIFIED means the source is not specifying - // which mode. - AudioBitrateMode bitrate_mode; - - // TODO(dustingreen): AAC profile settings. -}; - -// AudioPcmMode -// -// TODO(dustingreen): Keep or discard any non-linear formats for purposes of the -// Codec interface? -enum AudioPcmMode { - // 16 bit signed int linear or 32 bit float linear, for now - // 1-N channels ok, with "A.B" channels designated as A+B channel_count - the - // channel map is separately specified. So 5.1 becomes channel_count 6. - LINEAR = 0; - // G.711 8 bit format-defined waveform semantics - // 1 channel - ALAW = 1; - // G.711 8 bit format-defined waveform semantics - // 1 channel - MULAW = 2; -}; - -// AudioChannelId -// -// Used in specifying which audio channel is for which speaker location / type. -// -// TODO(dustingreen): Do we need more channel IDs than this? -// -// TODO(dustingreen): Check with mpuryear@ re. naming consistency for "S" vs. -// "R" as we move these to a common definition. Also the ordering of LS/RS vs. -// LR/RR - probably LR/RR being first would make more sense re. how channels -// get added incrementally, but changing the order would no longer match -// Android's ordering. -enum AudioChannelId { - SKIP = 0; // unused channel - LF = 1; // left front - RF = 2; // right front - CF = 3; // center front - LS = 4; // left surround - RS = 5; // right surround - LFE = 6; // low frequency effects - CS = 7; // back surround - LR = 8; // left rear - RR = 9; // right rear - // This is the last explicitly-defined value + 1. This name will be - // re-defined in future if we add more defined channel IDs above. - END_DEFINED = 10; - // This is where format-specific (or ad-hoc) channel ID values should go, to - // avoid colliding with any additional values allocated above. The values - // here are not guaranteed to avoid collision across different formats. - EXTENDED_CHANNEL_ID_BASE = 0x6f000000; - // Extended channel IDs should be <= Max. - MAX = 0x7fffffff; -}; - -// PcmFormat -// -// PCM audio format details. -// -// TODO(dustingreen): Discuss with mpuryear@ re. where definitions for these -// details go and make sure the common details can specify at least this much. -struct PcmFormat { - // Implicit details: - // * For bits_per_sample > 8, host-endian is implied. - // * At least for now, for channel_count >= 2, interleaved layout is - // implied. - - AudioPcmMode pcm_mode; - - // bits_per_sample - // - // A "sample" is for a single channel. - // - // For example, CD quality is 16. See PcmMode comments, as the mode - // constrains this value. - uint32 bits_per_sample; - - // frames_per_second - // - // A "frame" is one datapoint (one "sample") for each channel. Each channel - // is sampled this many times per second. For example, CD quality is 44100. - uint32 frames_per_second; - - // channel_map - // - // channel_map.size() is the channel count. See PcmMode comments, as some - // modes constrain the channel count to 1. - // - // Values from AudioChannelId should be used if they are suitable. - // - // If a channel has no suitable AudioChannelId, an ad-hoc value can be used in - // a range starting from AudioChannel_ExtendedChannelIdBase. - vector<AudioChannelId>:16 channel_map; - - // TODO(dustingreen): Add unsigned 8 bit, float 32 bit, maybe others. FWIW, - // AOSP appears to support signed 16 bit, unsigned 8 bit, and float 32 bit - // under "Pcm", AFAICT based on OMX_NUMERICALDATATYPE and ACodec.cpp code. -}; - -// AudioUncompressedFormat -// -// Uncompressed audio format details. -union AudioUncompressedFormat { - PcmFormat pcm; -}; - -// AudioFormat -// -// Audio format details. -union AudioFormat { - AudioCompressedFormat compressed; - AudioUncompressedFormat uncompressed; -}; - -// VideoCompressedFormat -// -// Compressed video format details. -// -// Mostly encoder settings will go under here. -// -// If a compressed video format is missing any fields here other than encoder -// settings, it's because it's a good format and is already self-describing -// given the mime_type + format-defined codec_oob_bytes as appropriate + -// in-band data. -union VideoCompressedFormat { - // TODO(dustingreen): Any compressed video formats that aren't sufficiently - // self-describing to select and create a Codec instance to decode it? - - // TODO(turnage): Add fields for scaling, target bitrate, etc. - - // TODO(dustingreen): temp field to make the compiler happy until we have at - // least one real field. - uint32 temp_field_todo_remove; -}; - -// VideoUncompressedFormatSpecificDetails -// -// Extended format-specific uncompressed video format details. -// -// TODO(dustingreen): Switch to FIDL table instead. -union VideoUncompressedFormatSpecificDetails { - // TODO(dustingreen): Which formats that we care about really require special - // format-specific details here? - - // TODO(dustingreen): temp field to make the compiler happy until we have at - // least one real field. - uint32 temp_field_todo_remove; -}; - -enum VideoColorSpace { - // TODO(dustingreen): add to this list - INVALID = 0; -}; - -// VideoUncompressedFormat -// -// Uncompressed video format details. -// -// TODO(dustingreen): Integrate with a system-wide structure for this purpose. -struct VideoUncompressedFormat { - // fourcc - // - // A human-readable fourcc like RGBA should be 0x41424752 in the fourcc field - // (regardless of host endian-ness). Note that the R (first character) of the - // fourcc is in the low-order byte of this fourcc field. - // - // There are some fourcc codes that don't format nicely as a string. While I - // don't foresee any use of any of the purely numeric fourcc codes (not - // corresponding to packed ascii character values), those would be stored - // such that their numeric value has it's low-order byte in the low-order - // byte of this fourcc value. So a fourcc with "hex value" 0x00000001 would - // have the numeric value 1 in this field. - // - // The endian-ness of fourcc values stored in files or in network packets is - // outside the scope of these comments, other than to state that regardless - // of the source of the fourcc code and the order that storage / transmission - // format stores these bytes, a human-readable fourcc should have its - // human-read first ascii character value in the low order byte of this - // field. - uint32 fourcc; - - // For formats with different planes having different resolution, this is the - // resolution of the highest-resolution plane(s). Else it's the resolution - // of all the planes. - uint32 primary_width_pixels; - uint32 primary_height_pixels; - - // For formats where the secondary planes are the same resolution, these fields - // will be the same as primary_width_pixels and primary_height_pixels. For - // formats with smaller secondary resolutions, these indicate that resolution. - uint32 secondary_width_pixels; - uint32 secondary_height_pixels; - - // Planar means the various planes are separately stored in their own chunks - // of memory. - bool planar; - - // If a format is swizzled, the swizzling parameters are not directly here. - bool swizzled; - - uint32 primary_line_stride_bytes; - // Formats with the same stride for all planes will have this field equal to - // primary_line_stride_bytes. - uint32 secondary_line_stride_bytes; - - // R or Y - uint32 primary_start_offset; - // G or U - uint32 secondary_start_offset; - // B or V - uint32 tertiary_start_offset; - - uint32 primary_pixel_stride; - // For formats with the same pixel stride for all planes, this field will be - // equal to primary_pixel_stride. - uint32 secondary_pixel_stride; - - // These override the primary_width_pixels and primary_height_pixels for - // purposes of display (but not for purposes of determining the pixel layout - // in memory). These can crop on the right and bottom. These must be <= the - // corresponding coded dimension. - // - // This value must be <= primary_width_pixels. - uint32 primary_display_width_pixels; - // This value must be <= primary_height_pixels. - uint32 primary_display_height_pixels; - - // The pixel_aspect_ratio_width : pixel_aspect_ratio_height is the pixel - // aspect ratio (AKA sample aspect ratio aka SAR) for the luma (AKA Y) - // samples. A pixel_aspect_ratio of 1:1 mean square pixels. A - // pixel_aspect_ratio of 2:1 would mean pixels that are displayed twice as - // wide as they are tall. Codec implementation should ensure these two values - // are relatively prime by reducing the fraction (dividing both by GCF) if - // necessary. - // - // When has_pixel_aspect_ratio == false, pixel_aspect_ratio_width and - // pixel_aspect_ratio_height will both be 1, but in that case the - // pixel_aspect_ratio_width : pixel_aspect_ratio_height of 1:1 is just a very - // weak suggestion re. reasonable-ish handling, not in any way authoritative. - // In this case (or in any case really) the receiver of this message may have - // other OOB means to determine the actual pixel_aspect_ratio. - bool has_pixel_aspect_ratio = false; - uint32 pixel_aspect_ratio_width = 1; - uint32 pixel_aspect_ratio_height = 1; - - // TODO(dustingreen): Currently this assumes 8 bits per channel, but we'll - // need fields to indicate more bits per pixel such as 10 or 12 bits per - // pixel. Also, potentially a way to indicate different number of bits per - // channel for 565 16 bit RGB + packing details. Also, potentially - // endian-ness. - // - // TODO(dustingreen): Also, an easy way to get a template - // VideoUncompressedFormat that's pre-populated with reasonably-plausible - // values, based on a fourcc or enum value + maybe primary resolution. - - VideoUncompressedFormatSpecificDetails special_formats; -}; - -// VideoFormat -// -// Video (compress or uncompressed) format details. -union VideoFormat { - VideoCompressedFormat compressed; - VideoUncompressedFormat uncompressed; -}; - -// DomainFormat -// -// Domain-specific format details (audio or video, compressed or uncompressed). -union DomainFormat { - AudioFormat audio; - VideoFormat video; -}; - -const uint64 kMaxCodecOobBytesSize = 8192; - -// CodecFormatDetails -// -// This describes/details the format on input or output of a codec (separate -// instances for input vs. output). -struct CodecFormatDetails { - // Particular instances of CodecFormatDetails will set this field to make it - // easier for a receiver to determine if any part of the format has changed - // vs. the last CodecFormatDetails received for the same context. - uint64 format_details_version_ordinal; - - // "mime_type" strings used by particular decoders / encoders so far: - // - // SW AAC decoder: - // * input: - // * "audio/aac-adts" - ATDS AAC; self-contained format, but - // implementation for now requires codec_oob_bytes to contain - // AudioSpecificConfig() reconstructed from ADTS header data - see also - // make_AudioSpecificConfig_from_ADTS_header() for now. - // * output: - // * "audio/raw" - stereo linear 16 bit integer PCM - // - // TODO(dustingreen): avoid requiring codec_oob_bytes when using SoftAAC2.cpp - // for AAC ADTS. - // - // TODO(dustingreen): Add non-ADTS AAC support (which naturally needs - // codec_oob_bytes). - // - // TODO(dustingreen): Consider "pseudo_mime_type", or an enum, + "domain" - // details as needed instead, since calling this "mime_type" could lead to - // confusion. - string mime_type; - - // Some codecs have their own binary codec configuration structure. For those - // codecs we allow that binary structure to be directly conveyed to the codec - // here. - // - // audio/aac - this is an AudioSpecificConfig(). - // audio/aac-adts - this is not set. - // TODO(dustingreen): make the audio/aac-adts statement true soon. At the - // moment we set this with make_AudioSpecificConfig_from_ADTS_header(), but - // that should not be the client's job for ADTS. - // - // For some formats whose "ES" data format is self-contained, or for which - // there is no format-defined binary OOB config, this is null. - // - // A server can close the channel if the count of bytes is > - // kMaxCodecOobBytesSize or is larger than makes any sense for the codec. If - // any codec actually needs more than kMaxCodecOobBytesSize bytes here, we - // could potentially increase this restriction some, but this interface isn't - // designed to support codec OOB config blobs that approach - // ZX_CHANNEL_MAX_MSG_BYTES. - vector<uint8>? codec_oob_bytes; - - // Decoder input format: - // - // If a format is not self-describing given the mime_type and a - // format-spec-defined codec_oob_bytes, this domain field can be set to - // provide the additional compressed-format-specific details. This is - // expected to be fairly rare, so most compressed input formats will have - // only the mime_type and possibly codec_oob_bytes set, with domain typically - // null. If an encoder is upstream however, domain may be set to convey the - // encoder settings that were used, but a decoder consumer doesn't need to - // look at those. - // - // Encoder output format: - // - // The encoder's compressed data output typically needs some configuration - // (provided in this field) that's convenient to provide in a form that's not - // codec_oob_bytes, and the codec can convert that config to codec_oob_bytes - // on encoder output via OnOutputConfig(). We retain these encoder settings - // in the output CodecFormatDetails to allow for cases where a downstream - // consumer knowing the encoder settings could be useful. - // - // TODO(dustingreen): Decide if we want to retain this, or if we'd prefer to - // split out config settings and maybe only represent a few encoder settings - // as best-effort optional aux data, like bitrate. - // - // Encoder input format / decoder output format: - // - // This field contains fairly detailed information re. uncompressed data - // format details, which tends to _not_ be self-describing in-band. - DomainFormat? domain; - - // See comments above on Parameter. At the time we lock relevant FIDL - // interfaces, there should be zero use of this field outside tests, but this - // is here in case we need to allow a codec client to convey additional config - // parameters to/from a codec which we didn't anticipate before locking. - // - // If there are any known "official" exceptions to the previous paragraph, - // we'll list them here by corresponding mime_type (none so far): - // * "<mime_type>" - <usage_description> - // - // For codecs that define their own codec-specific config/OOB data, put that - // in codec_oob_bytes above instead of this field. - vector<Parameter>? pass_through_parameters; -}; diff --git a/garnet/public/fidl/fuchsia.mediacodec/codec_factory.fidl b/garnet/public/fidl/fuchsia.mediacodec/codec_factory.fidl index 480fc0e07bdbf9563c0014ef93d5bd9d78b36cd4..8ba91b4eaf83a0d77af5865263b7b5d1ef6fcad1 100644 --- a/garnet/public/fidl/fuchsia.mediacodec/codec_factory.fidl +++ b/garnet/public/fidl/fuchsia.mediacodec/codec_factory.fidl @@ -262,9 +262,10 @@ interface CodecFactory { // because finding the Codec is allowed to be fully async, so we don't // necessarily yet know on return from this method which Codec will be // selected, if any. + [Transitional] CreateDecoder( CreateDecoder_Params decoder_params, - request<Codec> decoder); + request<fuchsia.media.StreamProcessor> decoder); [Transitional] CreateDecoder2(