/*
 * Android camera input device
 *
 * Copyright (C) 2017 Felix Matouschek
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <errno.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>

#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraManager.h>
#include <media/NdkImage.h>
#include <media/NdkImageReader.h>

#include "libavformat/avformat.h"
#include "libavformat/internal.h"
#include "libavutil/avstring.h"
#include "libavutil/display.h"
#include "libavutil/imgutils.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixfmt.h"
#include "libavutil/threadmessage.h"
#include "libavutil/time.h"

#include "version.h"

/* This image format is available on all Android devices
 * supporting the Camera2 API */
#define IMAGE_FORMAT_ANDROID AIMAGE_FORMAT_YUV_420_888

#define MAX_BUF_COUNT 2
#define VIDEO_STREAM_INDEX 0
#define VIDEO_TIMEBASE_ANDROID 1000000000

#define RETURN_CASE(x) case x: return AV_STRINGIFY(x);
#define RETURN_DEFAULT(x) default: return AV_STRINGIFY(x);

typedef struct AndroidCameraCtx {
    const AVClass *class;

    int requested_width;
    int requested_height;
    AVRational framerate;
    int camera_index;
    int input_queue_size;

    uint8_t lens_facing;
    int32_t sensor_orientation;
    int width;
    int height;
    int32_t framerate_range[2];
    int image_format;

    ACameraManager *camera_mgr;
    char *camera_id;
    ACameraMetadata *camera_metadata;
    ACameraDevice *camera_dev;
    ACameraDevice_StateCallbacks camera_state_callbacks;
    AImageReader *image_reader;
    AImageReader_ImageListener image_listener;
    ANativeWindow *image_reader_window;
    ACaptureSessionOutputContainer *capture_session_output_container;
    ACaptureSessionOutput *capture_session_output;
    ACameraOutputTarget *camera_output_target;
    ACaptureRequest *capture_request;
    ACameraCaptureSession_stateCallbacks capture_session_state_callbacks;
    ACameraCaptureSession *capture_session;

    AVThreadMessageQueue *input_queue;
    atomic_int exit;
    atomic_int got_image_format;
} AndroidCameraCtx;

static const char *camera_status_string(camera_status_t val)
{
    switch(val) {
        RETURN_CASE(ACAMERA_OK)
        RETURN_CASE(ACAMERA_ERROR_UNKNOWN)
        RETURN_CASE(ACAMERA_ERROR_INVALID_PARAMETER)
        RETURN_CASE(ACAMERA_ERROR_CAMERA_DISCONNECTED)
        RETURN_CASE(ACAMERA_ERROR_NOT_ENOUGH_MEMORY)
        RETURN_CASE(ACAMERA_ERROR_METADATA_NOT_FOUND)
        RETURN_CASE(ACAMERA_ERROR_CAMERA_DEVICE)
        RETURN_CASE(ACAMERA_ERROR_CAMERA_SERVICE)
        RETURN_CASE(ACAMERA_ERROR_SESSION_CLOSED)
        RETURN_CASE(ACAMERA_ERROR_INVALID_OPERATION)
        RETURN_CASE(ACAMERA_ERROR_STREAM_CONFIGURE_FAIL)
        RETURN_CASE(ACAMERA_ERROR_CAMERA_IN_USE)
        RETURN_CASE(ACAMERA_ERROR_MAX_CAMERA_IN_USE)
        RETURN_CASE(ACAMERA_ERROR_CAMERA_DISABLED)
        RETURN_CASE(ACAMERA_ERROR_PERMISSION_DENIED)
        RETURN_DEFAULT(ACAMERA_ERROR_UNKNOWN)
    }
}

