HeifWriter

public final class HeifWriter implements AutoCloseable


Writes one or more still images (of the same dimensions) into a heif file.

This class currently supports three input modes: INPUT_MODE_BUFFER, INPUT_MODE_SURFACE, or INPUT_MODE_BITMAP.

The general sequence (in pseudo-code) to write a heif file using this class is as follows:

1) Construct the writer:HeifWriter heifwriter = new HeifWriter(...);

2) If using surface input mode, obtain the input surface:Surface surface = heifwriter.getInputSurface();

3) Call start:heifwriter.start();

4) Depending on the chosen input mode, add one or more images using one of these methods:heifwriter.addYuvBuffer(...); Orheifwriter.addBitmap(...); Or render to the previously obtained surface

5) Call stop:heifwriter.stop(...);

6) Close the writer:heifwriter.close();

Please refer to the documentations on individual methods for the exact usage.

Summary

Nested types

public final class HeifWriter.Builder

Builder class for constructing a HeifWriter object from specified parameters.

Constants

static final int

The input mode where the client adds bitmaps.

static final int

The input mode where the client adds bitmaps.

static final int

The input mode where the client adds input buffers with YUV data.

static final int

The input mode where the client adds input buffers with YUV data.

static final int

The input mode where the client renders the images to an input Surface created by the writer.

static final int

The input mode where the client renders the images to an input Surface created by the writer.

Public methods

void

Add one bitmap to the heif file.

void
addExifData(
    int imageIndex,
    @NonNull byte[] exifData,
    int offset,
    int length
)

Add Exif data for the specified image.

void
addYuvBuffer(int format, @NonNull byte[] data)

Add one YUV buffer to the heif file.

void
@Nullable Handler
@NonNull Surface

Retrieves the input surface for encoding.

int
int
int
int
boolean
boolean
void
setInputEndOfStreamTimestamp(@IntRange(from = 0) long timestampNs)

Set the timestamp (in nano seconds) of the last input frame to encode.

void

Start the heif writer.

void
stop(@IntRange(from = 0) long timeoutMs)

Stop the heif writer synchronously.

Inherited methods

From java.lang.AutoCloseable
abstract void

Constants

INPUT_MODE_BITMAP

Added in 1.0.0
public static final int INPUT_MODE_BITMAP = 2

The input mode where the client adds bitmaps.

See also
addBitmap

INPUT_MODE_BITMAP

Added in 1.0.0
protected static final int INPUT_MODE_BITMAP = 2

The input mode where the client adds bitmaps.

See also
addBitmap

INPUT_MODE_BUFFER

Added in 1.0.0
public static final int INPUT_MODE_BUFFER = 0

The input mode where the client adds input buffers with YUV data.

See also
addYuvBuffer

INPUT_MODE_BUFFER

Added in 1.0.0
protected static final int INPUT_MODE_BUFFER = 0

The input mode where the client adds input buffers with YUV data.

See also
addYuvBuffer

INPUT_MODE_SURFACE

Added in 1.0.0
public static final int INPUT_MODE_SURFACE = 1

The input mode where the client renders the images to an input Surface created by the writer. The input surface operates in single buffer mode. As a result, for use case where camera directly outputs to the input surface, this mode will not work because camera framework requires multiple buffers to operate in a pipeline fashion.

See also
getInputSurface

INPUT_MODE_SURFACE

Added in 1.0.0
protected static final int INPUT_MODE_SURFACE = 1

The input mode where the client renders the images to an input Surface created by the writer. The input surface operates in single buffer mode. As a result, for use case where camera directly outputs to the input surface, this mode will not work because camera framework requires multiple buffers to operate in a pipeline fashion.

See also
getInputSurface

Protected fields

mEncoder

protected @NonNull EncoderBase mEncoder

mHandler

protected final Handler mHandler

mHandlerThread

protected final HandlerThread mHandlerThread

mHighBitDepthEnabled

protected final boolean mHighBitDepthEnabled

mInputMode

protected final int mInputMode

mMaxImages

protected final int mMaxImages

mMuxer

