| <html devsite> |
| <head> |
| <title>Error and stream handling</title> |
| <meta name="project_path" value="/_project.yaml" /> |
| <meta name="book_path" value="/_book.yaml" /> |
| </head> |
| <body> |
| <!-- |
| Copyright 2017 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. |
| --> |
| |
| |
| |
| <h2 id="error-mgmt">Error management</h2> |
| <p>Camera HAL device ops functions that have a return value will all return <code>-ENODEV |
| / NULL</code> in case of a serious error. This means the device cannot continue |
| operation and must be closed by the framework. Once this error is returned by |
| some method, or if <code>notify()</code> is called with <code>ERROR_DEVICE</code>, only the <code>close()</code> method |
| can be called successfully. All other methods will return <code>-ENODEV / NULL</code>.</p> |
| <p>If a device op is called in the wrong sequence, for example if the framework |
| calls <code>configure_streams()</code> before <code>initialize()</code>, the device must return |
| <code>-ENOSYS</code> from the call, and do nothing.</p> |
| <p>Transient errors in image capture must be reported through <code>notify()</code> as follows:</p> |
| <ul> |
| <li>The failure of an entire capture to occur must be reported by the HAL by |
| calling <code>notify()</codE> with <code>ERROR_REQUEST</code>. Individual errors for the result metadata |
| or the output buffers must not be reported in this case.</li> |
| <li>If the metadata for a capture cannot be produced, but some image buffers were |
| filled, the HAL must call <code>notify()</code> with <code>ERROR_RESULT</code>.</li> |
| <li>If an output image buffer could not be filled, but either the metadata was |
| produced or some other buffers were filled, the HAL must call <code>notify()</code> with |
| <code>ERROR_BUFFER</code> for each failed buffer.</li> |
| </ul> |
| <p>In each of these transient failure cases, the HAL must still call |
| <code>process_capture_result</code>, with valid output <code>buffer_handle_t</code>. If the result |
| metadata could not be produced, it should be <code>NULL</code>. If some buffers could not be |
| filled, their sync fences must be set to the error state.</p> |
| <p>Invalid input arguments result in <code>-EINVAL</code> from the appropriate methods. In that |
| case, the framework must act as if that call had never been made.</p> |
| <h2 id="stream-mgmt">Stream management</h2> |
| <h3 id="configure_streams">configure_streams</h3> |
| <p>Reset the HAL camera device processing pipeline and set up new input and output |
| streams. This call replaces any existing stream configuration with the streams |
| defined in the <code>stream_list</code>. This method will be called at least once after |
| <code>initialize()</code> before a request is submitted with <code>process_capture_request()</code>.</p> |
| <p>The <code>stream_list</code> must contain at least one output-capable stream, and may not |
| contain more than one input-capable stream. |
| The <code>stream_list</code> may contain streams that are also in the currently-active set of |
| streams (from the previous call to <code>configure_stream()</code>). These streams will |
| already have valid values for usage, maxbuffers, and the private pointer. If |
| such a stream has already had its buffers registered, <code>register_stream_buffers()</code> |
| will not be called again for the stream, and buffers from the stream can be |
| immediately included in input requests.</p> |
| <p>If the HAL needs to change the stream configuration for an existing stream due |
| to the new configuration, it may rewrite the values of usage and/or maxbuffers |
| during the configure call. The framework will detect such a change, and will |
| then reallocate the stream buffers, and call <code>register_stream_buffers()</code> again |
| before using buffers from that stream in a request.</p> |
| <p>If a currently-active stream is not included in <code>stream_list</code>, the HAL may safely |
| remove any references to that stream. It will not be reused in a later |
| <code>configure()</code> call by the framework, and all the gralloc buffers for it will be |
| freed after the <code>configure_streams()</code> call returns.</p> |
| <p>The <code>stream_list</code> structure is owned by the framework, and may not be accessed |
| once this call completes. The address of an individual <code>camera3streamt</code> |
| structure will remain valid for access by the HAL until the end of the first |
| <code>configure_stream()</code> call which no longer includes that <code>camera3streamt</code> in the |
| <code>stream_list</code> argument. The HAL may not change values in the stream structure |
| outside of the private pointer, except for the usage and maxbuffers members |
| during the <code>configure_streams()</code> call itself.</p> |
| <p>If the stream is new, the usage, maxbuffer, and private pointer fields of the |
| stream structure will all be set to 0. The HAL device must set these fields |
| before the <code>configure_streams()</code> call returns. These fields are then used by the |
| framework and the platform gralloc module to allocate the gralloc buffers for |
| each stream.</p> |
| <p>Before such a new stream can have its buffers included in a capture request, the |
| framework will call <code>register_stream_buffers()</code> with that stream. However, the |
| framework is not required to register buffers for _all streams before |
| submitting a request. This allows for quick startup of (for example) a preview |
| stream, with allocation for other streams happening later or concurrently.</p> |
| <h4><strong>Preconditions</strong></h4> |
| <p>The framework will only call this method when no captures are being processed. |
| That is, all results have been returned to the framework, and all in-flight |
| input and output buffers have been returned and their release sync fences have |
| been signaled by the HAL. The framework will not submit new requests for capture |
| while the <code>configure_streams()</code> call is underway.</p> |
| <h4><strong>Postconditions</strong></h4> |
| <p>The HAL device must configure itself to provide maximum possible output frame |
| rate given the sizes and formats of the output streams, as documented in the |
| camera device's static metadata.</p> |
| <h4><strong>Performance expectations</strong></h4> |
| <p>This call is expected to be heavyweight and possibly take several hundred |
| milliseconds to complete, since it may require resetting and reconfiguring the |
| image sensor and the camera processing pipeline. Nevertheless, the HAL device |
| should attempt to minimize the reconfiguration delay to minimize the |
| user-visible pauses during application operational mode changes (such as |
| switching from still capture to video recording).</p> |
| <h4><strong>Return values</strong></h4> |
| <ul> |
| <li><code>0</code>: On successful stream configuration</li> |
| <li><code>undefined</code></li> |
| <li><code>-EINVAL</code>: If the requested stream configuration is invalid. Some examples of |
| invalid stream configurations include: |
| <ul> |
| <li>Including more than 1 input-capable stream (<code>INPUT</code> or <code>BIDIRECTIONAL</code>)</li> |
| <li>Not including any output-capable streams (<code>OUTPUT</code> or <code>BIDIRECTIONAL</code>)</li> |
| <li>Including streams with unsupported formats, or an unsupported size for |
| that format.</li> |
| <li>Including too many output streams of a certain format.</li> |
| <li>Note that the framework submitting an invalid stream configuration is not |
| normal operation, since stream configurations are checked before |
| configure. An invalid configuration means that a bug exists in the |
| framework code, or there is a mismatch between the HAL's static metadata |
| and the requirements on streams.</li> |
| </ul> |
| </li> |
| <li><code>-ENODEV</code>: If there has been a fatal error and the device is no longer |
| operational. Only <code>close()</code> can be called successfully by the framework after |
| this error is returned.</li> |
| </ul> |
| <h3 id="register-stream">register_stream_buffers</h3> |
| <p>Register buffers for a given stream with the HAL device. This method is called |
| by the framework after a new stream is defined by <code>configure_streams</code>, and before |
| buffers from that stream are included in a capture request. If the same stream |
| is listed in a subsequent <code>configure_streams()</code> call, <code>register_stream_buffers</code> will |
| not be called again for that stream.</p> |
| <p>The framework does not need to register buffers for all configured streams |
| before it submits the first capture request. This allows quick startup for |
| preview (or similar use cases) while other streams are still being allocated.</p> |
| <p>This method is intended to allow the HAL device to map or otherwise prepare the |
| buffers for later use. The buffers passed in will already be locked for use. At |
| the end of the call, all the buffers must be ready to be returned to the stream. |
| The bufferset argument is only valid for the duration of this call.</p> |
| <p>If the stream format was set to <code>HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED</code>, the |
| camera HAL should inspect the passed-in buffers here to determine any |
| platform-private pixel format information.</p> |
| <h4><strong>Return values</strong></h4> |
| <ul> |
| <li><code>0</code>: On successful registration of the new stream buffers</li> |
| <li><code>-EINVAL</code>: If the streambufferset does not refer to a valid active stream, or |
| if the buffers array is invalid.</li> |
| <li><code>-ENOMEM</code>: If there was a failure in registering the buffers. The framework must |
| consider all the stream buffers to be unregistered, and can try to register |
| again later.</li> |
| <li><code>-ENODEV</code>: If there is a fatal error, and the device is no longer operational. |
| Only <code>close()</code> can be called successfully by the framework after this error is |
| returned.</li> |
| </ul> |
| |
| </body> |
| </html> |