static const char *media_status_string(media_status_t val)
{
    switch(val) {
        RETURN_CASE(AMEDIA_OK)
        RETURN_CASE(AMEDIA_ERROR_UNKNOWN)
        RETURN_CASE(AMEDIA_ERROR_MALFORMED)
        RETURN_CASE(AMEDIA_ERROR_UNSUPPORTED)
        RETURN_CASE(AMEDIA_ERROR_INVALID_OBJECT)
        RETURN_CASE(AMEDIA_ERROR_INVALID_PARAMETER)
        RETURN_CASE(AMEDIA_ERROR_INVALID_OPERATION)
        RETURN_CASE(AMEDIA_DRM_NOT_PROVISIONED)
        RETURN_CASE(AMEDIA_DRM_RESOURCE_BUSY)
        RETURN_CASE(AMEDIA_DRM_DEVICE_REVOKED)
        RETURN_CASE(AMEDIA_DRM_SHORT_BUFFER)
        RETURN_CASE(AMEDIA_DRM_SESSION_NOT_OPENED)
        RETURN_CASE(AMEDIA_DRM_TAMPER_DETECTED)
        RETURN_CASE(AMEDIA_DRM_VERIFY_FAILED)
        RETURN_CASE(AMEDIA_DRM_NEED_KEY)
        RETURN_CASE(AMEDIA_DRM_LICENSE_EXPIRED)
        RETURN_CASE(AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE)
        RETURN_CASE(AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED)
        RETURN_CASE(AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE)
        RETURN_CASE(AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE)
        RETURN_CASE(AMEDIA_IMGREADER_IMAGE_NOT_LOCKED)
        RETURN_DEFAULT(AMEDIA_ERROR_UNKNOWN)
    }
}

static const char *error_state_callback_string(int val)
{
    switch(val) {
        RETURN_CASE(ERROR_CAMERA_IN_USE)
        RETURN_CASE(ERROR_MAX_CAMERAS_IN_USE)
        RETURN_CASE(ERROR_CAMERA_DISABLED)
        RETURN_CASE(ERROR_CAMERA_DEVICE)
        RETURN_CASE(ERROR_CAMERA_SERVICE)
        default:
            return "ERROR_CAMERA_UNKNOWN";
    }
}

static void camera_dev_disconnected(void *context, ACameraDevice *device)
{
    AVFormatContext *avctx = context;
    AndroidCameraCtx *ctx = avctx->priv_data;
    atomic_store(&ctx->exit, 1);
    av_log(avctx, AV_LOG_ERROR, "Camera with id %s disconnected.\n",
           ACameraDevice_getId(device));
}

static void camera_dev_error(void *context, ACameraDevice *device, int error)
{
    AVFormatContext *avctx = context;
    AndroidCameraCtx *ctx = avctx->priv_data;
    atomic_store(&ctx->exit, 1);
    av_log(avctx, AV_LOG_ERROR, "Error %s on camera with id %s.\n",
           error_state_callback_string(error), ACameraDevice_getId(device));
}

static int open_camera(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    camera_status_t ret;
    ACameraIdList *camera_ids;

    ret = ACameraManager_getCameraIdList(ctx->camera_mgr, &camera_ids);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR, "Failed to get camera id list, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    if (ctx->camera_index < camera_ids->numCameras) {
        ctx->camera_id = av_strdup(camera_ids->cameraIds[ctx->camera_index]);
        if (!ctx->camera_id) {
            av_log(avctx, AV_LOG_ERROR, "Failed to allocate memory for camera_id.\n");
            return AVERROR(ENOMEM);
        }
    } else {
        av_log(avctx, AV_LOG_ERROR, "No camera with index %d available.\n",
               ctx->camera_index);
        return AVERROR(ENXIO);
    }

    ACameraManager_deleteCameraIdList(camera_ids);

    ret = ACameraManager_getCameraCharacteristics(ctx->camera_mgr,
            ctx->camera_id, &ctx->camera_metadata);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR, "Failed to get metadata for camera with id %s, error: %s.\n",
               ctx->camera_id, camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ctx->camera_state_callbacks.context = avctx;
    ctx->camera_state_callbacks.onDisconnected = camera_dev_disconnected;
    ctx->camera_state_callbacks.onError = camera_dev_error;

    ret = ACameraManager_openCamera(ctx->camera_mgr, ctx->camera_id,
                                    &ctx->camera_state_callbacks, &ctx->camera_dev);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR, "Failed to open camera with id %s, error: %s.\n",
               ctx->camera_id, camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    return 0;
}