protected @NonNull MediaMuxer mMuxer

mNumTiles

protected int mNumTiles

mPrimaryIndex

protected final int mPrimaryIndex

mRotation

protected final int mRotation

Public methods

addBitmap

Added in 1.0.0
public void addBitmap(@NonNull Bitmap bitmap)

Add one bitmap to the heif file.

Parameters
@NonNull Bitmap bitmap

the bitmap to be added to the file.

Throws
java.lang.IllegalStateException

if not started or not configured to use bitmap input.

addExifData

Added in 1.0.0
public void addExifData(
    int imageIndex,
    @NonNull byte[] exifData,
    int offset,
    int length
)

Add Exif data for the specified image. The data must be a valid Exif data block, starting with "Exif\0\0" followed by the TIFF header (See JEITA CP-3451C Section 4.5.2.)

Parameters
int imageIndex

index of the image, must be a valid index for the max number of image specified by setMaxImages.

@NonNull byte[] exifData

byte buffer containing a Exif data block.

int offset

offset of the Exif data block within exifData.

int length

length of the Exif data block.

addYuvBuffer

Added in 1.0.0
public void addYuvBuffer(int format, @NonNull byte[] data)

Add one YUV buffer to the heif file.

Parameters
int format

The YUV format as defined in android.graphics.ImageFormat, currently only support YUV_420_888.

@NonNull byte[] data

byte array containing the YUV data. If the format has more than one planes, they must be concatenated.

Throws
java.lang.IllegalStateException

if not started or not configured to use buffer input.

close

Added in 1.0.0
public void close()

getHandler

Added in 1.1.0-alpha02
public @Nullable Handler getHandler()

getInputSurface

Added in 1.0.0
public @NonNull Surface getInputSurface()

Retrieves the input surface for encoding.

Returns
@NonNull Surface

the input surface if configured to use surface input.

Throws
java.lang.IllegalStateException

if called after start or not configured to use surface input.

getMaxImages

Added in 1.1.0-alpha02
public int getMaxImages()

getPrimaryIndex

Added in 1.1.0-alpha02
public int getPrimaryIndex()

getQuality

Added in 1.1.0-alpha02
public int getQuality()

getRotation

Added in 1.1.0-alpha02
public int getRotation()

isGridEnabled

Added in 1.1.0-alpha02
public boolean isGridEnabled()

isHighBitDepthEnabled

Added in 1.1.0-alpha02
public boolean isHighBitDepthEnabled()

setInputEndOfStreamTimestamp

Added in 1.0.0
public void setInputEndOfStreamTimestamp(@IntRange(from = 0) long timestampNs)

Set the timestamp (in nano seconds) of the last input frame to encode. This call is only valid for surface input. Client can use this to stop the heif writer earlier before the maximum number of images are written. If not called, the writer will only stop when the maximum number of images are written.

Parameters
@IntRange(from = 0) long timestampNs

timestamp (in nano seconds) of the last frame that will be written to the heif file. Frames with timestamps larger than the specified value will not be written. However, if a frame already started encoding when this is set, all tiles within that frame will be encoded.

Throws
java.lang.IllegalStateException

if not started or not configured to use surface input.

start

Added in 1.0.0
public void start()

Start the heif writer. Can only be called once.

Throws
java.lang.IllegalStateException

if called more than once.

stop

Added in 1.0.0
public void stop(@IntRange(from = 0) long timeoutMs)

Stop the heif writer synchronously. Throws exception if the writer didn't finish writing successfully. Upon a success return: - For buffer and bitmap inputs, all images sent before stop will be written. - For surface input, images with timestamp on or before that specified in setInputEndOfStreamTimestamp will be written. In case where setInputEndOfStreamTimestamp was never called, stop will block until maximum number of images are received.

Parameters
@IntRange(from = 0) long timeoutMs

Maximum time (in microsec) to wait for the writer to complete, with zero indicating waiting indefinitely.

Throws
java.lang.Exception

if encountered error, in which case the output file may not be valid. In particular, TimeoutException is thrown when timed out, and is thrown when encountered codec error.