public
class
ImageWriter
extends Object
implements
AutoCloseable
java.lang.Object | |
↳ | android.media.ImageWriter |
The ImageWriter class allows an application to produce Image data into a
Surface
, and have it be consumed by another component
like CameraDevice
.
Several Android API classes can provide input Surface
objects for ImageWriter to produce data into, including
MediaCodec
(encoder),
CameraCaptureSession
(reprocessing input), ImageReader
, etc.
The input Image data is encapsulated in Image
objects. To produce
Image data into a destination Surface
, the
application can get an input Image via dequeueInputImage()
then write
Image data into it. Multiple such Image
objects can be dequeued at
the same time and queued back in any order, up to the number specified by the
maxImages
constructor parameter.
If the application already has an Image from ImageReader
, the
application can directly queue this Image into ImageWriter (via
queueInputImage(Image)
), potentially with zero buffer copies. For the
PRIVATE
format Images produced by
ImageReader
, this is the only way to send Image data to ImageWriter,
as the Image data aren't accessible by the application.
ImageReader
or
CameraDevice
) to consume the Images. If the
downstream components cannot consume the Images at least as fast as the
ImageWriter production rate, the dequeueInputImage()
call will
eventually block and the application will have to drop input frames.
If the consumer component that provided the input Surface
abandons the Surface
, queueing
or dequeueing
an Image
will throw an
IllegalStateException
.
Nested classes | |
---|---|
interface |
ImageWriter.OnImageReleasedListener
ImageWriter callback interface, used to to asynchronously notify the application of various ImageWriter events. |
Public methods | |
---|---|
void
|
close()
Free up all the resources associated with this ImageWriter. |
Image
|
dequeueInputImage()
Dequeue the next available input Image for the application to produce data into. |
int
|
getFormat()
Get the ImageWriter format. |
int
|
getMaxImages()
Maximum number of Images that can be dequeued from the ImageWriter
simultaneously (for example, with |
static
ImageWriter
|
newInstance(Surface surface, int maxImages)
Create a new ImageWriter. |
void
|
queueInputImage(Image image)
Queue an input |
void
|
setOnImageReleasedListener(ImageWriter.OnImageReleasedListener listener, Handler handler)
Register a listener to be invoked when an input Image is returned to the ImageWriter. |
Protected methods | |
---|---|
void
|
finalize()
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. |
Inherited methods | |
---|---|
From
class
java.lang.Object
| |
From
interface
java.lang.AutoCloseable
|
void close ()
Free up all the resources associated with this ImageWriter.
After calling this method, this ImageWriter cannot be used. Calling any
methods on this ImageWriter and Images previously provided by
dequeueInputImage()
will result in an
IllegalStateException
, and attempting to write into
ByteBuffers
returned by an earlier
Plane#getBuffer
call will have undefined
behavior.
Image dequeueInputImage ()
Dequeue the next available input Image for the application to produce data into.
This method requests a new input Image from ImageWriter. The application
owns this Image after this call. Once the application fills the Image
data, it is expected to return this Image back to ImageWriter for
downstream consumer components (e.g.
CameraDevice
) to consume. The Image can
be returned to ImageWriter via queueInputImage(Image)
or
close()
.
This call will block if all available input images have been queued by
the application and the downstream consumer has not yet consumed any.
When an Image is consumed by the downstream consumer and released, an
onImageReleased(ImageWriter)
callback will be fired,
which indicates that there is one input Image available. For non-
PRIVATE
formats (
getFormat()
!= PRIVATE
), it is
recommended to dequeue the next Image only after this callback is fired,
in the steady state.
If the format of ImageWriter is PRIVATE
(
getFormat()
== PRIVATE
), the
image buffer is inaccessible to the application, and calling this method
will result in an IllegalStateException
. Instead, the application
should acquire images from some other component (e.g. an
ImageReader
), and queue them directly to this ImageWriter via the
queueInputImage()
method.
Returns | |
---|---|
Image |
The next available input Image from this ImageWriter. |
Throws | |
---|---|
IllegalStateException |
if maxImages Images are currently
dequeued, or the ImageWriter format is
PRIVATE , or the input
Surface has been abandoned by the
consumer component that provided the Surface . |
See also:
int getFormat ()
Get the ImageWriter format.
This format may be different than the Image format returned by
getFormat()
. However, if the ImageWriter format is
PRIVATE
, calling dequeueInputImage()
will result in an IllegalStateException
.
Returns | |
---|---|
int |
The ImageWriter format. |
int getMaxImages ()
Maximum number of Images that can be dequeued from the ImageWriter
simultaneously (for example, with dequeueInputImage()
).
An Image is considered dequeued after it's returned by
dequeueInputImage()
from ImageWriter, and until the Image is
sent back to ImageWriter via queueInputImage(Image)
, or
close()
.
Attempting to dequeue more than maxImages
concurrently will
result in the dequeueInputImage()
function throwing an
IllegalStateException
.
Returns | |
---|---|
int |
Maximum number of Images that can be dequeued from this ImageWriter. |
ImageWriter newInstance (Surface surface, int maxImages)
Create a new ImageWriter.
The maxImages
parameter determines the maximum number of
Image
objects that can be be dequeued from the
ImageWriter
simultaneously. Requesting more buffers will use up
more memory, so it is important to use only the minimum number necessary.
The input Image size and format depend on the Surface that is provided by the downstream consumer end-point.
Parameters | |
---|---|
surface |
Surface :
The destination Surface this writer produces Image data
into. |
maxImages |
int :
The maximum number of Images the user will want to
access simultaneously for producing Image data. This should be
as small as possible to limit memory use. Once maxImages
Images are dequeued by the user, one of them has to be queued
back before a new Image can be dequeued for access via
dequeueInputImage() . |
Returns | |
---|---|
ImageWriter |
a new ImageWriter instance. |
void queueInputImage (Image image)
Queue an input Image
back to ImageWriter for the downstream
consumer to access.
The input Image
could be from ImageReader (acquired via
acquireNextImage()
or
acquireLatestImage()
), or from this ImageWriter
(acquired via dequeueInputImage()
). In the former case, the Image
data will be moved to this ImageWriter. Note that the Image properties
(size, format, strides, etc.) must be the same as the properties of the
images dequeued from this ImageWriter, or this method will throw an
IllegalArgumentException
. In the latter case, the application has
filled the input image with data. This method then passes the filled
buffer to the downstream consumer. In both cases, it's up to the caller
to ensure that the Image timestamp (in nanoseconds) is correctly set, as
the downstream component may want to use it to indicate the Image data
capture time.
After this method is called and the downstream consumer consumes and
releases the Image, an onImageReleased(ImageWriter)
callback will fire. The application can use this callback to avoid
sending Images faster than the downstream consumer processing rate in
steady state.
Passing in an Image from some other component (e.g. an
ImageReader
) requires a free input Image from this ImageWriter as
the destination. In this case, this call will block, as
dequeueInputImage()
does, if there are no free Images available.
To avoid blocking, the application should ensure that there is at least
one free Image available in this ImageWriter before calling this method.
After this call, the input Image is no longer valid for further access,
as if the Image is closed
. Attempting to access the
ByteBuffers
returned by an earlier
Plane#getBuffer
call will result in an
IllegalStateException
.
Parameters | |
---|---|
image |
Image :
The Image to be queued back to ImageWriter for future
consumption. |
Throws | |
---|---|
IllegalStateException |
if the image was already queued previously,
or the image was aborted previously, or the input
Surface has been abandoned by the
consumer component that provided the
Surface . |
See also:
void setOnImageReleasedListener (ImageWriter.OnImageReleasedListener listener, Handler handler)
Register a listener to be invoked when an input Image is returned to the ImageWriter.
Parameters | |
---|---|
listener |
ImageWriter.OnImageReleasedListener :
The listener that will be run. |
handler |
Handler :
The handler on which the listener should be invoked, or
null if the listener should be invoked on the calling thread's
looper. |
Throws | |
---|---|
IllegalArgumentException |
If no handler specified and the calling thread has no looper. |
void finalize ()
Called by the garbage collector on an object when garbage collection
determines that there are no more references to the object.
A subclass overrides the finalize
method to dispose of
system resources or to perform other cleanup.
The general contract of finalize
is that it is invoked
if and when the JavaTM virtual
machine has determined that there is no longer any
means by which this object can be accessed by any thread that has
not yet died, except as a result of an action taken by the
finalization of some other object or class which is ready to be
finalized. The finalize
method may take any action, including
making this object available again to other threads; the usual purpose
of finalize
, however, is to perform cleanup actions before
the object is irrevocably discarded. For example, the finalize method
for an object that represents an input/output connection might perform
explicit I/O transactions to break the connection before the object is
permanently discarded.
The finalize
method of class Object
performs no
special action; it simply returns normally. Subclasses of
Object
may override this definition.
The Java programming language does not guarantee which thread will
invoke the finalize
method for any given object. It is
guaranteed, however, that the thread that invokes finalize will not
be holding any user-visible synchronization locks when finalize is
invoked. If an uncaught exception is thrown by the finalize method,
the exception is ignored and finalization of that object terminates.
After the finalize
method has been invoked for an object, no
further action is taken until the Java virtual machine has again
determined that there is no longer any means by which this object can
be accessed by any thread that has not yet died, including possible
actions by other objects or classes which are ready to be finalized,
at which point the object may be discarded.
The finalize
method is never invoked more than once by a Java
virtual machine for any given object.
Any exception thrown by the finalize
method causes
the finalization of this object to be halted, but is otherwise
ignored.
Throws | |
---|---|
Throwable |