static void get_sensor_orientation(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    ACameraMetadata_const_entry lens_facing;
    ACameraMetadata_const_entry sensor_orientation;

    ACameraMetadata_getConstEntry(ctx->camera_metadata,
                                  ACAMERA_LENS_FACING, &lens_facing);
    ACameraMetadata_getConstEntry(ctx->camera_metadata,
                                  ACAMERA_SENSOR_ORIENTATION, &sensor_orientation);

    ctx->lens_facing = lens_facing.data.u8[0];
    ctx->sensor_orientation = sensor_orientation.data.i32[0];
}

static void match_video_size(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    ACameraMetadata_const_entry available_configs;
    int found = 0;

    ACameraMetadata_getConstEntry(ctx->camera_metadata,
                                  ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
                                  &available_configs);

    for (int i = 0; i < available_configs.count; i++) {
        int32_t input = available_configs.data.i32[i * 4 + 3];
        int32_t format = available_configs.data.i32[i * 4 + 0];

        if (input) {
            continue;
        }

        if (format == IMAGE_FORMAT_ANDROID) {
            int32_t width = available_configs.data.i32[i * 4 + 1];
            int32_t height = available_configs.data.i32[i * 4 + 2];

            //Same ratio
            if ((ctx->requested_width == width && ctx->requested_height == height) ||
                    (ctx->requested_width == height && ctx->requested_height == width)) {
                ctx->width = width;
                ctx->height = height;
                found = 1;
                break;
            }
        }
    }

    if (!found || ctx->width == 0 || ctx->height == 0) {
        ctx->width = available_configs.data.i32[1];
        ctx->height = available_configs.data.i32[2];

        av_log(avctx, AV_LOG_WARNING,
               "Requested video_size %dx%d not available, falling back to %dx%d\n",
               ctx->requested_width, ctx->requested_height, ctx->width, ctx->height);
    }

    return;
}

static void match_framerate(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    ACameraMetadata_const_entry available_framerates;
    int found = 0;
    int current_best_match = -1;
    int requested_framerate = av_q2d(ctx->framerate);

    ACameraMetadata_getConstEntry(ctx->camera_metadata,
                                  ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
                                  &available_framerates);

    for (int i = 0; i < available_framerates.count; i++) {
        int32_t min = available_framerates.data.i32[i * 2 + 0];
        int32_t max = available_framerates.data.i32[i * 2 + 1];

        if (requested_framerate == max) {
            if (min == max) {
                ctx->framerate_range[0] = min;
                ctx->framerate_range[1] = max;
                found = 1;
                break;
            } else if (current_best_match >= 0) {
                int32_t current_best_match_min = available_framerates.data.i32[current_best_match * 2 + 0];
                if (min > current_best_match_min) {
                    current_best_match = i;
                }
            } else {
                current_best_match = i;
            }
        }
    }

    if (!found) {
        if (current_best_match >= 0) {
            ctx->framerate_range[0] = available_framerates.data.i32[current_best_match * 2 + 0];
            ctx->framerate_range[1] = available_framerates.data.i32[current_best_match * 2 + 1];

        } else {
            ctx->framerate_range[0] = available_framerates.data.i32[0];
            ctx->framerate_range[1] = available_framerates.data.i32[1];
        }

        av_log(avctx, AV_LOG_WARNING,
               "Requested framerate %d not available, falling back to min: %d and max: %d fps\n",
               requested_framerate, ctx->framerate_range[0], ctx->framerate_range[1]);
    }

    return;
}

