From c80bf213563a1778c6f9397b3662efc220641a13 Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Thu, 6 Sep 2018 05:22:36 -0700 Subject: [PATCH] Initial commit of public Codec2 HIDL interfaces Test: Builds Bug: 112362730 Bug: 115717053 Change-Id: I8ad7fe965a90d56b5bbfd23998d4585f6e634bd6 --- media/c2/1.0/Android.bp | 51 ++ media/c2/1.0/IComponent.hal | 365 ++++++++++ media/c2/1.0/IComponentInterface.hal | 38 ++ media/c2/1.0/IComponentListener.hal | 128 ++++ media/c2/1.0/IComponentStore.hal | 224 ++++++ media/c2/1.0/IConfigurable.hal | 241 +++++++ media/c2/1.0/IInputSurface.hal | 51 ++ media/c2/1.0/IInputSurfaceConnection.hal | 37 + media/c2/1.0/types.hal | 832 +++++++++++++++++++++++ 9 files changed, 1967 insertions(+) create mode 100644 media/c2/1.0/Android.bp create mode 100644 media/c2/1.0/IComponent.hal create mode 100644 media/c2/1.0/IComponentInterface.hal create mode 100644 media/c2/1.0/IComponentListener.hal create mode 100644 media/c2/1.0/IComponentStore.hal create mode 100644 media/c2/1.0/IConfigurable.hal create mode 100644 media/c2/1.0/IInputSurface.hal create mode 100644 media/c2/1.0/IInputSurfaceConnection.hal create mode 100644 media/c2/1.0/types.hal diff --git a/media/c2/1.0/Android.bp b/media/c2/1.0/Android.bp new file mode 100644 index 0000000000..c37c22b4e2 --- /dev/null +++ b/media/c2/1.0/Android.bp @@ -0,0 +1,51 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.media.c2@1.0", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "types.hal", + "IComponent.hal", + "IComponentInterface.hal", + "IComponentListener.hal", + "IComponentStore.hal", + "IConfigurable.hal", + "IInputSurface.hal", + "IInputSurfaceConnection.hal", + ], + interfaces: [ + "android.hardware.graphics.bufferqueue@1.0", + "android.hardware.graphics.common@1.0", + "android.hardware.media.bufferpool@2.0", + "android.hardware.media.omx@1.0", + "android.hardware.media@1.0", + "android.hidl.base@1.0", + ], + types: [ + "BaseBlock", + "Block", + "Buffer", + "FieldDescriptor", + "FieldId", + "FieldSupportedValues", + "FieldSupportedValuesQuery", + "FieldSupportedValuesQueryResult", + "FrameData", + "InfoBuffer", + "ParamDescriptor", + "ParamField", + "ParamFieldValues", + "SettingResult", + "Status", + "StructDescriptor", + "Work", + "WorkBundle", + "WorkOrdinal", + "Worklet", + ], + gen_java: false, +} + diff --git a/media/c2/1.0/IComponent.hal b/media/c2/1.0/IComponent.hal new file mode 100644 index 0000000000..7fd551fc2b --- /dev/null +++ b/media/c2/1.0/IComponent.hal @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.media.c2@1.0; + +import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer; +import android.hardware.media.omx@1.0::IGraphicBufferSource; + +import IConfigurable; +import IComponentInterface; +import IComponentListener; +import IInputSurface; +import IInputSurfaceConnection; + +/** + * Interface for a Codec2 component corresponding to API level 1.0 or below. + * Components have two states: stopped and running. The running state has three + * sub-states: executing, tripped and error. + * + * All methods in `IComponent` must not block. If a method call cannot be + * completed in a timely manner, it must return `TIMED_OUT` in the return + * status. + */ +interface IComponent { + + // METHODS AVAILABLE WHEN RUNNING + // ========================================================================= + + /** + * Queues up work for the component. + * + * This method must be supported in running (including tripped) states. + * + * It is acceptable for this method to return `OK` and return an error value + * using the IComponentListener::onWorkDone() callback. + * + * @param workBundle `WorkBundle` object containing a list of `Work` objects + * to queue to the component. + * @return status Status of the call, which may be + * - `OK` - Works in @p workBundle were successfully queued. + * - `BAD_INDEX` - Some component id in some `Worklet` is not valid. + * - `CANNOT_DO` - The components are not tunneled but some `Work` object + * contains tunneling information. + * - `NO_MEMORY` - Not enough memory to queue @p workBundle. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + queue(WorkBundle workBundle) generates (Status status); + + /** + * Discards and abandons any pending `Work` items for the component. + * + * This method must be supported in running (including tripped) states. + * + * `Work` that could be immediately abandoned/discarded must be returned in + * @p flushedWorkBundle. The order in which queued `Work` items are + * discarded can be arbitrary. + * + * `Work` that could not be abandoned or discarded immediately must be + * marked to be discarded at the earliest opportunity, and must be returned + * via IComponentListener::onWorkDone(). This must be completed within + * 500ms. + * + * @return status Status of the call, which may be + * - `OK` - The component has been successfully flushed. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return flushedWorkBundle `WorkBundle` object containing flushed `Work` + * items. + */ + flush( + ) generates ( + Status status, + WorkBundle flushedWorkBundle + ); + + /** + * Drains the component, and optionally downstream components. This is a + * signalling method; as such it does not wait for any work completion. + * + * The last `Work` item is marked as "drain-till-here", so the component is + * notified not to wait for further `Work` before it processes what is + * already queued. This method can also be used to set the end-of-stream + * flag after `Work` has been queued. Client can continue to queue further + * `Work` immediately after this method returns. + * + * This method must be supported in running (including tripped) states. + * + * `Work` that is completed must be returned via + * IComponentListener::onWorkDone(). + * + * @param withEos Whether to drain the component with marking end-of-stream. + * @return status Status of the call, which may be + * - `OK` - The drain request has been successfully recorded. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + drain(bool withEos) generates (Status status); + + /** + * Starts using a surface for output. + * + * This method must not block. + * + * @param blockPoolId Id of the `C2BlockPool` to be associated with the + * output surface. + * @param surface Output surface. + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `CANNOT_DO` - The component does not support an output surface. + * - `REFUSED` - The output surface cannot be accessed. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + setOutputSurface( + uint64_t blockPoolId, + IGraphicBufferProducer surface + ) generates ( + Status status + ); + + /** + * Starts using an input surface. + * + * The component must be in running state. + * + * @param inputSurface Input surface to connect to. + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `CANNOT_DO` - The component does not support an input surface. + * - `BAD_STATE` - The component is not in running state. + * - `DUPLICATE` - The component is already connected to an input surface. + * - `REFUSED` - The input surface is already in use. + * - `NO_MEMORY` - Not enough memory to start the component. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return connection `IInputSurfaceConnection` object, which can be used to + * query and configure properties of the connection. This cannot be + * null. + */ + connectToInputSurface( + IInputSurface inputSurface + ) generates ( + Status status, + IInputSurfaceConnection connection + ); + + /** + * Starts using an OMX input surface. + * + * The component must be in running state. + * + * This method is similar to connectToInputSurface(), but it takes an OMX + * input surface (as a pair of `IGraphicBufferProducer` and + * `IGraphicBufferSource`) instead of Codec2's own `IInputSurface`. + * + * @param producer Producer component of an OMX input surface. + * @param source Source component of an OMX input surface. + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `CANNOT_DO` - The component does not support an OMX input surface. + * - `BAD_STATE` - The component is not in running state. + * - `DUPLICATE` - The component is already connected to an input surface. + * - `REFUSED` - The input surface is already in use. + * - `NO_MEMORY` - Not enough memory to start the component. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return connection `IInputSurfaceConnection` object, which can be used to + * query and configure properties of the connection. This cannot be + * null. + */ + connectToOmxInputSurface( + IGraphicBufferProducer producer, + IGraphicBufferSource source + ) generates ( + Status status, + IInputSurfaceConnection connection + ); + + /** + * Stops using an input surface. + * + * The component must be in running state. + * + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `CANNOT_DO` - The component does not support an input surface. + * - `BAD_STATE` - The component is not in running state. + * - `NOT_FOUND` - The component is not connected to an input surface. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + disconnectFromInputSurface() generates (Status Status); + + /** + * Creates a local `C2BlockPool` backed by the given allocator and returns + * its id. + * + * The returned @p blockPoolId is the only way the client can refer to a + * `C2BlockPool` object in the component. The id can be passed to + * setOutputSurface() or used in some C2Param objects later. + * + * The created `C2BlockPool` object can be destroyed by calling + * destroyBlockPool(), reset() or release(). reset() and release() must + * destroy all `C2BlockPool` objects that have been created. + * + * @param allocatorId Id of a `C2Allocator`. + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `NO_MEMORY` - Not enough memory to create the pool. + * - `BAD_VALUE` - @p allocatorId is not recognized. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return blockPoolId Id of the created C2BlockPool object. This may be + * used in setOutputSurface() if the allocator + * @return configurable Configuration interface for the created pool. This + * must not be null. + */ + createBlockPool(uint32_t allocatorId) generates ( + Status status, + uint64_t blockPoolId, + IConfigurable configurable + ); + + /** + * Destroys a local block pool previously created by createBlockPool(). + * + * @param blockPoolId Id of a `C2BlockPool` that was previously returned by + * createBlockPool(). + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `NOT_FOUND` - The supplied blockPoolId is not valid. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + destroyBlockPool(uint64_t blockPoolId) generates (Status status); + + // STATE CHANGE METHODS + // ========================================================================= + + /** + * Starts the component. + * + * This method must be supported in stopped state as well as tripped state. + * + * If the return value is `OK`, the component must be in the running state. + * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is + * expected as a response to this call. Otherwise, the component must be in + * the stopped state. + * + * If a component is in the tripped state and start() is called while the + * component configuration still results in a trip, start() must succeed and + * a new onTripped() callback must be used to communicate the configuration + * conflict that results in the new trip. + * + * @return status Status of the call, which may be + * - `OK` - The component has started successfully. + * - `BAD_STATE` - Component is not in stopped or tripped state. + * - `DUPLICATE` - When called during another start call from another + * thread. + * - `NO_MEMORY` - Not enough memory to start the component. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + start() generates (Status status); + + /** + * Stops the component. + * + * This method must be supported in running (including tripped) state. + * + * This method must return withing 500ms. + * + * Upon this call, all pending `Work` must be abandoned. + * + * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is + * expected as a response to this call. For all other return values, the + * component must be in the stopped state. + * + * This does not alter any settings and tunings that may have resulted in a + * tripped state. + * + * @return status Status of the call, which may be + * - `OK` - The component has stopped successfully. + * - `BAD_STATE` - Component is not in running state. + * - `DUPLICATE` - When called during another stop call from another + * thread. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + stop() generates (Status status); + + /** + * Resets the component. + * + * This method must be supported in all (including tripped) states other + * than released. + * + * This method must be supported during any other blocking call. + * + * This method must return withing 500ms. + * + * When this call returns, if @p status is `OK`, all `Work` items must + * have been abandoned, and all resources (including `C2BlockPool` objects + * previously created by createBlockPool()) must have been released. + * + * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is + * expected as a response to this call. For all other return values, the + * component must be in the stopped state. + * + * This brings settings back to their default, "guaranteeing" no tripped + * state. + * + * @return status Status of the call, which may be + * - `OK` - The component has been reset. + * - `BAD_STATE` - Component is in released state. + * - `DUPLICATE` - When called during another reset call from another + * thread. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + reset() generates (Status status); + + /** + * Releases the component. + * + * This method must be supported in stopped state. + * + * This method destroys the component. Upon return, if @p status is `OK` or + * `DUPLICATE`, all resources must have been released. + * + * @return status Status of the call, which may be + * - `OK` - The component has been released. + * - `BAD_STATE` - The component is running. + * - `DUPLICATE` - The component is already released. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + release() generates (Status status); + + /** + * Returns the @ref IComponentInterface instance associated to this + * component. + * + * An @p IConfigurable instance for the component can be obtained by calling + * IComponentInterface::getConfigurable() on the returned @p intf. + * + * @return intf `IComponentInterface` instance. This must not be null. + */ + getInterface() generates (IComponentInterface intf); +}; + diff --git a/media/c2/1.0/IComponentInterface.hal b/media/c2/1.0/IComponentInterface.hal new file mode 100644 index 0000000000..a007d02fe3 --- /dev/null +++ b/media/c2/1.0/IComponentInterface.hal @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.media.c2@1.0; + +import IConfigurable; + +/** + * Component interface object. This object contains all of the configurations of + * a potential or actual component. It can be created and used independently of + * an actual Codec2 component to query supported parameters for various + * component settings, and configurations for a potential component. + * + * An actual component exposes this interface via IComponent::getInterface(). + */ +interface IComponentInterface { + /** + * Returns the @ref IConfigurable instance associated to this component + * interface. + * + * @return configurable `IConfigurable` instance. This must not be null. + */ + getConfigurable() generates (IConfigurable configurable); +}; + diff --git a/media/c2/1.0/IComponentListener.hal b/media/c2/1.0/IComponentListener.hal new file mode 100644 index 0000000000..70d5fb289e --- /dev/null +++ b/media/c2/1.0/IComponentListener.hal @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.media.c2@1.0; + +/** + * Callback interface for handling notifications from @ref IComponent. + */ +interface IComponentListener { + + /** + * Notify the listener that some `Work` items have been completed. + * + * All the input buffers in the returned `Work` objects must not be used by + * the component after onWorkDone() is called. + * + * @param workBundle List of completed `Work` objects. + */ + oneway onWorkDone(WorkBundle workBundle); + + /** + * Notify the listener that the component is tripped. + * + * @param settingResults List of failures. + */ + oneway onTripped(vec settingResults); + + /** + * Notify the listener of an error. + * + * @param status Error type. @p status may be `OK`, which means that an + * error has occurred, but the error type does not fit into the type + * `Status`. In this case, additional information is provided by + * @p errorCode. + * @param errorCode Additional error information. The framework may not + * recognize the meaning of this value. + */ + oneway onError(Status status, uint32_t errorCode); + + /** + * Information about rendering of a frame to a `Surface`. + */ + struct RenderedFrame { + /** + * Id of the `BufferQueue` containing the rendered buffer. + * + * This value must have been obtained by an earlier call to + * IGraphicBufferProducer::getUniqueId(). + */ + uint64_t bufferQueueId; + /** + * Id of the slot of the rendered buffer. + * + * This value must have been obtained by an earlier call to + * IGraphicBufferProducer::dequeueBuffer() or + * IGraphicBufferProducer::attachBuffer(). + */ + int32_t slotId; + /** + * Timestamp the rendering happened. + * + * The reference point for the timestamp is determined by the + * `BufferQueue` that performed the rendering. + */ + int64_t timestampNs; + }; + + /** + * Notify the listener that frames have been rendered. + * + * @param renderedFrames List of @ref RenderedFrame objects. + */ + oneway onFramesRendered(vec renderedFrames); + + /** + * Identifying information for an input buffer previously queued to the + * component via IComponent::queue(). + */ + struct InputBuffer { + /** + * This value comes from `Work::input.ordinal.frameIndex` in a `Work` + * object that was previously queued. + */ + uint64_t frameIndex; + /** + * This value is an index into `Work::input.buffers` (which is an array) + * in a `Work` object that was previously queued. + */ + uint32_t arrayIndex; + }; + + /** + * Notify the listener that some input buffers are no longer needed by the + * component, and hence can be released or reused by the client. + * + * Input buffers that are contained in a `Work` object returned by an + * earlier onWorkDone() call are assumed released, so they must not appear + * in any onInputBuffersReleased() calls. That means + * onInputBuffersReleased() must only report input buffers that are released + * before the output in the same `Work` item is produced. However, it is + * possible for an input buffer to be returned by onWorkDone() after it has + * been reported by onInputBuffersReleased(). + * + * @note onWorkDone() and onInputBuffersReleased() both notify the client + * that input buffers are no longer needed. However, in order to minimize + * IPC calls, onInputBuffersReleased() should be called only when + * onWorkDone() cannot be called, e.g., the component needs more input + * before an output can be produced. + * + * @param inputBuffers List of `InputBuffer` objects, identifying input + * buffers that are no longer needed by the component. + */ + oneway onInputBuffersReleased(vec inputBuffers); +}; + diff --git a/media/c2/1.0/IComponentStore.hal b/media/c2/1.0/IComponentStore.hal new file mode 100644 index 0000000000..6a57c389f6 --- /dev/null +++ b/media/c2/1.0/IComponentStore.hal @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.media.c2@1.0; + +import android.hardware.media.bufferpool@2.0::IClientManager; +import IComponentInterface; +import IComponentListener; +import IComponent; +import IConfigurable; +import IInputSurface; + +/** + * Entry point for Codec2 HAL. + * + * All methods in `IComponentStore` must not block. If a method call cannot be + * completed in a timely manner, it must return `TIMED_OUT` in the return + * status. The only exceptions are getPoolClientManager() and getConfigurable(), + * which must always return immediately. + */ +interface IComponentStore { + + /** + * Creates a component by name. + * + * @param name Name of the component to create. This must match one of the + * names returned by listComponents(). + * @param listener Callback receiver. + * @param pool `IClientManager` object of the BufferPool in the client + * process. This may be null if the client does not own a BufferPool. + * @return status Status of the call, which may be + * - `OK` - The component was created successfully. + * - `NOT_FOUND` - There is no component with the given name. + * - `NO_MEMORY` - Not enough memory to create the component. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return comp The created component if @p status is `OK`. + * + * @sa IComponentListener. + */ + createComponent( + string name, + IComponentListener listener, + IClientManager pool + ) generates ( + Status status, + IComponent comp + ); + + /** + * Creates a component interface by name. + * + * @param name Name of the component interface to create. This should match + * one of the names returned by listComponents(). + * @return status Status of the call, which may be + * - `OK - The component interface was created successfully. + * - `NOT_FOUND` - There is no component interface with the given name. + * - `NO_MEMORY` - Not enough memory to create the component interface. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return compIntf The created component interface if @p status is `OK`. + */ + createInterface( + string name + ) generates ( + Status status, + IComponentInterface compIntf + ); + + /** + * Component traits. + */ + struct ComponentTraits { + /** + * Name of the component. This must be unique for each component. + * + * This name is use to identify the component to create in + * createComponent() and createComponentInterface(). + */ + string name; + + enum Domain : uint32_t { + OTHER = 0, + VIDEO, + AUDIO, + IMAGE, + }; + /** + * Component domain. + */ + Domain domain; + + enum Kind : uint32_t { + OTHER = 0, + DECODER, + ENCODER, + }; + /** + * Component kind. + */ + Kind kind; + + /** + * Rank used by `MediaCodecList` to determine component ordering. Lower + * value means higher priority. + */ + uint32_t rank; + + /** + * MIME type. + */ + string mediaType; + + /** + * Aliases for component name for backward compatibility. + * + * Multiple components can have the same alias (but not the same + * component name) as long as their media types differ. + */ + vec aliases; + }; + + /** + * Returns the list of components supported by this component store. + * + * @return status Status of the call, which may be + * - `OK - The operation was successful. + * - `NO_MEMORY` - Not enough memory to complete this method. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return traits List of component traits for all components supported by + * this store (in no particular order). + */ + listComponents() generates ( + Status status, + vec traits + ); + + /** + * Creates a persistent input surface that can be used as an input surface + * for any IComponent instance + * + * @return status Status of the call, which may be + * - `OK - The operation was successful. + * - `NO_MEMORY` - Not enough memory to complete this method. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return surface A persistent input surface. This may be null to indicate + * an error. + */ + createInputSurface() generates ( + Status status, + IInputSurface surface + ); + + /** + * Returns a list of `StructDescriptor` objects for a set of requested + * C2Param structure indices that this store is aware of. + * + * This operation must be performed at best effort, e.g. the component + * store must simply ignore all struct indices that it is not aware of. + * + * @param indices Indices of C2Param structures to describe. + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `NOT_FOUND` - Some indices were not known. + * - `NO_MEMORY` - Not enough memory to complete this method. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return structs List of `StructDescriptor` objects. + */ + getStructDescriptors( + vec indices + ) generates ( + Status status, + vec structs + ); + + /** + * Copies the contents of @p src into @p dst without changing the format of + * @p dst. + * + * @param src Source buffer. + * @param dst Destination buffer. + * @return status Status of the call, which may be + * - `OK` - The copy is successful. + * - `CANNOT_DO` - @p src and @p dst are not compatible. + * - `REFUSED` - No permission to copy. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + copyBuffer(Buffer src, Buffer dst) generates (Status status); + + /** + * Returns the `IClientManager` object for the component's BufferPool. + * + * @return pool If the component store supports receiving buffers via + * BufferPool API, @p pool must be a valid `IClientManager` instance. + * Otherwise, @p pool must be null. + */ + getPoolClientManager() generates (IClientManager pool); + + /** + * Returns the @ref IConfigurable instance associated to this component + * store. + * + * @return configurable `IConfigurable` instance. This must not be null. + */ + getConfigurable() generates (IConfigurable configurable); +}; + diff --git a/media/c2/1.0/IConfigurable.hal b/media/c2/1.0/IConfigurable.hal new file mode 100644 index 0000000000..31dc4d3cba --- /dev/null +++ b/media/c2/1.0/IConfigurable.hal @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.media.c2@1.0; + +/** + * Generic configuration interface presented by all configurable Codec2 objects. + * + * This interface must be supported in all states of the owning object, and must + * not change the state of the owning object. + */ +interface IConfigurable { + /** + * Returns the id of the object. This must be unique among all objects of + * the same type hosted by the same store. + * + * @return id Id of the object. + */ + getId() generates (uint32_t id); + + /** + * Returns the name of the object. + * + * This must match the name that was supplied during the creation of the + * object. + * + * @return name Name of the object. + */ + getName() generates (string name); + + /** + * Queries a set of parameters from the object. + * + * Querying is performed at best effort: the object must query all supported + * parameters and skip unsupported ones (which may include parameters that + * could not be allocated). Any errors are communicated in the return value. + * + * If @p mayBlock is false, this method must not block. All parameter + * queries that require blocking must be skipped. + * + * If @p mayBlock is true, a query may block, but the whole method call + * has to complete in a timely manner, or `status = TIMED_OUT` is returned. + * + * If @p mayBlock is false, this method must not block. Otherwise, this + * method is allowed to block for a certain period of time before completing + * the operation. If the operation is not completed in a timely manner, + * `status = TIMED_OUT` is returned. + * + * @note The order of C2Param objects in @p param does not depend on the + * order of C2Param structure indices in @p indices. + * + * \par For IComponent + * + * When the object type is @ref IComponent, this method must be supported in + * any state except released. This call must not change the state nor the + * internal configuration of the component. + * + * The blocking behavior of this method differs among states: + * - In the stopped state, this must be non-blocking. @p mayBlock is + * ignored. (The method operates as if @p mayBlock was false.) + * - In any of the running states, this method may block momentarily if + * @p mayBlock is true. However, if the call cannot be completed in a + * timely manner, `status = TIMED_OUT` is returned. + * + * @param indices List of C2Param structure indices to query. + * @param mayBlock Whether this call may block or not. + * @return status Status of the call, which may be + * - `OK` - All parameters could be queried. + * - `BAD_INDEX` - All supported parameters could be queried, but some + * parameters were not supported. + * - `NO_MEMORY` - Could not allocate memory for a supported parameter. + * - `BLOCKING` - Querying some parameters requires blocking, but + * @p mayBlock is false. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return params Flattened representation of C2Param objects. + * + * @sa Params. + */ + query( + vec indices, + bool mayBlock + ) generates ( + Status status, + Params params + ); + + /** + * Sets a set of parameters for the object. + * + * Tuning is performed at best effort: the object must update all supported + * configurations at best effort and skip unsupported parameters. Any errors + * are communicated in the return value and in @p failures. + * + * A non-strict parameter update with an unsupported value shall cause an + * update to the closest supported value. A strict parameter update with an + * unsupported value shall be skipped and a failure shall be returned. + * + * If @p mayBlock is false, this method must not block. An update that + * requires blocking shall be skipped and a failure shall be returned. + * + * If @p mayBlock is true, an update may block, but the whole method call + * has to complete in a timely manner, or `status = TIMED_OUT` is returned. + * + * The final values for all parameters set are propagated back to the caller + * in @p params. + * + * \par For IComponent + * + * When the object type is @ref IComponent, this method must be supported in + * any state except released. + * + * The blocking behavior of this method differs among states: + * - In the stopped state, this must be non-blocking. @p mayBlock is + * ignored. (The method operates as if @p mayBlock was false.) + * - In any of the running states, this method may block momentarily if + * @p mayBlock is true. However, if the call cannot be completed in a + * timely manner, `status = TIMED_OUT` is returned. + * + * @note Parameter tuning @e does depend on the order of the tuning + * parameters, e.g., some parameter update may enable some subsequent + * parameter update. + * + * @param inParams Requested parameter updates. + * @param mayBlock Whether this call may block or not. + * @return status Status of the call, which may be + * - `OK` - All parameters could be updated successfully. + * - `BAD_INDEX` - All supported parameters could be updated successfully, + * but some parameters were not supported. + * - `NO_MEMORY` - Some supported parameters could not be updated + * successfully because they contained unsupported values. + * These are returned in @p failures. + * - `BLOCKING` - Setting some parameters requires blocking, but + * @p mayBlock is false. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return failures List of update failures. + * @return outParams Flattened representation of configured parameters. The + * order of parameters in @p outParams is based on the order of + * requested updates in @p inParams. + * + * @sa SettingResult. + */ + config( + Params inParams, + bool mayBlock + ) generates ( + Status status, + vec failures, + Params outParams + ); + + // REFLECTION MECHANISM + // ========================================================================= + + /** + * Returns a list of supported parameters within a selected range of C2Param + * structure indices. + * + * @param start The first index of the selected range. + * @param count The length of the selected range. + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `NO_MEMORY` - Not enough memory to complete this method. + * @return params List of supported parameters in the selected range. This + * list may have fewer than @p count elements if some indices in the + * range are not supported. + * + * @sa ParamDescriptor. + */ + querySupportedParams( + uint32_t start, + uint32_t count + ) generates ( + Status status, + vec params + ); + + /** + * Retrieves the supported values for the queried fields. + * + * The object must process all fields queried even if some queries fail. + * + * If @p mayBlock is false, this method must not block. Otherwise, this + * method is allowed to block for a certain period of time before completing + * the operation. If the operation cannot be completed in a timely manner, + * `status = TIMED_OUT` is returned. + * + * \par For IComponent + * + * When the object type is @ref IComponent, this method must be supported in + * any state except released. + * + * The blocking behavior of this method differs among states: + * - In the stopped state, this must be non-blocking. @p mayBlock is + * ignored. (The method operates as if @p mayBlock was false.) + * - In any of the running states, this method may block momentarily if + * @p mayBlock is true. However, if the call cannot be completed in a + * timely manner, `status = TIMED_OUT` is returned. + * + * @param inFields List of field queries. + * @param mayBlock Whether this call may block or not. + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `BLOCKING` - Querying some parameters requires blocking, but + * @p mayBlock is false. + * - `NO_MEMORY` - Not enough memory to complete this method. + * - `BAD_INDEX` - At least one field was not recognized as a component + * field. + * - `BLOCKING` - Querying some fields requires blocking, but @p mayblock + * is false. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return outFields List of supported values and results for the + * supplied queries. + * + * @sa FieldSupportedValuesQuery, FieldSupportedValuesQueryResult. + */ + querySupportedValues( + vec inFields, + bool mayBlock + ) generates ( + Status status, + vec outFields + ); + +}; + diff --git a/media/c2/1.0/IInputSurface.hal b/media/c2/1.0/IInputSurface.hal new file mode 100644 index 0000000000..25c6c8e570 --- /dev/null +++ b/media/c2/1.0/IInputSurface.hal @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.media.c2@1.0; + +import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer; + +import IConfigurable; + +/** + * Input surface for a Codec2 component. + * + * An input surface is an instance of `IInputSurface`, which may be + * created by calling IComponentStore::createInputSurface(). Once created, the + * client may + * 1. write data to it via the `IGraphicBufferProducer` interface; and + * 2. use it as input to a Codec2 encoder. + * + * @sa IInputSurfaceConnection, IComponentStore::createInputSurface(), + * IComponent::connectToInputSurface(). + */ +interface IInputSurface { + /** + * Returns the producer interface into the internal buffer queue. + * + * @return producer `IGraphicBufferProducer` instance. This must not be + * null. + */ + getGraphicBufferProducer() generates (IGraphicBufferProducer producer); + + /** + * Returns the @ref IConfigurable instance associated to this input surface. + * + * @return configurable `IConfigurable` instance. This must not be null. + */ + getConfigurable() generates (IConfigurable configurable); +}; + diff --git a/media/c2/1.0/IInputSurfaceConnection.hal b/media/c2/1.0/IInputSurfaceConnection.hal new file mode 100644 index 0000000000..efd9c6e9a5 --- /dev/null +++ b/media/c2/1.0/IInputSurfaceConnection.hal @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.media.c2@1.0; + +import IConfigurable; + +/** + * Connection between a component and an input surface. + * + * An instance of `IInputSurfaceConnection` contains an `IConfigurable` + * interface for querying and configuring properties of the connection. + */ +interface IInputSurfaceConnection { + /** + * Returns the @ref IConfigurable instance associated to this connection. + * + * This can be used to customize the connection. + * + * @return configurable `IConfigurable` instance. This must not be null. + */ + getConfigurable() generates (IConfigurable configurable); +}; + diff --git a/media/c2/1.0/types.hal b/media/c2/1.0/types.hal new file mode 100644 index 0000000000..7b750416b0 --- /dev/null +++ b/media/c2/1.0/types.hal @@ -0,0 +1,832 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.media.c2@1.0; + +import android.hardware.media.bufferpool@2.0::BufferStatusMessage; + +/** + * Common return values for Codec2 operations. + */ +enum Status : int32_t { + /** Operation completed successfully. */ + OK = 0, + + // bad input + + /** Argument has invalid value (user error). */ + BAD_VALUE = -22, + /** Argument uses invalid index (user error). */ + BAD_INDEX = -75, + /** Argument/Index is valid but not possible. */ + CANNOT_DO = -2147483646, + + // bad sequencing of events + + /** Object already exists. */ + DUPLICATE = -17, + /** Object not found. */ + NOT_FOUND = -2, + /** Operation is not permitted in the current state. */ + BAD_STATE = -38, + /** Operation would block but blocking is not permitted. */ + BLOCKING = -9930, + + // bad environment + + /** Not enough memory to complete operation. */ + NO_MEMORY = -12, + /** Missing permission to complete operation. */ + REFUSED = -1, + + /** Operation did not complete within timeout. */ + TIMED_OUT = -110, + + // missing functionality + + /** Operation is not implemented/supported (optional only). */ + OMITTED = -74, + + // unknown fatal + + /** Some unexpected error prevented the operation. */ + CORRUPTED = -2147483648, + + // uninitialized + + /** Status has not been initialized. */ + NO_INIT = -19, +}; + +/** + * C2Param structure index. + * + * This is a number that is unique for each C2Param structure type. + * + * @sa Codec 2.0 standard. + */ +typedef uint32_t ParamIndex; + +/** + * Flattened representation of C2Param objects. + * + * The `Params` type is an array of bytes made up by concatenating a list of + * C2Param objects. The start index (offset into @ref Params) of each C2Param + * object in the list is divisible by 8. Up to 7 padding bytes may be added + * after each C2Param object to achieve this 64-bit alignment. + * + * Each C2Param object has the following layout: + * - 4 bytes: C2Param structure index (of type @ref ParamIndex) identifying the + * type of the C2Param object. + * - 4 bytes: size of the C2Param object (unsigned 4-byte integer). + * - (size - 8) bytes: data of the C2Param object. + * + * In order to interpret each C2Param object correctly, its structure must be + * described by IComponentStore::getStructDescriptors(). + * + * @note Please refer to the Codec 2.0 standard for the list of standard + * parameter structures. + * + * @sa Codec 2.0 standard. + */ +typedef vec Params; + +/** + * Identifying information of a field relative to a known C2Param structure. + * + * Within a given C2Param structure, each field is uniquely identified by @ref + * FieldId. + */ +struct FieldId { + /** Offset of the field in bytes. */ + uint32_t offset; + /** Size of the field in bytes. */ + uint32_t size; +}; + +/** + * Reference to a field in a C2Param structure. + */ +struct ParamField { + /** Index of the C2Param structure. */ + ParamIndex index; + /** Identifier of the field inside the C2Param structure. */ + FieldId fieldId; +}; + +/** + * Usage description of a C2Param structure. + * + * @ref ParamDescriptor is returned by IConfigurable::querySupportedParams(). + */ +struct ParamDescriptor { + /** + * Index of the C2Param structure being described. + */ + ParamIndex index; + + enum Attrib : uint32_t { + /** + * The parameter is required to be specified. + */ + REQUIRED = 1u << 0, + /** + * The parameter retains its value. + */ + PERSISTENT = 1u << 1, + /** + * The parameter is strict. + */ + STRICT = 1u << 2, + /** + * The parameter is publicly read-only. + */ + READ_ONLY = 1u << 3, + /** + * The parameter must not be visible to clients. + */ + HIDDEN = 1u << 4, + /** + * The parameter must not be used by framework (other than testing). + */ + INTERNAL = 1u << 5, + /** + * The parameter is publicly constant (hence read-only). + */ + CONST = 1u << 6, + }; + bitfield attrib; + + /** + * Name of the structure. This must be unique for each structure. + */ + string name; + + /** + * Indices of other C2Param structures that this C2Param structure depends + * on. + */ + vec dependencies; +}; + +// Generic way to describe supported numeric values for Codec2 interfaces. + +/** + * An untyped value that can fit in 64 bits, the type of which is communicated + * via a separate channel (@ref FieldSupportedValues.type). + */ +typedef uint64_t PrimitiveValue; + +/* + * Description of supported values for a field. + * + * This can be a continuous range or a discrete set of values. + */ +struct FieldSupportedValues { + /** + * Used if #type is `RANGE`. + * + * If the `step` member is 0, and `num` and `denom` are both 1, the `Range` + * structure represents a closed interval bounded by `min` and `max`. + * + * Otherwise, the #Range structure represents a finite sequence of numbers + * produced from the following recurrence relation: + * + * @code + * v[0] = min + * v[i] = v[i - 1] * num / denom + step ; i >= 1 + * @endcode + * + * Both the ratio `num / denom` and the value `step` must be positive. The + * last number in the sequence described by this #Range structure is the + * largest number in the sequence that is smaller than or equal to `max`. + * + * @note + * The division in the formula may truncate the result if the data type of + * these values is an integral type. + */ + struct Range { + /** + * Lower end of the range (inclusive). + */ + PrimitiveValue min; + /** + * Upper end of the range (inclusive). + */ + PrimitiveValue max; + /** + * The non-homogeneous term in the recurrence relation. + */ + PrimitiveValue step; + /** + * The numerator of the scale coefficient in the recurrence relation. + */ + PrimitiveValue num; + /** + * The denominator of the scale coefficient in the recurrence relation. + */ + PrimitiveValue denom; + }; + + enum Type : int32_t { + /** No supported values */ + EMPTY = 0, + /** Numeric range, described in a #Range structure */ + RANGE, + /** List of values */ + VALUES, + /** List of flags that can be OR-ed */ + FLAGS, + }; + /** + * Type of the supported values. + */ + Type type; + + /** + * When #type is #Type.RANGE, #range shall specify the range of possible + * values. + * + * The intended type of members of #range shall be clear in the context + * where `FieldSupportedValues` is used. + */ + Range range; + + /** + * When #type is #Type.VALUES or #Type.FLAGS, #value shall list supported + * values/flags. + * + * The intended type of components of #value shall be clear in the context + * where `FieldSupportedValues` is used. + */ + vec values; +}; + +/** + * Supported values for a field. + * + * This is a pair of the field specifier together with an optional supported + * values object. This structure is used when reporting parameter configuration + * failures and conflicts. + */ +struct ParamFieldValues { + /** + * Reference to a field or a C2Param structure. + */ + ParamField paramOrField; + + /** + * Optional supported values for the field if #paramOrField specifies an + * actual field that is numeric (non struct, blob or string). Supported + * values for arrays (including string and blobs) describe the supported + * values for each element (character for string, and bytes for blobs). It + * is optional for read-only strings and blobs. + */ + vec values; +}; + +/** + * Description of a field inside a C2Param structure. + */ +struct FieldDescriptor { + + /** Location of the field in the C2Param structure */ + FieldId fieldId; + + /** + * Possible types of the field. + */ + enum Type : uint32_t { + NO_INIT = 0, + INT32, + UINT32, + CNTR32, + INT64, + UINT64, + CNTR64, + FLOAT, + /** + * Fixed-size string (POD). + */ + STRING = 0x100, + /** + * A blob has no sub-elements and can be thought of as an array of + * bytes. However, bytes cannot be individually addressed by clients. + */ + BLOB, + /** + * The field is a structure that may contain other fields. + */ + STRUCT = 0x20000, + }; + /** + * Type of the field. + */ + bitfield type; + + /** + * If #type is #Type.STRUCT, #structIndex is the C2Param structure index; + * otherwise, #structIndex is not used. + */ + ParamIndex structIndex; + + /** + * Extent of the field. + * - For a non-array field, #extent is 1. + * - For a fixed-length array field, #extent is the length. An array field + * of length 1 is indistinguishable from a non-array field. + * - For a variable-length array field, #extent is 0. This can only occur as + * the last member of a C2Param structure. + */ + uint32_t extent; + + /** + * Name of the field. This must be unique for each field in the same + * structure. + */ + string name; + + /** + * Named value type. This is used for defining an enum value for a numeric + * type. + */ + struct NamedValue { + /** + * Name of the enum value. This must be unique for each enum value in + * the same field. + */ + string name; + /** + * Underlying value of the enum value. Multiple enum names may have the + * same underlying value. + */ + PrimitiveValue value; + }; + /** + * List of enum values. This is not used when #type is not one of the + * numeric types. + */ + vec namedValues; +}; + +/** + * Description of a C2Param structure. It consists of an index and a list of + * `FieldDescriptor`s. + */ +struct StructDescriptor { + /** + * Index of the structure. + */ + ParamIndex type; + /** + * List of fields in the structure. + * + * Fields are ordered by their offsets. A field that is a structure is + * ordered before its members. + */ + vec fields; +}; + +/** + * Information describing the reason the parameter settings may fail, or may be + * overridden. + */ +struct SettingResult { + /** Failure code */ + enum Failure : uint32_t { + /** Parameter is not supported. */ + BAD_TYPE, + /** Parameter is not supported on the specific port. */ + BAD_PORT, + /** Parameter is not supported on the specific stream. */ + BAD_INDEX, + /** Parameter is read-only and cannot be set. */ + READ_ONLY, + /** Parameter mismatches input data. */ + MISMATCH, + /** Strict parameter does not accept value for the field at all. */ + BAD_VALUE, + /** + * Strict parameter field value is in conflict with an/other + * setting(s). + */ + CONFLICT, + /** + * Parameter field is out of range due to other settings. (This failure + * mode can only be used for strict calculated parameters.) + */ + UNSUPPORTED, + /** + * Field does not access the requested parameter value at all. It has + * been corrected to the closest supported value. This failure mode is + * provided to give guidance as to what are the currently supported + * values for this field (which may be a subset of the at-all-potential + * values). + */ + INFO_BAD_VALUE, + /** + * Requested parameter value is in conflict with an/other setting(s) + * and has been corrected to the closest supported value. This failure + * mode is given to provide guidance as to what are the currently + * supported values as well as to optionally provide suggestion to the + * client as to how to enable the requested parameter value. + */ + INFO_CONFLICT, + }; + Failure failure; + + /** + * Failing (or corrected) field or parameter and optionally, currently + * supported values for the field. Values must only be set for field + * failures other than `BAD_VALUE`, and only if they are different from the + * globally supported values (e.g. due to restrictions by another parameter + * or input data). + */ + ParamFieldValues field; + + /** + * Conflicting parameters or fields with (optional) suggested values for any + * conflicting fields to avoid the conflict. Values must only be set for + * `CONFLICT`, `UNSUPPORTED` or `INFO_CONFLICT` failure code. + */ + vec conflicts; +}; + +/** + * Ordering information of @ref FrameData objects. Each member is used for + * comparing urgency: a smaller difference from a reference value indicates that + * the associated Work object is more urgent. The reference value for each + * member is initialized the first time it is communicated between the client + * and the codec, and it may be updated to later values that are communicated. + * + * Each member of `WorkOrdinal` is stored as an unsigned integer, but the actual + * order it represents is derived by subtracting the reference value, then + * interpreting the result as a signed number with the same storage size (using + * two's complement). + * + * @note `WorkOrdinal` is the HIDL counterpart of `C2WorkOrdinalStruct` in the + * Codec 2.0 standard. + */ +struct WorkOrdinal { + /** + * Timestamp in microseconds. + */ + uint64_t timestampUs; + /** + * Frame index. + */ + uint64_t frameIndex; + /** + * Component specific frame ordinal. + */ + uint64_t customOrdinal; +}; + +/** + * Storage type for `BaseBlock`. + * + * A `BaseBlock` is a representation of a codec memory block. Coded data, + * decoded data, codec-specific data, and other codec-related data are all sent + * in the form of BaseBlocks. + */ +safe_union BaseBlock { + /** + * #nativeBlock is the opaque representation of a buffer. + */ + handle nativeBlock; + /** + * #pooledBlock is a reference to a buffer handled by a BufferPool. + */ + BufferStatusMessage pooledBlock; +}; + +/** + * Reference to a @ref BaseBlock within a @ref WorkBundle. + * + * `Block` contains additional attributes that `BaseBlock` does not. These + * attributes may differ among `Block` objects that refer to the same + * `BaseBlock` in the same `WorkBundle`. + */ +struct Block { + /** + * Identity of a `BaseBlock` within a `WorkBundle`. This is an index into + * #WorkBundle.baseBlocks. + */ + uint32_t index; + /** + * Metadata associated with this `Block`. + */ + Params meta; + /** + * Fence for synchronizing `Block` access. + */ + handle fence; +}; + +/** + * A codec buffer, which is a collection of @ref Block objects and metadata. + * + * This is a part of @ref FrameData. + */ +struct Buffer { + /** + * Metadata associated with the buffer. + */ + Params info; + /** + * Blocks contained in the buffer. + */ + vec blocks; +}; + +/** + * An extension of @ref Buffer that also contains a C2Param structure index. + * + * This is a part of @ref FrameData. + */ +struct InfoBuffer { + /** + * A C2Param structure index. + */ + ParamIndex index; + /** + * Associated @ref Buffer object. + */ + Buffer buffer; +}; + +/** + * Data for an input frame or an output frame. + * + * This structure represents a @e frame with its metadata. A @e frame consists + * of an ordered set of buffers, configuration changes, and info buffers along + * with some non-configuration metadata. + * + * @note `FrameData` is the HIDL counterpart of `C2FrameData` in the Codec 2.0 + * standard. + */ +struct FrameData { + enum Flags : uint32_t { + /** + * For input frames: no output frame shall be generated when processing + * this frame, but metadata must still be processed. + * + * For output frames: this frame must be discarded but metadata is still + * valid. + */ + DROP_FRAME = (1 << 0), + /** + * This frame is the last frame of the current stream. Further frames + * are part of a new stream. + */ + END_OF_STREAM = (1 << 1), + /** + * This frame must be discarded with its metadata. + * + * This flag is only set by components, e.g. as a response to the flush + * command. + */ + DISCARD_FRAME = (1 << 2), + /** + * This frame is not the last frame produced for the input. + * + * This flag is normally set by the component - e.g. when an input frame + * results in multiple output frames, this flag is set on all but the + * last output frame. + * + * Also, when components are chained, this flag should be propagated + * down the work chain. That is, if set on an earlier frame of a + * work-chain, it should be propagated to all later frames in that + * chain. Additionally, components down the chain could set this flag + * even if not set earlier, e.g. if multiple output frames are generated + * at that component for the input frame. + */ + FLAG_INCOMPLETE = (1 << 3), + /** + * This frame contains only codec-specific configuration data, and no + * actual access unit. + * + * @deprecated Pass codec configuration with the codec-specific + * configuration info together with the access unit. + */ + CODEC_CONFIG = (1u << 31), + }; + + /** + * Frame flags, as described in #Flags. + */ + bitfield flags; + + /** + * @ref WorkOrdinal of the frame. + */ + WorkOrdinal ordinal; + + /** + * List of frame buffers. + */ + vec buffers; + + /** + * List of configuration updates. + */ + Params configUpdate; + + /** + * List of info buffers. + */ + vec infoBuffers; +}; + +/** + * In/out structure containing some instructions for and results from output + * processing. + * + * This is a part of @ref Work. One `Worklet` corresponds to one output + * @ref FrameData. The client must construct an original `Worklet` object inside + * a @ref Work object for each expected output before calling + * IComponent::queue(). + */ +struct Worklet { + /** + * Component id. (Input) + * + * This is used only when tunneling is enabled. + * + * When used, this must match the return value from IConfigurable::getId(). + */ + uint32_t componentId; + + /** + * List of C2Param objects describing tunings to be applied before + * processing this `Worklet`. (Input) + */ + Params tunings; + + /** + * Flag determining whether this `Worklet` has output or not. + */ + bool hasOutput; + + /** + * List of failures. (Output) + */ + vec failures; + + /** + * Output frame data. (Output) + */ + FrameData output; +}; + +/** + * A collection of input data to and output data from the component. + * + * A `Work` object holds information about a single work item. It is created by + * the client and passed to the component via IComponent::queue(). The component + * has two ways of returning a `Work` object to the client: + * 1. If the queued `Work` object has been successfully processed, + * IComponentListener::onWorkDone() shall be called to notify the listener, + * and the output shall be included in the returned `Work` object. + * 2. If the client calls IComponent::flush(), a `Work` object that has not + * been processed shall be returned. + * + * `Work` is a part of @ref WorkBundle. + */ +struct Work { + /** + * Additional work chain info not part of this work. + */ + Params chainInfo; + + /** + * @ref FrameData for the input. + */ + FrameData input; + + /** + * The chain of `Worklet`s. + * + * The length of #worklets is 1 when tunneling is not enabled. + * + * If #worklets has more than a single element, the tunnels between + * successive components of the work chain must have been successfully + * pre-registered at the time that the `Work` is submitted. Allocating the + * output buffers in the `Worklet`s is the responsibility of each component + * in the chain. + * + * Upon `Work` submission, #worklets must be an appropriately sized vector + * containing `Worklet`s with @ref Worklet.hasOutput set to `false`. After a + * successful processing, all but the final `Worklet` in the returned + * #worklets must have @ref Worklet.hasOutput set to `false`. + */ + vec worklets; + + /** + * The number of `Worklet`s successfully processed in this chain. + * + * This must be initialized to 0 by the client when the `Work` is submitted, + * and it must contain the number of `Worklet`s that were successfully + * processed when the `Work` is returned to the client. + * + * #workletsProcessed cannot exceed the length of #worklets. If + * #workletsProcessed is smaller than the length of #worklets, #result + * cannot be `OK`. + */ + uint32_t workletsProcessed; + + /** + * The final outcome of the `Work` (corresponding to #workletsProcessed). + * + * The value of @ref Status.OK implies that all `Worklet`s have been + * successfully processed. + */ + Status result; +}; + +/** + * List of `Work` objects. + * + * `WorkBundle` is used in IComponent::queue(), IComponent::flush() and + * IComponentListener::onWorkDone(). A `WorkBundle` object consists of a list of + * `Work` objects and a list of `BaseBlock` objects. Bundling multiple `Work` + * objects together provides two benefits: + * 1. Batching of `Work` objects can reduce the number of IPC calls. + * 2. If multiple `Work` objects contain `Block`s that refer to the same + * `BaseBlock`, the number of `BaseBlock`s that is sent between processes + * is also reduced. + * + * @note `WorkBundle` is the HIDL counterpart of the vector of `C2Work` in the + * Codec 2.0 standard. The presence of #baseBlocks helps with minimizing the + * data transferred over an IPC. + */ +struct WorkBundle { + /** + * A list of Work items. + */ + vec works; + /** + * A list of blocks indexed by elements of #works. + */ + vec baseBlocks; +}; + +/** + * Query information for supported values of a field. This is used as input to + * IConfigurable::querySupportedValues(). + */ +struct FieldSupportedValuesQuery { + /** + * Identity of the field to query. + */ + ParamField field; + + enum Type : uint32_t { + /** Query all possible values regardless of other settings. */ + POSSIBLE, + /** Query currently possible values given dependent settings. */ + CURRENT, + }; + /** + * Type of the query. See #Type for more information. + */ + Type type; +}; + +/** + * This structure is used to hold the result from + * IConfigurable::querySupportedValues(). + */ +struct FieldSupportedValuesQueryResult { + /** + * Result of the query. Possible values are + * - `OK`: The query was successful. + * - `BAD_STATE`: The query was requested when the `IConfigurable` instance + * was in a bad state. + * - `BAD_INDEX`: The requested field was not recognized. + * - `TIMED_OUT`: The query could not be completed in a timely manner. + * - `BLOCKING`: The query must block, but the parameter `mayBlock` in the + * call to `querySupportedValues()` was `false`. + * - `CORRUPTED`: Some unknown error occurred. + */ + Status status; + + /** + * Supported values. This is meaningful only when #status is `OK`. + */ + FieldSupportedValues values; +}; +