25 #include <stdatomic.h> 
   29 #include <camera/NdkCameraDevice.h> 
   30 #include <camera/NdkCameraManager.h> 
   31 #include <media/NdkImage.h> 
   32 #include <media/NdkImageReader.h> 
   48 #define IMAGE_FORMAT_ANDROID AIMAGE_FORMAT_YUV_420_888 
   50 #define MAX_BUF_COUNT 2 
   51 #define VIDEO_STREAM_INDEX 0 
   52 #define VIDEO_TIMEBASE_ANDROID 1000000000 
   54 #define RETURN_CASE(x) case x: return AV_STRINGIFY(x); 
   55 #define RETURN_DEFAULT(x) default: return AV_STRINGIFY(x); 
  152             return "ERROR_CAMERA_UNKNOWN";
 
  162            ACameraDevice_getId(device));
 
  178     ACameraIdList *camera_ids;
 
  180     ret = ACameraManager_getCameraIdList(
ctx->camera_mgr, &camera_ids);
 
  181     if (
ret != ACAMERA_OK) {
 
  187     if (
ctx->camera_index < camera_ids->numCameras) {
 
  189         if (!
ctx->camera_id) {
 
  199     ACameraManager_deleteCameraIdList(camera_ids);
 
  201     ret = ACameraManager_getCameraCharacteristics(
ctx->camera_mgr,
 
  202             ctx->camera_id, &
ctx->camera_metadata);
 
  203     if (
ret != ACAMERA_OK) {
 
  204         av_log(avctx, 
AV_LOG_ERROR, 
"Failed to get metadata for camera with id %s, error: %s.\n",
 
  209     ctx->camera_state_callbacks.context = avctx;
 
  213     ret = ACameraManager_openCamera(
ctx->camera_mgr, 
ctx->camera_id,
 
  214                                     &
ctx->camera_state_callbacks, &
ctx->camera_dev);
 
  215     if (
ret != ACAMERA_OK) {
 
  227     ACameraMetadata_const_entry lens_facing;
 
  228     ACameraMetadata_const_entry sensor_orientation;
 
  230     ACameraMetadata_getConstEntry(
ctx->camera_metadata,
 
  231                                   ACAMERA_LENS_FACING, &lens_facing);
 
  232     ACameraMetadata_getConstEntry(
ctx->camera_metadata,
 
  233                                   ACAMERA_SENSOR_ORIENTATION, &sensor_orientation);
 
  235     ctx->lens_facing = lens_facing.data.u8[0];
 
  236     ctx->sensor_orientation = sensor_orientation.data.i32[0];
 
  242     ACameraMetadata_const_entry available_configs;
 
  245     ACameraMetadata_getConstEntry(
ctx->camera_metadata,
 
  246                                   ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
 
  249     for (
int i = 0; 
i < available_configs.count; 
i++) {
 
  272     if (!found || 
ctx->width == 0 || 
ctx->height == 0) {
 
  273         ctx->width = available_configs.data.i32[1];
 
  274         ctx->height = available_configs.data.i32[2];
 
  277                "Requested video_size %dx%d not available, falling back to %dx%d\n",
 
  278                ctx->requested_width, 
ctx->requested_height, 
ctx->width, 
ctx->height);
 
  287     ACameraMetadata_const_entry available_framerates;
 
  289     int current_best_match = -1;
 
  290     int requested_framerate = 
av_q2d(
ctx->framerate);
 
  292     ACameraMetadata_getConstEntry(
ctx->camera_metadata,
 
  293                                   ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
 
  294                                   &available_framerates);
 
  296     for (
int i = 0; 
i < available_framerates.count; 
i++) {
 
  297         int32_t min = available_framerates.data.i32[
i * 2 + 0];
 
  298         int32_t max = available_framerates.data.i32[
i * 2 + 1];
 
  300         if (requested_framerate == 
max) {
 
  302                 ctx->framerate_range[0] = 
min;
 
  303                 ctx->framerate_range[1] = 
max;
 
  306             } 
else if (current_best_match >= 0) {
 
  307                 int32_t current_best_match_min = available_framerates.data.i32[current_best_match * 2 + 0];
 
  308                 if (
min > current_best_match_min) {
 
  309                     current_best_match = 
i;
 
  312                 current_best_match = 
i;
 
  318         if (current_best_match >= 0) {
 
  319             ctx->framerate_range[0] = available_framerates.data.i32[current_best_match * 2 + 0];
 
  320             ctx->framerate_range[1] = available_framerates.data.i32[current_best_match * 2 + 1];
 
  323             ctx->framerate_range[0] = available_framerates.data.i32[0];
 
  324             ctx->framerate_range[1] = available_framerates.data.i32[1];
 
  328                "Requested framerate %d not available, falling back to min: %d and max: %d fps\n",
 
  329                requested_framerate, 
ctx->framerate_range[0], 
ctx->framerate_range[1]);
 
  339     uint8_t *image_plane_data[2];
 
  340     int plane_data_length[2];
 
  342     for (
int i = 0; 
i < 2; 
i++) {
 
  343         AImage_getPlanePixelStride(image, 
i + 1, &image_pixelstrides[
i]);
 
  344         AImage_getPlaneData(image, 
i + 1, &image_plane_data[
i], &plane_data_length[
i]);
 
  347     if (image_pixelstrides[0] != image_pixelstrides[1]) {
 
  349                "Pixel strides of U and V plane should have been the same.\n");
 
  353     switch (image_pixelstrides[0]) {
 
  358             if (image_plane_data[0] < image_plane_data[1]) {
 
  366                    "Unknown pixel stride %d of U and V plane, cannot determine camera image format.\n",
 
  367                    image_pixelstrides[0]);
 
  378     media_status_t media_status;
 
  382     int64_t image_timestamp;
 
  384     uint8_t *image_plane_data[4];
 
  385     int plane_data_length[4];
 
  388     int pkt_buffer_size = 0;
 
  390     media_status = AImageReader_acquireLatestImage(reader, &image);
 
  391     if (media_status != AMEDIA_OK) {
 
  392         if (media_status == AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) {
 
  394                    "An image reader frame was discarded");
 
  397                    "Failed to acquire latest image from image reader, error: %s.\n",
 
  414                    "Could not get image format of camera.\n");
 
  422     AImage_getTimestamp(image, &image_timestamp);
 
  424     AImage_getPlaneRowStride(image, 0, &image_linestrides[0]);
 
  425     AImage_getPlaneData(image, 0, &image_plane_data[0], &plane_data_length[0]);
 
  427     switch (
ctx->image_format) {
 
  429             AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
 
  430             AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
 
  431             AImage_getPlaneRowStride(image, 2, &image_linestrides[2]);
 
  432             AImage_getPlaneData(image, 2, &image_plane_data[2], &plane_data_length[2]);
 
  435             AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
 
  436             AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
 
  439             AImage_getPlaneRowStride(image, 2, &image_linestrides[1]);
 
  440             AImage_getPlaneData(image, 2, &image_plane_data[1], &plane_data_length[1]);
 
  451                "Failed to create new av packet, error: %s.\n", 
av_err2str(
ret));
 
  456     pkt.
pts = image_timestamp;
 
  458                             (
const uint8_t * 
const *) image_plane_data,
 
  459                             image_linestrides, 
ctx->image_format,
 
  460                             ctx->width, 
ctx->height, 32);
 
  468                    "Error while processing new image, error: %s.\n", 
av_err2str(
ret));
 
  473                    "Input queue was full, dropping frame, consider raising the input_queue_size option (current value: %d)\n",
 
  474                    ctx->input_queue_size);
 
  476         if (pkt_buffer_size) {
 
  481     AImage_delete(image);
 
  493     if (
ret != AMEDIA_OK) {
 
  499     ctx->image_listener.context = avctx;
 
  502     ret = AImageReader_setImageListener(
ctx->image_reader, &
ctx->image_listener);
 
  503     if (
ret != AMEDIA_OK) {
 
  505                "Failed to set image listener on image reader, error: %s.\n",
 
  510     ret = AImageReader_getWindow(
ctx->image_reader, &
ctx->image_reader_window);
 
  511     if (
ret != AMEDIA_OK) {
 
  513                "Could not get image reader window, error: %s.\n",
 
  541     ret = ACaptureSessionOutputContainer_create(&
ctx->capture_session_output_container);
 
  542     if (
ret != ACAMERA_OK) {
 
  544                "Failed to create capture session output container, error: %s.\n",
 
  549     ANativeWindow_acquire(
ctx->image_reader_window);
 
  551     ret = ACaptureSessionOutput_create(
ctx->image_reader_window, &
ctx->capture_session_output);
 
  552     if (
ret != ACAMERA_OK) {
 
  554                "Failed to create capture session container, error: %s.\n",
 
  559     ret = ACaptureSessionOutputContainer_add(
ctx->capture_session_output_container,
 
  560                                              ctx->capture_session_output);
 
  561     if (
ret != ACAMERA_OK) {
 
  563                "Failed to add output to output container, error: %s.\n",
 
  568     ret = ACameraOutputTarget_create(
ctx->image_reader_window, &
ctx->camera_output_target);
 
  569     if (
ret != ACAMERA_OK) {
 
  571                "Failed to create camera output target, error: %s.\n",
 
  576     ret = ACameraDevice_createCaptureRequest(
ctx->camera_dev, TEMPLATE_RECORD, &
ctx->capture_request);
 
  577     if (
ret != ACAMERA_OK) {
 
  579                "Failed to create capture request, error: %s.\n",
 
  584     ret = ACaptureRequest_setEntry_i32(
ctx->capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,
 
  585                                        2, 
ctx->framerate_range);
 
  586     if (
ret != ACAMERA_OK) {
 
  588                "Failed to set target fps range in capture request, error: %s.\n",
 
  593     ret = ACaptureRequest_addTarget(
ctx->capture_request, 
ctx->camera_output_target);
 
  594     if (
ret != ACAMERA_OK) {
 
  596                "Failed to add capture request capture request, error: %s.\n",
 
  601     ctx->capture_session_state_callbacks.context = avctx;
 
  606     ret = ACameraDevice_createCaptureSession(
ctx->camera_dev, 
ctx->capture_session_output_container,
 
  607                                              &
ctx->capture_session_state_callbacks, &
ctx->capture_session);
 
  608     if (
ret != ACAMERA_OK) {
 
  610                "Failed to create capture session, error: %s.\n",
 
  615     ret = ACameraCaptureSession_setRepeatingRequest(
ctx->capture_session, 
NULL, 1, &
ctx->capture_request, 
NULL);
 
  616     if (
ret != ACAMERA_OK) {
 
  618                "Failed to set repeating request on capture session, error: %s.\n",
 
  646     if (
ctx->lens_facing == ACAMERA_LENS_FACING_FRONT) {
 
  657     memcpy(side_data, display_matrix, 
sizeof(display_matrix));
 
  699     if (
ctx->capture_session) {
 
  700         ACameraCaptureSession_stopRepeating(
ctx->capture_session);
 
  704         ACameraCaptureSession_close(
ctx->capture_session);
 
  708     if (
ctx->capture_request) {
 
  709         ACaptureRequest_removeTarget(
ctx->capture_request, 
ctx->camera_output_target);
 
  710         ACaptureRequest_free(
ctx->capture_request);
 
  714     if (
ctx->camera_output_target) {
 
  715         ACameraOutputTarget_free(
ctx->camera_output_target);
 
  716         ctx->camera_output_target = 
NULL;
 
  719     if (
ctx->capture_session_output) {
 
  720         ACaptureSessionOutputContainer_remove(
ctx->capture_session_output_container,
 
  721                 ctx->capture_session_output);
 
  722         ACaptureSessionOutput_free(
ctx->capture_session_output);
 
  723         ctx->capture_session_output = 
NULL;
 
  726     if (
ctx->image_reader_window) {
 
  727         ANativeWindow_release(
ctx->image_reader_window);
 
  728         ctx->image_reader_window = 
NULL;
 
  731     if (
ctx->capture_session_output_container) {
 
  732         ACaptureSessionOutputContainer_free(
ctx->capture_session_output_container);
 
  733         ctx->capture_session_output_container = 
NULL;
 
  736     if (
ctx->camera_dev) {
 
  737         ACameraDevice_close(
ctx->camera_dev);
 
  741     if (
ctx->image_reader) {
 
  742         AImageReader_delete(
ctx->image_reader);
 
  746     if (
ctx->camera_metadata) {
 
  747         ACameraMetadata_free(
ctx->camera_metadata);
 
  753     if (
ctx->camera_mgr) {
 
  754         ACameraManager_delete(
ctx->camera_mgr);
 
  758     if (
ctx->input_queue) {
 
  781                "Failed to allocate input queue, error: %s.\n", 
av_err2str(
ret));
 
  785     ctx->camera_mgr = ACameraManager_create();
 
  786     if (!
ctx->camera_mgr) {
 
  842 #define OFFSET(x) offsetof(AndroidCameraCtx, x) 
  843 #define DEC AV_OPT_FLAG_DECODING_PARAM 
  847     { 
"camera_index", 
"set index of camera to use", 
OFFSET(camera_index), 
AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, 
DEC },
 
  848     { 
"input_queue_size", 
"set maximum number of frames to buffer", 
OFFSET(input_queue_size), 
AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, 
DEC },
 
  861     .
name           = 
"android_camera",