static int get_image_format(AVFormatContext *avctx, AImage *image)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    int32_t image_pixelstrides[2];
    uint8_t *image_plane_data[2];
    int plane_data_length[2];

    for (int i = 0; i < 2; i++) {
        AImage_getPlanePixelStride(image, i + 1, &image_pixelstrides[i]);
        AImage_getPlaneData(image, i + 1, &image_plane_data[i], &plane_data_length[i]);
    }

    if (image_pixelstrides[0] != image_pixelstrides[1]) {
        av_log(avctx, AV_LOG_ERROR,
               "Pixel strides of U and V plane should have been the same.\n");
        return AVERROR_EXTERNAL;
    }

    switch (image_pixelstrides[0]) {
        case 1:
            ctx->image_format = AV_PIX_FMT_YUV420P;
            break;
        case 2:
            if (image_plane_data[0] < image_plane_data[1]) {
                ctx->image_format = AV_PIX_FMT_NV12;
            } else {
                ctx->image_format = AV_PIX_FMT_NV21;
            }
            break;
        default:
            av_log(avctx, AV_LOG_ERROR,
                   "Unknown pixel stride %d of U and V plane, cannot determine camera image format.\n",
                   image_pixelstrides[0]);
            return AVERROR(ENOSYS);
    }

    return 0;
}

static void image_available(void *context, AImageReader *reader)
{
    AVFormatContext *avctx = context;
    AndroidCameraCtx *ctx = avctx->priv_data;
    media_status_t media_status;
    int ret = 0;

    AImage *image;
    int64_t image_timestamp;
    int32_t image_linestrides[4];
    uint8_t *image_plane_data[4];
    int plane_data_length[4];

    AVPacket pkt;
    int pkt_buffer_size = 0;

    media_status = AImageReader_acquireLatestImage(reader, &image);
    if (media_status != AMEDIA_OK) {
        if (media_status == AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) {
            av_log(avctx, AV_LOG_WARNING,
                   "An image reader frame was discarded");
        } else {
            av_log(avctx, AV_LOG_ERROR,
                   "Failed to acquire latest image from image reader, error: %s.\n",
                   media_status_string(media_status));
            ret = AVERROR_EXTERNAL;
        }
        goto error;
    }

    // Silently drop frames when exit is set
    if (atomic_load(&ctx->exit)) {
        goto error;
    }

    // Determine actual image format
    if (!atomic_load(&ctx->got_image_format)) {
        ret = get_image_format(avctx, image);
        if (ret < 0) {
            av_log(avctx, AV_LOG_ERROR,
                   "Could not get image format of camera.\n");
            goto error;
        } else {
            atomic_store(&ctx->got_image_format, 1);
        }
    }

    pkt_buffer_size = av_image_get_buffer_size(ctx->image_format, ctx->width, ctx->height, 32);
    AImage_getTimestamp(image, &image_timestamp);

    AImage_getPlaneRowStride(image, 0, &image_linestrides[0]);
    AImage_getPlaneData(image, 0, &image_plane_data[0], &plane_data_length[0]);

    switch (ctx->image_format) {
        case AV_PIX_FMT_YUV420P:
            AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
            AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
            AImage_getPlaneRowStride(image, 2, &image_linestrides[2]);
            AImage_getPlaneData(image, 2, &image_plane_data[2], &plane_data_length[2]);
            break;
        case AV_PIX_FMT_NV12:
            AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
            AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
            break;
        case AV_PIX_FMT_NV21:
            AImage_getPlaneRowStride(image, 2, &image_linestrides[1]);
            AImage_getPlaneData(image, 2, &image_plane_data[1], &plane_data_length[1]);
            break;
        default:
            av_log(avctx, AV_LOG_ERROR, "Unsupported camera image format.\n");
            ret = AVERROR(ENOSYS);
            goto error;
    }

    ret = av_new_packet(&pkt, pkt_buffer_size);
    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to create new av packet, error: %s.\n", av_err2str(ret));
        goto error;
    }

    pkt.stream_index = VIDEO_STREAM_INDEX;
    pkt.pts = image_timestamp;
    av_image_copy_to_buffer(pkt.data, pkt_buffer_size,
                            (const uint8_t * const *) image_plane_data,
                            image_linestrides, ctx->image_format,
                            ctx->width, ctx->height, 32);

    ret = av_thread_message_queue_send(ctx->input_queue, &pkt, AV_THREAD_MESSAGE_NONBLOCK);

