25 #include <stdatomic.h> 29 #include <camera/NdkCameraDevice.h> 30 #include <camera/NdkCameraManager.h> 31 #include <media/NdkImage.h> 32 #include <media/NdkImageReader.h> 50 #define IMAGE_FORMAT_ANDROID AIMAGE_FORMAT_YUV_420_888 52 #define MAX_BUF_COUNT 2 53 #define VIDEO_STREAM_INDEX 0 54 #define VIDEO_TIMEBASE_ANDROID 1000000000 56 #define RETURN_CASE(x) case x: return AV_STRINGIFY(x); 57 #define RETURN_DEFAULT(x) default: return AV_STRINGIFY(x); 154 return "ERROR_CAMERA_UNKNOWN";
164 ACameraDevice_getId(device));
180 ACameraIdList *camera_ids;
182 ret = ACameraManager_getCameraIdList(ctx->
camera_mgr, &camera_ids);
183 if (ret != ACAMERA_OK) {
201 ACameraManager_deleteCameraIdList(camera_ids);
203 ret = ACameraManager_getCameraCharacteristics(ctx->
camera_mgr,
205 if (ret != ACAMERA_OK) {
206 av_log(avctx,
AV_LOG_ERROR,
"Failed to get metadata for camera with id %s, error: %s.\n",
217 if (ret != ACAMERA_OK) {
233 ACAMERA_LENS_FACING, &lens_facing);
235 ACAMERA_SENSOR_ORIENTATION, &sensor_orientation);
244 ACameraMetadata_const_entry available_configs;
248 ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
251 for (
int i = 0;
i < available_configs.count;
i++) {
274 if (!found || ctx->
width == 0 || ctx->
height == 0) {
275 ctx->
width = available_configs.data.i32[1];
276 ctx->
height = available_configs.data.i32[2];
279 "Requested video_size %dx%d not available, falling back to %dx%d\n",
289 ACameraMetadata_const_entry available_framerates;
291 int current_best_match = -1;
295 ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
296 &available_framerates);
298 for (
int i = 0;
i < available_framerates.count;
i++) {
299 int32_t min = available_framerates.data.i32[
i * 2 + 0];
300 int32_t max = available_framerates.data.i32[
i * 2 + 1];
302 if (requested_framerate == max) {
308 }
else if (current_best_match >= 0) {
309 int32_t current_best_match_min = available_framerates.data.i32[current_best_match * 2 + 0];
310 if (min > current_best_match_min) {
311 current_best_match =
i;
314 current_best_match =
i;
320 if (current_best_match >= 0) {
321 ctx->
framerate_range[0] = available_framerates.data.i32[current_best_match * 2 + 0];
322 ctx->
framerate_range[1] = available_framerates.data.i32[current_best_match * 2 + 1];
330 "Requested framerate %d not available, falling back to min: %d and max: %d fps\n",
342 int plane_data_length[2];
344 for (
int i = 0;
i < 2;
i++) {
345 AImage_getPlanePixelStride(image,
i + 1, &image_pixelstrides[
i]);
346 AImage_getPlaneData(image, i + 1, &image_plane_data[i], &plane_data_length[i]);
349 if (image_pixelstrides[0] != image_pixelstrides[1]) {
351 "Pixel strides of U and V plane should have been the same.\n");
355 switch (image_pixelstrides[0]) {
360 if (image_plane_data[0] < image_plane_data[1]) {
368 "Unknown pixel stride %d of U and V plane, cannot determine camera image format.\n",
369 image_pixelstrides[0]);
380 media_status_t media_status;
384 int64_t image_timestamp;
387 int plane_data_length[4];
390 int pkt_buffer_size = 0;
392 media_status = AImageReader_acquireLatestImage(reader, &image);
393 if (media_status != AMEDIA_OK) {
394 if (media_status == AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) {
396 "An image reader frame was discarded");
399 "Failed to acquire latest image from image reader, error: %s.\n",
416 "Could not get image format of camera.\n");
424 AImage_getTimestamp(image, &image_timestamp);
426 AImage_getPlaneRowStride(image, 0, &image_linestrides[0]);
427 AImage_getPlaneData(image, 0, &image_plane_data[0], &plane_data_length[0]);
431 AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
432 AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
433 AImage_getPlaneRowStride(image, 2, &image_linestrides[2]);
434 AImage_getPlaneData(image, 2, &image_plane_data[2], &plane_data_length[2]);
437 AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
438 AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
441 AImage_getPlaneRowStride(image, 2, &image_linestrides[1]);
442 AImage_getPlaneData(image, 2, &image_plane_data[1], &plane_data_length[1]);
453 "Failed to create new av packet, error: %s.\n",
av_err2str(ret));
458 pkt.
pts = image_timestamp;
460 (
const uint8_t *
const *) image_plane_data,
470 "Error while processing new image, error: %s.\n",
av_err2str(ret));
475 "Input queue was full, dropping frame, consider raising the input_queue_size option (current value: %d)\n",
478 if (pkt_buffer_size) {
483 AImage_delete(image);
495 if (ret != AMEDIA_OK) {
505 if (ret != AMEDIA_OK) {
507 "Failed to set image listener on image reader, error: %s.\n",
513 if (ret != AMEDIA_OK) {
515 "Could not get image reader window, error: %s.\n",
544 if (ret != ACAMERA_OK) {
546 "Failed to create capture session output container, error: %s.\n",
554 if (ret != ACAMERA_OK) {
556 "Failed to create capture session container, error: %s.\n",
563 if (ret != ACAMERA_OK) {
565 "Failed to add output to output container, error: %s.\n",
571 if (ret != ACAMERA_OK) {
573 "Failed to create camera output target, error: %s.\n",
579 if (ret != ACAMERA_OK) {
581 "Failed to create capture request, error: %s.\n",
586 ret = ACaptureRequest_setEntry_i32(ctx->
capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,
588 if (ret != ACAMERA_OK) {
590 "Failed to set target fps range in capture request, error: %s.\n",
596 if (ret != ACAMERA_OK) {
598 "Failed to add capture request capture request, error: %s.\n",
610 if (ret != ACAMERA_OK) {
612 "Failed to create capture session, error: %s.\n",
618 if (ret != ACAMERA_OK) {
620 "Failed to set repeating request on capture session, error: %s.\n",
648 if (ctx->
lens_facing == ACAMERA_LENS_FACING_FRONT) {
659 memcpy(side_data, display_matrix,
sizeof(display_matrix));
783 "Failed to allocate input queue, error: %s.\n",
av_err2str(ret));
844 #define OFFSET(x) offsetof(AndroidCameraCtx, x) 845 #define DEC AV_OPT_FLAG_DECODING_PARAM 863 .
name =
"android_camera",
870 .priv_class = &android_camera_class,
static void capture_session_ready(void *context, ACameraCaptureSession *session)
static void capture_session_active(void *context, ACameraCaptureSession *session)
#define atomic_store(object, desired)
void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, int err)
Set the receiving error code.
int av_image_copy_to_buffer(uint8_t *dst, int dst_size, const uint8_t *const src_data[4], const int src_linesize[4], enum AVPixelFormat pix_fmt, int width, int height, int align)
Copy image data from an image into a buffer.
ACaptureSessionOutput * capture_session_output
#define AV_LOG_WARNING
Something somehow does not look correct.
#define LIBAVUTIL_VERSION_INT
#define IMAGE_FORMAT_ANDROID
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
const char * av_default_item_name(void *ptr)
Return the context name.
static const char * media_status_string(media_status_t val)
#define VIDEO_STREAM_INDEX
static void error(const char *err)
ANativeWindow * image_reader_window
static int wait_for_image_format(AVFormatContext *avctx)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate.The lists are not just lists
This struct describes the properties of an encoded stream.
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure counterclockwise rotation by the specified angle...
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
static int add_video_stream(AVFormatContext *avctx)
int av_thread_message_queue_recv(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Receive a message from the queue.
static const AVClass android_camera_class
static int android_camera_read_close(AVFormatContext *avctx)
ACaptureSessionOutputContainer * capture_session_output_container
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
int av_thread_message_queue_send(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Send a message on the queue.
int id
Format-specific stream ID.
static const char * camera_status_string(camera_status_t val)
#define VIDEO_TIMEBASE_ANDROID
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
ACaptureRequest * capture_request
int flags
Flags modifying the (de)muxer behaviour.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
#define AVERROR_EOF
End of file.
int32_t framerate_range[2]
static av_cold int read_close(AVFormatContext *ctx)
#define RETURN_DEFAULT(x)
static void camera_dev_error(void *context, ACameraDevice *device, int error)
static int android_camera_read_header(AVFormatContext *avctx)
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
AVThreadMessageQueue * input_queue
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters...
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define atomic_load(object)
static void capture_session_closed(void *context, ACameraCaptureSession *session)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
enum AVMediaType codec_type
General type of the encoded data.
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
AVInputFormat ff_android_camera_demuxer
AVRational avg_frame_rate
Average framerate.
static int create_image_reader(AVFormatContext *avctx)
ACameraCaptureSession * capture_session
as above, but U and V bytes are swapped
ACameraDevice_StateCallbacks camera_state_callbacks
static void get_sensor_orientation(AVFormatContext *avctx)
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
ACameraManager * camera_mgr
int32_t sensor_orientation
uint8_t * av_stream_new_side_data(AVStream *stream, enum AVPacketSideDataType type, int size)
Allocate new information from stream.
static int read_header(FFV1Context *f)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
ACameraMetadata * camera_metadata
#define AV_LOG_INFO
Standard information.
char * av_strdup(const char *s)
Duplicate a string.
static int open_camera(AVFormatContext *avctx)
void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, int err)
Set the sending error code.
static void match_video_size(AVFormatContext *avctx)
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Perform non-blocking operation.
static int add_display_matrix(AVFormatContext *avctx, AVStream *st)
Describe the class of an AVClass context structure.
static const AVOption options[]
static int create_capture_session(AVFormatContext *avctx)
Rational number (pair of numerator and denominator).
int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, unsigned nelem, unsigned elsize)
Allocate a new message queue.
offset must point to AVRational
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
ACameraOutputTarget * camera_output_target
AImageReader_ImageListener image_listener
offset must point to two consecutive integers
Libavdevice version macros.
#define flags(name, subs,...)
void av_thread_message_queue_free(AVThreadMessageQueue **mq)
Free a message queue.
ACameraCaptureSession_stateCallbacks capture_session_state_callbacks
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static void match_framerate(AVFormatContext *avctx)
static const char * error_state_callback_string(int val)
static int android_camera_read_packet(AVFormatContext *avctx, AVPacket *pkt)
ACameraDevice * camera_dev
static void image_available(void *context, AImageReader *reader)
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
static void camera_dev_disconnected(void *context, ACameraDevice *device)
void * priv_data
Format private data.
atomic_int got_image_format
#define atomic_init(obj, value)
AImageReader * image_reader
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option keep it simple and lowercase description are in without and describe what they for example set the foo of the bar offset is the offset of the field in your local context
AVRational r_frame_rate
Real base framerate of the stream.
#define AVERROR_EXTERNAL
Generic error in an external library.
static double val(void *priv, double ch)
This structure stores compressed data.
static int get_image_format(AVFormatContext *avctx, AImage *image)
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...