1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * @addtogroup Media
19  * @{
20  */
21 
22 /**
23  * @file NdkImageReader.h
24  */
25 
26 /*
27  * This file defines an NDK API.
28  * Do not remove methods.
29  * Do not change method signatures.
30  * Do not change the value of constants.
31  * Do not change the size of any of the classes defined in here.
32  * Do not reference types that are not part of the NDK.
33  * Do not #include files that aren't part of the NDK.
34  */
35 
36 #ifndef _NDK_IMAGE_READER_H
37 #define _NDK_IMAGE_READER_H
38 
39 #include <sys/cdefs.h>
40 #ifdef __ANDROID_VNDK__
41 #include <cutils/native_handle.h>
42 #endif
43 
44 #include <android/native_window.h>
45 #include "NdkMediaError.h"
46 #include "NdkImage.h"
47 
48 __BEGIN_DECLS
49 
50 /**
51  * AImage is an opaque type that allows direct application access to image data rendered into a
52  * {@link ANativeWindow}.
53  */
54 typedef struct AImageReader AImageReader;
55 
56 #if __ANDROID_API__ >= 24
57 
58 /**
59  * Create a new reader for images of the desired size and format.
60  *
61  * <p>
62  * The maxImages parameter determines the maximum number of {@link AImage} objects that can be
63  * acquired from the {@link AImageReader} simultaneously. Requesting more buffers will use up
64  * more memory, so it is important to use only the minimum number necessary for the use case.
65  * </p>
66  * <p>
67  * The valid sizes and formats depend on the source of the image data.
68  * </p>
69  *
70  * Available since API level 24.
71  *
72  * @param width The default width in pixels of the Images that this reader will produce.
73  * @param height The default height in pixels of the Images that this reader will produce.
74  * @param format The format of the Image that this reader will produce. This must be one of the
75  *            AIMAGE_FORMAT_* enum value defined in {@link AIMAGE_FORMATS}. Note that not all
76  *            formats are supported. One example is {@link AIMAGE_FORMAT_PRIVATE}, as it is not
77  *            intended to be read by applications directly. That format is supported by
78  *            {@link AImageReader_newWithUsage} introduced in API 26.
79  * @param maxImages The maximum number of images the user will want to access simultaneously. This
80  *            should be as small as possible to limit memory use. Once maxImages Images are obtained
81  *            by the user, one of them has to be released before a new {@link AImage} will become
82  *            available for access through {@link AImageReader_acquireLatestImage} or
83  *            {@link AImageReader_acquireNextImage}. Must be greater than 0.
84  * @param reader The created image reader will be filled here if the method call succeeeds.
85  *
86  * @return <ul>
87  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
88  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL, or one or more of width,
89  *                 height, format, maxImages arguments is not supported.</li>
90  *         <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul>
91  *
92  * @see AImage
93  */
94 media_status_t AImageReader_new(
95         int32_t width, int32_t height, int32_t format, int32_t maxImages,
96         /*out*/AImageReader** reader) __INTRODUCED_IN(24);
97 
98 /**
99  * Delete an {@link AImageReader} and return all images generated by this reader to system.
100  *
101  * <p>This method will return all {@link AImage} objects acquired by this reader (via
102  * {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}) to system,
103  * making any of data pointers obtained from {@link AImage_getPlaneData} invalid. Do NOT access
104  * the reader object or any of those data pointers after this method returns.</p>
105  *
106  * Available since API level 24.
107  *
108  * @param reader The image reader to be deleted.
109  */
110 void AImageReader_delete(AImageReader* reader) __INTRODUCED_IN(24);
111 
112 /**
113  * Get a {@link ANativeWindow} that can be used to produce {@link AImage} for this image reader.
114  *
115  * Available since API level 24.
116  *
117  * @param reader The image reader of interest.
118  * @param window The output {@link ANativeWindow} will be filled here if the method call succeeds.
119  *                The {@link ANativeWindow} is managed by this image reader. Do NOT call
120  *                {@link ANativeWindow_release} on it. Instead, use {@link AImageReader_delete}.
121  *
122  * @return <ul>
123  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
124  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or window is NULL.</li></ul>
125  */
126 media_status_t AImageReader_getWindow(AImageReader* reader, /*out*/ANativeWindow** window) __INTRODUCED_IN(24);
127 
128 /**
129  * Query the default width of the {@link AImage} generated by this reader, in pixels.
130  *
131  * <p>The width may be overridden by the producer sending buffers to this reader's
132  * {@link ANativeWindow}. If so, the actual width of the images can be found using
133  * {@link AImage_getWidth}.</p>
134  *
135  * Available since API level 24.
136  *
137  * @param reader The image reader of interest.
138  * @param width the default width of the reader will be filled here if the method call succeeeds.
139  *
140  * @return <ul>
141  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
142  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or width is NULL.</li></ul>
143  */
144 media_status_t AImageReader_getWidth(const AImageReader* reader, /*out*/int32_t* width) __INTRODUCED_IN(24);
145 
146 /**
147  * Query the default height of the {@link AImage} generated by this reader, in pixels.
148  *
149  * <p>The height may be overridden by the producer sending buffers to this reader's
150  * {@link ANativeWindow}. If so, the actual height of the images can be found using
151  * {@link AImage_getHeight}.</p>
152  *
153  * Available since API level 24.
154  *
155  * @param reader The image reader of interest.
156  * @param height the default height of the reader will be filled here if the method call succeeeds.
157  *
158  * @return <ul>
159  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
160  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or height is NULL.</li></ul>
161  */
162 media_status_t AImageReader_getHeight(const AImageReader* reader, /*out*/int32_t* height) __INTRODUCED_IN(24);
163 
164 /**
165  * Query the format of the {@link AImage} generated by this reader.
166  *
167  * Available since API level 24.
168  *
169  * @param reader The image reader of interest.
170  * @param format the fromat of the reader will be filled here if the method call succeeeds. The
171  *                value will be one of the AIMAGE_FORMAT_* enum value defiend in {@link NdkImage.h}.
172  *
173  * @return <ul>
174  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
175  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or format is NULL.</li></ul>
176  */
177 media_status_t AImageReader_getFormat(const AImageReader* reader, /*out*/int32_t* format) __INTRODUCED_IN(24);
178 
179 /**
180  * Query the maximum number of concurrently acquired {@link AImage}s of this reader.
181  *
182  * Available since API level 24.
183  *
184  * @param reader The image reader of interest.
185  * @param maxImages the maximum number of concurrently acquired images of the reader will be filled
186  *                here if the method call succeeeds.
187  *
188  * @return <ul>
189  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
190  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or maxImages is NULL.</li></ul>
191  */
192 media_status_t AImageReader_getMaxImages(const AImageReader* reader, /*out*/int32_t* maxImages) __INTRODUCED_IN(24);
193 
194 /**
195  * Acquire the next {@link AImage} from the image reader's queue.
196  *
197  * <p>Warning: Consider using {@link AImageReader_acquireLatestImage} instead, as it will
198  * automatically release older images, and allow slower-running processing routines to catch
199  * up to the newest frame. Usage of {@link AImageReader_acquireNextImage} is recommended for
200  * batch/background processing. Incorrectly using this method can cause images to appear
201  * with an ever-increasing delay, followed by a complete stall where no new images seem to appear.
202  * </p>
203  *
204  * <p>
205  * This method will fail if {@link AImageReader_getMaxImages maxImages} have been acquired with
206  * {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}. In particular
207  * a sequence of {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}
208  * calls greater than {@link AImageReader_getMaxImages maxImages} without calling
209  * {@link AImage_delete} in-between will exhaust the underlying queue. At such a time,
210  * {@link AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED} will be returned until more images are released with
211  * {@link AImage_delete}.
212  * </p>
213  *
214  * Available since API level 24.
215  *
216  * @param reader The image reader of interest.
217  * @param image the acquired {@link AImage} will be filled here if the method call succeeeds.
218  *
219  * @return <ul>
220  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
221  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or image is NULL.</li>
222  *         <li>{@link AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED} if the number of concurrently acquired
223  *                 images has reached the limit.</li>
224  *         <li>{@link AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE} if there is no buffers currently
225  *                 available in the reader queue.</li>
226  *         <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul>
227  *
228  * @see AImageReader_acquireLatestImage
229  */
230 media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image) __INTRODUCED_IN(24);
231 
232 /**
233  * Acquire the latest {@link AImage} from the image reader's queue, dropping older images.
234  *
235  * <p>
236  * This operation will acquire all the images possible from the image reader, but
237  * {@link AImage_delete} all images that aren't the latest. This function is recommended to use over
238  * {@link AImageReader_acquireNextImage} for most use-cases, as it's more suited for real-time
239  * processing.
240  * </p>
241  * <p>
242  * Note that {@link AImageReader_getMaxImages maxImages} should be at least 2 for
243  * {@link AImageReader_acquireLatestImage} to be any different than
244  * {@link AImageReader_acquireNextImage} - discarding all-but-the-newest {@link AImage} requires
245  * temporarily acquiring two {@link AImage}s at once. Or more generally, calling
246  * {@link AImageReader_acquireLatestImage} with less than two images of margin, that is
247  * (maxImages - currentAcquiredImages < 2) will not discard as expected.
248  * </p>
249  * <p>
250  * This method will fail if {@link AImageReader_getMaxImages maxImages} have been acquired with
251  * {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}. In particular
252  * a sequence of {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}
253  * calls greater than {@link AImageReader_getMaxImages maxImages} without calling
254  * {@link AImage_delete} in-between will exhaust the underlying queue. At such a time,
255  * {@link AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED} will be returned until more images are released with
256  * {@link AImage_delete}.
257  * </p>
258  *
259  * Available since API level 24.
260  *
261  * @param reader The image reader of interest.
262  * @param image the acquired {@link AImage} will be filled here if the method call succeeeds.
263  *
264  * @return <ul>
265  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
266  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or image is NULL.</li>
267  *         <li>{@link AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED} if the number of concurrently acquired
268  *                 images has reached the limit.</li>
269  *         <li>{@link AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE} if there is no buffers currently
270  *                 available in the reader queue.</li>
271  *         <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul>
272  *
273  * @see AImageReader_acquireNextImage
274  */
275 media_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image) __INTRODUCED_IN(24);
276 
277 
278 /**
279  * Signature of the callback which is called when a new image is available from {@link AImageReader}.
280  *
281  * @param context The optional application context provided by user in
282  *                {@link AImageReader_setImageListener}.
283  * @param session The camera capture session whose state is changing.
284  */
285 typedef void (*AImageReader_ImageCallback)(void* context, AImageReader* reader);
286 
287 typedef struct AImageReader_ImageListener {
288     /// Optional application context passed as the first parameter of the callback.
289     void*                      context;
290 
291     /**
292      * This callback is called when there is a new image available in the image reader's queue.
293      *
294      * <p>The callback happens on one dedicated thread per {@link AImageReader} instance. It is okay
295      * to use AImageReader_* and AImage_* methods within the callback. Note that it is possible that
296      * calling {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}
297      * returns {@link AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE} within this callback. For example, when
298      * there are multiple images and callbacks queued, if application called
299      * {@link AImageReader_acquireLatestImage}, some images will be returned to system before their
300      * corresponding callback is executed.</p>
301      */
302     AImageReader_ImageCallback onImageAvailable;
303 } AImageReader_ImageListener;
304 
305 /**
306  * Set the onImageAvailable listener of this image reader.
307  *
308  * Calling this method will replace previously registered listeners.
309  *
310  * Available since API level 24.
311  *
312  * @param reader The image reader of interest.
313  * @param listener The {@link AImageReader_ImageListener} to be registered. Set this to NULL if
314  *                 the application no longer needs to listen to new images.
315  *
316  * @return <ul>
317  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
318  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL.</li></ul>
319  */
320 media_status_t AImageReader_setImageListener(
321         AImageReader* reader, AImageReader_ImageListener* listener) __INTRODUCED_IN(24);
322 
323 #endif /* __ANDROID_API__ >= 24 */
324 
325 #if __ANDROID_API__ >= 26
326 
327 /**
328  * AImageReader constructor similar to {@link AImageReader_new} that takes an additional parameter
329  * for the consumer usage. All other parameters and the return values are identical to those passed
330  * to {@link AImageReader_new}.
331  *
332  * <p>If the \c format is {@link AIMAGE_FORMAT_PRIVATE}, the created {@link AImageReader}
333  * will produce images whose contents are not directly accessible by the application. The application can
334  * still acquire images from this {@link AImageReader} and access {@link AHardwareBuffer} via
335  * {@link AImage_getHardwareBuffer()}. The {@link AHardwareBuffer} gained this way can then
336  * be passed back to hardware (such as GPU or hardware encoder if supported) for future processing.
337  * For example, you can obtain an {@link EGLClientBuffer} from the {@link AHardwareBuffer} by using
338  * {@link eglGetNativeClientBufferANDROID} extension and pass that {@link EGLClientBuffer} to {@link
339  * eglCreateImageKHR} to create an {@link EGLImage} resource type, which may then be bound to a
340  * texture via {@link glEGLImageTargetTexture2DOES} on supported devices. This can be useful for
341  * transporting textures that may be shared cross-process.</p>
342  * <p>In general, when software access to image data is not necessary, an {@link AImageReader}
343  * created with {@link AIMAGE_FORMAT_PRIVATE} format is more efficient, compared with {@link
344  * AImageReader}s using other format such as {@link AIMAGE_FORMAT_YUV_420_888}.</p>
345  *
346  * <p>Note that not all format and usage flag combination is supported by the {@link AImageReader},
347  * especially if \c format is {@link AIMAGE_FORMAT_PRIVATE}, \c usage must not include either
348  * {@link AHARDWAREBUFFER_USAGE_READ_RARELY} or {@link AHARDWAREBUFFER_USAGE_READ_OFTEN}</p>
349  *
350  * @param width The default width in pixels of the Images that this reader will produce.
351  * @param height The default height in pixels of the Images that this reader will produce.
352  * @param format The format of the Image that this reader will produce. This must be one of the
353  *            AIMAGE_FORMAT_* enum value defined in {@link AIMAGE_FORMATS}.
354  * @param usage specifies how the consumer will access the AImage, using combination of the
355  *            AHARDWAREBUFFER_USAGE flags described in {@link hardware_buffer.h}.
356  *            Passing {@link AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN} is equivalent to calling
357  *            {@link AImageReader_new} with the same parameters.
358  *
359  * Note that not all format and usage flag combination is supported by the {@link AImageReader}.
360  * Below are the combinations supported by the {@link AImageReader}.
361  * <table>
362  * <tr>
363  *   <th>Format</th>
364  *   <th>Compatible usage flags</th>
365  * </tr>
366  * <tr>
367  *   <td>non-{@link AIMAGE_FORMAT_PRIVATE PRIVATE} formats defined in {@link AImage.h}
368  * </td>
369  *   <td>{@link AHARDWAREBUFFER_USAGE_CPU_READ_RARELY} or
370  *   {@link AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN}</td>
371  * </tr>
372  * <tr>
373  *   <td>{@link AIMAGE_FORMAT_RGBA_8888}</td>
374  *   <td>{@link AHARDWAREBUFFER_USAGE_VIDEO_ENCODE} or
375  *   {@link AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE}, or combined</td>
376  * </tr>
377  * </table>
378  *
379  * Available since API level 26.
380  *
381  * @return <ul>
382  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
383  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL, or one or more of width,
384  *                 height, format, maxImages, or usage arguments is not supported.</li>
385  *         <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul>
386  *
387  * @see AImage
388  * @see AImageReader_new
389  * @see AHardwareBuffer
390  */
391 media_status_t AImageReader_newWithUsage(
392         int32_t width, int32_t height, int32_t format, uint64_t usage, int32_t maxImages,
393         /*out*/ AImageReader** reader) __INTRODUCED_IN(26);
394 
395 /**
396  * Acquire the next {@link AImage} from the image reader's queue asynchronously.
397  *
398  * <p>AImageReader acquire method similar to {@link AImageReader_acquireNextImage} that takes an
399  * additional parameter for the sync fence. All other parameters and the return values are
400  * identical to those passed to {@link AImageReader_acquireNextImage}.</p>
401  *
402  * Available since API level 26.
403  *
404  * @param acquireFenceFd A sync fence fd defined in {@link sync.h}, which is used to signal when the
405  *         buffer is ready to consume. When synchronization fence is not needed, fence will be set
406  *         to -1 and the {@link AImage} returned is ready for use immediately. Otherwise, user shall
407  *         use syscalls such as \c poll(), \c epoll(), \c select() to wait for the
408  *         fence fd to change status before attempting to access the {@link AImage} returned.
409  *
410  * @see sync.h
411  * @see sync_get_fence_info
412  */
413 media_status_t AImageReader_acquireNextImageAsync(
414         AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd) __INTRODUCED_IN(26);
415 
416 /**
417  * Acquire the latest {@link AImage} from the image reader's queue asynchronously, dropping older
418  * images.
419  *
420  * <p>AImageReader acquire method similar to {@link AImageReader_acquireLatestImage} that takes an
421  * additional parameter for the sync fence. All other parameters and the return values are
422  * identical to those passed to {@link AImageReader_acquireLatestImage}.</p>
423  *
424  * Available since API level 26.
425  *
426  * @param acquireFenceFd A sync fence fd defined in {@link sync.h}, which is used to signal when the
427  *         buffer is ready to consume. When synchronization fence is not needed, fence will be set
428  *         to -1 and the {@link AImage} returned is ready for use immediately. Otherwise, user shall
429  *         use syscalls such as \c poll(), \c epoll(), \c select() to wait for the
430  *         fence fd to change status before attempting to access the {@link AImage} returned.
431  *
432  * @see sync.h
433  * @see sync_get_fence_info
434  */
435 media_status_t AImageReader_acquireLatestImageAsync(
436         AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd) __INTRODUCED_IN(26);
437 
438 /**
439  * Signature of the callback which is called when {@link AImageReader} is about to remove a buffer.
440  *
441  * @param context The optional application context provided by user in
442  *                {@link AImageReader_setBufferRemovedListener}.
443  * @param reader The {@link AImageReader} of interest.
444  * @param buffer The {@link AHardwareBuffer} that is being removed from this image reader.
445  */
446 typedef void (*AImageReader_BufferRemovedCallback)(void* context,
447         AImageReader* reader,
448         AHardwareBuffer* buffer);
449 
450 typedef struct AImageReader_BufferRemovedListener {
451     /// Optional application context passed as the first parameter of the callback.
452     void*                      context;
453 
454     /**
455      * This callback is called when an old {@link AHardwareBuffer} is about to be removed from the
456      * image reader.
457      *
458      * <p>Note that registering this callback is optional unless the user holds on extra reference
459      * to {@link AHardwareBuffer} returned from {@link AImage_getHardwareBuffer} by calling {@link
460      * AHardwareBuffer_acquire} or creating external graphic objects, such as EglImage, from it.</p>
461      *
462      * <p>If the callback is registered, the {@link AImageReader} will hold on the last of its
463      * references to the {@link AHardwareBuffer} until this callback returns. User can use the
464      * callback to get notified that it becomes the last owner of the buffer. It is up to the user
465      * to decide to either 1) immediately release all of its references to the buffer; or 2) keep
466      * using the buffer and release it in future. Note that, if option 2 if used, user of this API
467      * is responsible to deallocate the buffer properly by calling {@link AHardwareBuffer_release}.
468      * </p>
469      *
470      * @see AHardwareBuffer_release
471      * @see AImage_getHardwareBuffer
472      */
473     AImageReader_BufferRemovedCallback onBufferRemoved;
474 } AImageReader_BufferRemovedListener;
475 
476 /**
477  * Set the onBufferRemoved listener of this image reader.
478  *
479  * <p>Note that calling this method will replace previously registered listeners.</p>
480  *
481  * Available since API level 26.
482  *
483  * @param reader The image reader of interest.
484  * @param listener the {@link AImageReader_BufferRemovedListener} to be registered. Set this to
485  * NULL if application no longer needs to listen to buffer removed events.
486  *
487  * @return <ul>
488  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
489  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL.</li></ul>
490  *
491  * @see AImage_getHardwareBuffer
492  */
493 media_status_t AImageReader_setBufferRemovedListener(
494         AImageReader* reader, AImageReader_BufferRemovedListener* listener) __INTRODUCED_IN(26);
495 
496 #ifdef __ANDROID_VNDK__
497 /*
498  * Get the native_handle_t corresponding to the ANativeWindow owned by the
499  * AImageReader provided.
500  *
501  * @param reader The image reader of interest.
502  * @param handle The output native_handle_t. This native handle is owned by
503  *               this image reader.
504  *
505  * @return AMEDIA_OK if the method call succeeds.
506  *         AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL.
507  *         AMEDIA_ERROR_UNKNOWN if some other error is encountered.
508  */
509 media_status_t AImageReader_getWindowNativeHandle(
510     AImageReader *reader, /* out */native_handle_t **handle);
511 #endif
512 
513 #endif /* __ANDROID_API__ >= 26 */
514 
515 __END_DECLS
516 
517 #endif //_NDK_IMAGE_READER_H
518 
519 /** @} */
520