error:
    if (ret < 0) {
        if (ret != AVERROR(EAGAIN)) {
            av_log(avctx, AV_LOG_ERROR,
                   "Error while processing new image, error: %s.\n", av_err2str(ret));
            av_thread_message_queue_set_err_recv(ctx->input_queue, ret);
            atomic_store(&ctx->exit, 1);
        } else {
            av_log(avctx, AV_LOG_WARNING,
                   "Input queue was full, dropping frame, consider raising the input_queue_size option (current value: %d)\n",
                   ctx->input_queue_size);
        }
        if (pkt_buffer_size) {
            av_packet_unref(&pkt);
        }
    }

    AImage_delete(image);

    return;
}

static int create_image_reader(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    media_status_t ret;

    ret = AImageReader_new(ctx->width, ctx->height, IMAGE_FORMAT_ANDROID,
                           MAX_BUF_COUNT, &ctx->image_reader);
    if (ret != AMEDIA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to create image reader, error: %s.\n", media_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ctx->image_listener.context = avctx;
    ctx->image_listener.onImageAvailable = image_available;

    ret = AImageReader_setImageListener(ctx->image_reader, &ctx->image_listener);
    if (ret != AMEDIA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to set image listener on image reader, error: %s.\n",
               media_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ret = AImageReader_getWindow(ctx->image_reader, &ctx->image_reader_window);
    if (ret != AMEDIA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Could not get image reader window, error: %s.\n",
               media_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    return 0;
}

static void capture_session_closed(void *context, ACameraCaptureSession *session)
{
    av_log(context, AV_LOG_INFO, "Android camera capture session was closed.\n");
}

static void capture_session_ready(void *context, ACameraCaptureSession *session)
{
    av_log(context, AV_LOG_INFO, "Android camera capture session is ready.\n");
}

static void capture_session_active(void *context, ACameraCaptureSession *session)
{
    av_log(context, AV_LOG_INFO, "Android camera capture session is active.\n");
}

static int create_capture_session(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    camera_status_t ret;

    ret = ACaptureSessionOutputContainer_create(&ctx->capture_session_output_container);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to create capture session output container, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ANativeWindow_acquire(ctx->image_reader_window);

    ret = ACaptureSessionOutput_create(ctx->image_reader_window, &ctx->capture_session_output);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to create capture session container, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ret = ACaptureSessionOutputContainer_add(ctx->capture_session_output_container,
                                             ctx->capture_session_output);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to add output to output container, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ret = ACameraOutputTarget_create(ctx->image_reader_window, &ctx->camera_output_target);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to create camera output target, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ret = ACameraDevice_createCaptureRequest(ctx->camera_dev, TEMPLATE_RECORD, &ctx->capture_request);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to create capture request, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ret = ACaptureRequest_setEntry_i32(ctx->capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,
                                       2, ctx->framerate_range);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to set target fps range in capture request, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ret = ACaptureRequest_addTarget(ctx->capture_request, ctx->camera_output_target);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to add capture request capture request, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ctx->capture_session_state_callbacks.context = avctx;
    ctx->capture_session_state_callbacks.onClosed = capture_session_closed;
    ctx->capture_session_state_callbacks.onReady = capture_session_ready;
    ctx->capture_session_state_callbacks.onActive = capture_session_active;

    ret = ACameraDevice_createCaptureSession(ctx->camera_dev, ctx->capture_session_output_container,
                                             &ctx->capture_session_state_callbacks, &ctx->capture_session);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to create capture session, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    ret = ACameraCaptureSession_setRepeatingRequest(ctx->capture_session, NULL, 1, &ctx->capture_request, NULL);
    if (ret != ACAMERA_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to set repeating request on capture session, error: %s.\n",
               camera_status_string(ret));
        return AVERROR_EXTERNAL;
    }

    return 0;
}

static int wait_for_image_format(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;

    while (!atomic_load(&ctx->got_image_format) && !atomic_load(&ctx->exit)) {
        //Wait until first frame arrived and actual image format was determined
        usleep(1000);
    }

    return atomic_load(&ctx->got_image_format);
}

static int add_display_matrix(AVFormatContext *avctx, AVStream *st)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    uint8_t *side_data;
    int32_t display_matrix[9];

    av_display_rotation_set(display_matrix, ctx->sensor_orientation);

    if (ctx->lens_facing == ACAMERA_LENS_FACING_FRONT) {
        av_display_matrix_flip(display_matrix, 1, 0);
    }

    side_data = av_stream_new_side_data(st,
            AV_PKT_DATA_DISPLAYMATRIX, sizeof(display_matrix));

    if (!side_data) {
        return AVERROR(ENOMEM);
    }

    memcpy(side_data, display_matrix, sizeof(display_matrix));

    return 0;
}

static int add_video_stream(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    AVStream *st;
    AVCodecParameters *codecpar;

    st = avformat_new_stream(avctx, NULL);
    if (!st) {
        return AVERROR(ENOMEM);
    }

    st->id = VIDEO_STREAM_INDEX;
    st->avg_frame_rate = (AVRational) { ctx->framerate_range[1], 1 };
    st->r_frame_rate = (AVRational) { ctx->framerate_range[1], 1 };

    if (!wait_for_image_format(avctx)) {
        return AVERROR_EXTERNAL;
    }

    codecpar = st->codecpar;
    codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    codecpar->codec_id = AV_CODEC_ID_RAWVIDEO;
    codecpar->format = ctx->image_format;
    codecpar->width = ctx->width;
    codecpar->height = ctx->height;

    avpriv_set_pts_info(st, 64, 1, VIDEO_TIMEBASE_ANDROID);

    return add_display_matrix(avctx, st);
}

static int android_camera_read_close(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;

    atomic_store(&ctx->exit, 1);

    if (ctx->capture_session) {
        ACameraCaptureSession_stopRepeating(ctx->capture_session);
        // Following warning is emitted, after capture session closed callback is received:
        // ACameraCaptureSession: Device is closed but session 0 is not notified
        // Seems to be a bug in Android, we can ignore this
        ACameraCaptureSession_close(ctx->capture_session);
        ctx->capture_session = NULL;
    }

    if (ctx->capture_request) {
        ACaptureRequest_removeTarget(ctx->capture_request, ctx->camera_output_target);
        ACaptureRequest_free(ctx->capture_request);
        ctx->capture_request = NULL;
    }

    if (ctx->camera_output_target) {
        ACameraOutputTarget_free(ctx->camera_output_target);
        ctx->camera_output_target = NULL;
    }

    if (ctx->capture_session_output) {
        ACaptureSessionOutputContainer_remove(ctx->capture_session_output_container,
                ctx->capture_session_output);
        ACaptureSessionOutput_free(ctx->capture_session_output);
        ctx->capture_session_output = NULL;
    }

    if (ctx->image_reader_window) {
        ANativeWindow_release(ctx->image_reader_window);
        ctx->image_reader_window = NULL;
    }

    if (ctx->capture_session_output_container) {
        ACaptureSessionOutputContainer_free(ctx->capture_session_output_container);
        ctx->capture_session_output_container = NULL;
    }

    if (ctx->camera_dev) {
        ACameraDevice_close(ctx->camera_dev);
        ctx->camera_dev = NULL;
    }

    if (ctx->image_reader) {
        AImageReader_delete(ctx->image_reader);
        ctx->image_reader = NULL;
    }

    if (ctx->camera_metadata) {
        ACameraMetadata_free(ctx->camera_metadata);
        ctx->camera_metadata = NULL;
    }

    av_freep(&ctx->camera_id);

    if (ctx->camera_mgr) {
        ACameraManager_delete(ctx->camera_mgr);
        ctx->camera_mgr = NULL;
    }

    if (ctx->input_queue) {
        AVPacket pkt;
        av_thread_message_queue_set_err_send(ctx->input_queue, AVERROR_EOF);
        while (av_thread_message_queue_recv(ctx->input_queue, &pkt, AV_THREAD_MESSAGE_NONBLOCK) >= 0) {
            av_packet_unref(&pkt);
        }
        av_thread_message_queue_free(&ctx->input_queue);
    }

    return 0;
}

static int android_camera_read_header(AVFormatContext *avctx)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    int ret;

    atomic_init(&ctx->got_image_format, 0);
    atomic_init(&ctx->exit, 0);

    ret = av_thread_message_queue_alloc(&ctx->input_queue, ctx->input_queue_size, sizeof(AVPacket));
    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to allocate input queue, error: %s.\n", av_err2str(ret));
        goto error;
    }

    ctx->camera_mgr = ACameraManager_create();
    if (!ctx->camera_mgr) {
        av_log(avctx, AV_LOG_ERROR, "Failed to create Android camera manager.\n");
        ret = AVERROR_EXTERNAL;
        goto error;
    }

    ret = open_camera(avctx);
    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR, "Failed to open camera.\n");
        goto error;
    }

    get_sensor_orientation(avctx);
    match_video_size(avctx);
    match_framerate(avctx);

    ret = create_image_reader(avctx);
    if (ret < 0) {
        goto error;
    }

    ret = create_capture_session(avctx);
    if (ret < 0) {
        goto error;
    }

    ret = add_video_stream(avctx);

