[FFmpeg-devel] [PATCH] Add android_capture indev

Michael Niedermayer michael at niedermayer.cc
Wed Dec 20 23:00:10 EET 2017


On Fri, Dec 08, 2017 at 10:49:56AM +0100, Felix Matouschek wrote:
[...]
> +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]);

missing memory allocation failure check


> +    } 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_width == height) &&
> +                    (ctx->requested_height == width || ctx->requested_height == height)) {

with thix 100x100 would match anything that has 100 in either w or h, notg needing both
is this intended ?


> +                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;
> +    double requested_framerate = av_q2d(ctx->framerate);

Theres no need to use a floating point value. Not using one would
avoid any risk from rounding differences

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

"You are 36 times more likely to die in a bathtub than at the hands of a
terrorist. Also, you are 2.5 times more likely to become a president and
2 times more likely to become an astronaut, than to die in a terrorist
attack." -- Thoughty2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20171220/6c2e5f3f/attachment.sig>


More information about the ffmpeg-devel mailing list