I have an ImageReader, whose surface is attached to a MediaCodec decoder to render into.
AMediaCodec *videoDecoder = nullptr;
ANativeWindow* surface = nullptr;
AImageReader* imageReader = nullptr;
AImageReader_ImageListener* imageListener = nullptr;
if ((videoDecoder = AMediaCodec_createDecoderByType(mime)))
{
if (AImageReader_new(mWidth, mHeight, AIMAGE_FORMAT_YUV_420_888, 2, &imageReader) == AMEDIA_OK)
{
if (AImageReader_getWindow(imageReader, &surface) == AMEDIA_OK)
{
if (AMediaCodec_configure(videoDecoder, mediaFormat, surface, NULL, 0) == AMEDIA_OK)
{
int32_t outputFormat{};
AMediaFormat_getInt32(AMediaCodec_getOutputFormat(videoDecoder), AMEDIAFORMAT_KEY_COLOR_FORMAT, &outputFormat);
imageListener = new AImageReader_ImageListener();
imageListener->onImageAvailable = &onImageAvailableCallback;
AImageReader_setImageListener(imageReader, imageListener);
if (AMediaCodec_start(videoDecoder) == AMEDIA_OK)
{
configCompleted = true;
}
else
{
TRACE("ImporterMP4Android", 0, "Failed to Start Video Decoder");
}
}
else
{
TRACE("ImporterMP4Android", 0, "Failed to Configure Video Decoder");
}
}
else
{
TRACE("ImporterMP4Android", 0, "Failed to Fetch Surface owned by the ImageReader");
}
}
else
{
TRACE("ImporterMP4Android", 0, "Failed to Create ImageReader");
}
}
else
{
TRACE("ImporterMP4Android", 0, "Failed to Create Decoder");
}
The onImageAvailableCallback
looks like this atm:
void onImageAvailableCallback(void *context, AImageReader *reader)
{
int32_t format;
media_status_t status = AImageReader_getFormat (reader, &format);
AImage *image;
status = AImageReader_acquireLatestImage(reader, &image);
status = AImage_getFormat(image, &format);
// TODO: copy *raw data somewhere for downstream processing
AImage_delete(image);
}
As indicated in TODO comment, I want to copy out the raw data of the Image
acquired from ImageReader
for further processing. The interface provided by the Image class allows me to query the number of planes and fetch individual planar data, but I am interested in grabbing the entire frame at once. Any suggestions on how I might accomplish this?
In a nutshell, I am using MediaCodec video decoder to render into a Surface owned by an ImageReader, and ultimately want to grab the decoded video frames from the ImageReader in their entirety in YUV420NV21 format for further processing.