25 #include <stdatomic.h> 
   30 #include <camera/NdkCameraDevice.h> 
   31 #include <camera/NdkCameraManager.h> 
   32 #include <media/NdkImage.h> 
   33 #include <media/NdkImageReader.h> 
   51 #define IMAGE_FORMAT_ANDROID AIMAGE_FORMAT_YUV_420_888 
   53 #define MAX_BUF_COUNT 2 
   54 #define VIDEO_STREAM_INDEX 0 
   55 #define VIDEO_TIMEBASE_ANDROID 1000000000 
   57 #define RETURN_CASE(x) case x: return AV_STRINGIFY(x); 
   58 #define RETURN_DEFAULT(x) default: return AV_STRINGIFY(x); 
  155             return "ERROR_CAMERA_UNKNOWN";
 
  165            ACameraDevice_getId(device));
 
  181     ACameraIdList *camera_ids;
 
  183     ret = ACameraManager_getCameraIdList(
ctx->camera_mgr, &camera_ids);
 
  184     if (
ret != ACAMERA_OK) {
 
  190     if (
ctx->camera_index < camera_ids->numCameras) {
 
  192         if (!
ctx->camera_id) {
 
  202     ACameraManager_deleteCameraIdList(camera_ids);
 
  204     ret = ACameraManager_getCameraCharacteristics(
ctx->camera_mgr,
 
  205             ctx->camera_id, &
ctx->camera_metadata);
 
  206     if (
ret != ACAMERA_OK) {
 
  207         av_log(avctx, 
AV_LOG_ERROR, 
"Failed to get metadata for camera with id %s, error: %s.\n",
 
  212     ctx->camera_state_callbacks.context = avctx;
 
  216     ret = ACameraManager_openCamera(
ctx->camera_mgr, 
ctx->camera_id,
 
  217                                     &
ctx->camera_state_callbacks, &
ctx->camera_dev);
 
  218     if (
ret != ACAMERA_OK) {
 
  230     ACameraMetadata_const_entry lens_facing;
 
  231     ACameraMetadata_const_entry sensor_orientation;
 
  233     ACameraMetadata_getConstEntry(
ctx->camera_metadata,
 
  234                                   ACAMERA_LENS_FACING, &lens_facing);
 
  235     ACameraMetadata_getConstEntry(
ctx->camera_metadata,
 
  236                                   ACAMERA_SENSOR_ORIENTATION, &sensor_orientation);
 
  238     ctx->lens_facing = lens_facing.data.u8[0];
 
  239     ctx->sensor_orientation = sensor_orientation.data.i32[0];
 
  245     ACameraMetadata_const_entry available_configs;
 
  248     ACameraMetadata_getConstEntry(
ctx->camera_metadata,
 
  249                                   ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
 
  252     for (
int i = 0; 
i < available_configs.count; 
i++) {
 
  275     if (!found || 
ctx->width == 0 || 
ctx->height == 0) {
 
  276         ctx->width = available_configs.data.i32[1];
 
  277         ctx->height = available_configs.data.i32[2];
 
  280                "Requested video_size %dx%d not available, falling back to %dx%d\n",
 
  281                ctx->requested_width, 
ctx->requested_height, 
ctx->width, 
ctx->height);
 
  290     ACameraMetadata_const_entry available_framerates;
 
  292     int current_best_match = -1;
 
  293     int requested_framerate = 
av_q2d(
ctx->framerate);
 
  295     ACameraMetadata_getConstEntry(
ctx->camera_metadata,
 
  296                                   ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
 
  297                                   &available_framerates);
 
  299     for (
int i = 0; 
i < available_framerates.count; 
i++) {
 
  300         int32_t min = available_framerates.data.i32[
i * 2 + 0];
 
  301         int32_t max = available_framerates.data.i32[
i * 2 + 1];
 
  303         if (requested_framerate == 
max) {
 
  305                 ctx->framerate_range[0] = 
min;
 
  306                 ctx->framerate_range[1] = 
max;
 
  309             } 
else if (current_best_match >= 0) {
 
  310                 int32_t current_best_match_min = available_framerates.data.i32[current_best_match * 2 + 0];
 
  311                 if (
min > current_best_match_min) {
 
  312                     current_best_match = 
i;
 
  315                 current_best_match = 
i;
 
  321         if (current_best_match >= 0) {
 
  322             ctx->framerate_range[0] = available_framerates.data.i32[current_best_match * 2 + 0];
 
  323             ctx->framerate_range[1] = available_framerates.data.i32[current_best_match * 2 + 1];
 
  326             ctx->framerate_range[0] = available_framerates.data.i32[0];
 
  327             ctx->framerate_range[1] = available_framerates.data.i32[1];
 
  331                "Requested framerate %d not available, falling back to min: %d and max: %d fps\n",
 
  332                requested_framerate, 
ctx->framerate_range[0], 
ctx->framerate_range[1]);
 
  342     uint8_t *image_plane_data[2];
 
  343     int plane_data_length[2];
 
  345     for (
int i = 0; 
i < 2; 
i++) {
 
  346         AImage_getPlanePixelStride(image, 
i + 1, &image_pixelstrides[
i]);
 
  347         AImage_getPlaneData(image, 
i + 1, &image_plane_data[
i], &plane_data_length[
i]);
 
  350     if (image_pixelstrides[0] != image_pixelstrides[1]) {
 
  352                "Pixel strides of U and V plane should have been the same.\n");
 
  356     switch (image_pixelstrides[0]) {
 
  361             if (image_plane_data[0] < image_plane_data[1]) {
 
  369                    "Unknown pixel stride %d of U and V plane, cannot determine camera image format.\n",
 
  370                    image_pixelstrides[0]);
 
  381     media_status_t media_status;
 
  387     uint8_t *image_plane_data[4];
 
  388     int plane_data_length[4];
 
  391     int pkt_buffer_size = 0;
 
  393     media_status = AImageReader_acquireLatestImage(reader, &image);
 
  394     if (media_status != AMEDIA_OK) {
 
  395         if (media_status == AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) {
 
  397                    "An image reader frame was discarded");
 
  400                    "Failed to acquire latest image from image reader, error: %s.\n",
 
  417                    "Could not get image format of camera.\n");
 
  425     AImage_getTimestamp(image, &image_timestamp);
 
  427     AImage_getPlaneRowStride(image, 0, &image_linestrides[0]);
 
  428     AImage_getPlaneData(image, 0, &image_plane_data[0], &plane_data_length[0]);
 
  430     switch (
ctx->image_format) {
 
  432             AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
 
  433             AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
 
  434             AImage_getPlaneRowStride(image, 2, &image_linestrides[2]);
 
  435             AImage_getPlaneData(image, 2, &image_plane_data[2], &plane_data_length[2]);
 
  438             AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
 
  439             AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
 
  442             AImage_getPlaneRowStride(image, 2, &image_linestrides[1]);
 
  443             AImage_getPlaneData(image, 2, &image_plane_data[1], &plane_data_length[1]);
 
  454                "Failed to create new av packet, error: %s.\n", 
av_err2str(
ret));
 
  459     pkt.
pts = image_timestamp;
 
  461                             (
const uint8_t * 
const *) image_plane_data,
 
  462                             image_linestrides, 
ctx->image_format,
 
  463                             ctx->width, 
ctx->height, 1);
 
  471                    "Error while processing new image, error: %s.\n", 
av_err2str(
ret));
 
  476                    "Input queue was full, dropping frame, consider raising the input_queue_size option (current value: %d)\n",
 
  477                    ctx->input_queue_size);
 
  479         if (pkt_buffer_size) {
 
  484     AImage_delete(image);
 
  496     if (
ret != AMEDIA_OK) {
 
  502     ctx->image_listener.context = avctx;
 
  505     ret = AImageReader_setImageListener(
ctx->image_reader, &
ctx->image_listener);
 
  506     if (
ret != AMEDIA_OK) {
 
  508                "Failed to set image listener on image reader, error: %s.\n",
 
  513     ret = AImageReader_getWindow(
ctx->image_reader, &
ctx->image_reader_window);
 
  514     if (
ret != AMEDIA_OK) {
 
  516                "Could not get image reader window, error: %s.\n",
 
  544     ret = ACaptureSessionOutputContainer_create(&
ctx->capture_session_output_container);
 
  545     if (
ret != ACAMERA_OK) {
 
  547                "Failed to create capture session output container, error: %s.\n",
 
  552     ANativeWindow_acquire(
ctx->image_reader_window);
 
  554     ret = ACaptureSessionOutput_create(
ctx->image_reader_window, &
ctx->capture_session_output);
 
  555     if (
ret != ACAMERA_OK) {
 
  557                "Failed to create capture session container, error: %s.\n",
 
  562     ret = ACaptureSessionOutputContainer_add(
ctx->capture_session_output_container,
 
  563                                              ctx->capture_session_output);
 
  564     if (
ret != ACAMERA_OK) {
 
  566                "Failed to add output to output container, error: %s.\n",
 
  571     ret = ACameraOutputTarget_create(
ctx->image_reader_window, &
ctx->camera_output_target);
 
  572     if (
ret != ACAMERA_OK) {
 
  574                "Failed to create camera output target, error: %s.\n",
 
  579     ret = ACameraDevice_createCaptureRequest(
ctx->camera_dev, TEMPLATE_RECORD, &
ctx->capture_request);
 
  580     if (
ret != ACAMERA_OK) {
 
  582                "Failed to create capture request, error: %s.\n",
 
  587     ret = ACaptureRequest_setEntry_i32(
ctx->capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,
 
  588                                        2, 
ctx->framerate_range);
 
  589     if (
ret != ACAMERA_OK) {
 
  591                "Failed to set target fps range in capture request, error: %s.\n",
 
  596     ret = ACaptureRequest_addTarget(
ctx->capture_request, 
ctx->camera_output_target);
 
  597     if (
ret != ACAMERA_OK) {
 
  599                "Failed to add capture request capture request, error: %s.\n",
 
  604     ctx->capture_session_state_callbacks.context = avctx;
 
  609     ret = ACameraDevice_createCaptureSession(
ctx->camera_dev, 
ctx->capture_session_output_container,
 
  610                                              &
ctx->capture_session_state_callbacks, &
ctx->capture_session);
 
  611     if (
ret != ACAMERA_OK) {
 
  613                "Failed to create capture session, error: %s.\n",
 
  618     ret = ACameraCaptureSession_setRepeatingRequest(
ctx->capture_session, 
NULL, 1, &
ctx->capture_request, 
NULL);
 
  619     if (
ret != ACAMERA_OK) {
 
  621                "Failed to set repeating request on capture session, error: %s.\n",
 
  649     if (
ctx->lens_facing == ACAMERA_LENS_FACING_FRONT) {
 
  656                                         sizeof(display_matrix), 0);
 
  662     memcpy(side_data->
data, display_matrix, 
sizeof(display_matrix));
 
  704     if (
ctx->capture_session) {
 
  705         ACameraCaptureSession_stopRepeating(
ctx->capture_session);
 
  709         ACameraCaptureSession_close(
ctx->capture_session);
 
  713     if (
ctx->capture_request) {
 
  714         ACaptureRequest_removeTarget(
ctx->capture_request, 
ctx->camera_output_target);
 
  715         ACaptureRequest_free(
ctx->capture_request);
 
  719     if (
ctx->camera_output_target) {
 
  720         ACameraOutputTarget_free(
ctx->camera_output_target);
 
  721         ctx->camera_output_target = 
NULL;
 
  724     if (
ctx->capture_session_output) {
 
  725         ACaptureSessionOutputContainer_remove(
ctx->capture_session_output_container,
 
  726                 ctx->capture_session_output);
 
  727         ACaptureSessionOutput_free(
ctx->capture_session_output);
 
  728         ctx->capture_session_output = 
NULL;
 
  731     if (
ctx->image_reader_window) {
 
  732         ANativeWindow_release(
ctx->image_reader_window);
 
  733         ctx->image_reader_window = 
NULL;
 
  736     if (
ctx->capture_session_output_container) {
 
  737         ACaptureSessionOutputContainer_free(
ctx->capture_session_output_container);
 
  738         ctx->capture_session_output_container = 
NULL;
 
  741     if (
ctx->camera_dev) {
 
  742         ACameraDevice_close(
ctx->camera_dev);
 
  746     if (
ctx->image_reader) {
 
  747         AImageReader_delete(
ctx->image_reader);
 
  751     if (
ctx->camera_metadata) {
 
  752         ACameraMetadata_free(
ctx->camera_metadata);
 
  758     if (
ctx->camera_mgr) {
 
  759         ACameraManager_delete(
ctx->camera_mgr);
 
  763     if (
ctx->input_queue) {
 
  786                "Failed to allocate input queue, error: %s.\n", 
av_err2str(
ret));
 
  790     ctx->camera_mgr = ACameraManager_create();
 
  791     if (!
ctx->camera_mgr) {
 
  847 #define OFFSET(x) offsetof(AndroidCameraCtx, x) 
  848 #define DEC AV_OPT_FLAG_DECODING_PARAM 
  852     { 
"camera_index", 
"set index of camera to use", 
OFFSET(camera_index), 
AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, 
DEC },
 
  853     { 
"input_queue_size", 
"set maximum number of frames to buffer", 
OFFSET(input_queue_size), 
AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, 
DEC },
 
  866     .
p.
name         = 
"android_camera",