error:
    if (ret < 0) {
        android_camera_read_close(avctx);
        av_log(avctx, AV_LOG_ERROR, "Failed to open android_camera.\n");
    }

    return ret;
}

static int android_camera_read_packet(AVFormatContext *avctx, AVPacket *pkt)
{
    AndroidCameraCtx *ctx = avctx->priv_data;
    int ret;

    if (!atomic_load(&ctx->exit)) {
        ret = av_thread_message_queue_recv(ctx->input_queue, pkt,
                avctx->flags & AVFMT_FLAG_NONBLOCK ? AV_THREAD_MESSAGE_NONBLOCK : 0);
    } else {
        ret = AVERROR_EOF;
    }

    if (ret < 0) {
        return ret;
    } else {
        return pkt->size;
    }
}

#define OFFSET(x) offsetof(AndroidCameraCtx, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
    { "video_size", "set video size given as a string such as 640x480 or hd720", OFFSET(requested_width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC },
    { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "30"}, 0, INT_MAX, DEC },
    { "camera_index", "set index of camera to use", OFFSET(camera_index), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
    { "input_queue_size", "set maximum number of frames to buffer", OFFSET(input_queue_size), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, DEC },
    { NULL },
};

static const AVClass android_camera_class = {
    .class_name = "android_camera indev",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
    .category   = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,
};

AVInputFormat ff_android_camera_demuxer = {
    .name           = "android_camera",
    .long_name      = NULL_IF_CONFIG_SMALL("Android camera input device"),
    .priv_data_size = sizeof(AndroidCameraCtx),
    .read_header    = android_camera_read_header,
    .read_packet    = android_camera_read_packet,
    .read_close     = android_camera_read_close,
    .flags          = AVFMT_NOFILE,
    .priv_class     = &android_camera_class,
};
