FFmpeg
android_camera.c
Go to the documentation of this file.
1 /*
2  * Android camera input device
3  *
4  * Copyright (C) 2017 Felix Matouschek
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <errno.h>
24 #include <pthread.h>
25 #include <stdatomic.h>
26 #include <stdbool.h>
27 #include <stdint.h>
28 #include <unistd.h>
29 
30 #include <camera/NdkCameraDevice.h>
31 #include <camera/NdkCameraManager.h>
32 #include <media/NdkImage.h>
33 #include <media/NdkImageReader.h>
34 
35 #include "libavformat/avformat.h"
36 #include "libavformat/demux.h"
37 #include "libavformat/internal.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/display.h"
40 #include "libavutil/imgutils.h"
41 #include "libavutil/log.h"
42 #include "libavutil/mem.h"
43 #include "libavutil/opt.h"
44 #include "libavutil/parseutils.h"
45 #include "libavutil/pixfmt.h"
47 #include "libavutil/time.h"
48 
49 /* This image format is available on all Android devices
50  * supporting the Camera2 API */
51 #define IMAGE_FORMAT_ANDROID AIMAGE_FORMAT_YUV_420_888
52 
53 #define MAX_BUF_COUNT 2
54 #define VIDEO_STREAM_INDEX 0
55 #define VIDEO_TIMEBASE_ANDROID 1000000000
56 
57 #define RETURN_CASE(x) case x: return AV_STRINGIFY(x);
58 #define RETURN_DEFAULT(x) default: return AV_STRINGIFY(x);
59 
60 typedef struct AndroidCameraCtx {
61  const AVClass *class;
62 
68 
69  uint8_t lens_facing;
71  int width;
72  int height;
75 
76  ACameraManager *camera_mgr;
77  char *camera_id;
78  ACameraMetadata *camera_metadata;
79  ACameraDevice *camera_dev;
80  ACameraDevice_StateCallbacks camera_state_callbacks;
81  AImageReader *image_reader;
82  AImageReader_ImageListener image_listener;
83  ANativeWindow *image_reader_window;
84  ACaptureSessionOutputContainer *capture_session_output_container;
85  ACaptureSessionOutput *capture_session_output;
86  ACameraOutputTarget *camera_output_target;
87  ACaptureRequest *capture_request;
88  ACameraCaptureSession_stateCallbacks capture_session_state_callbacks;
89  ACameraCaptureSession *capture_session;
90 
95 
96 static const char *camera_status_string(camera_status_t val)
97 {
98  switch(val) {
99  RETURN_CASE(ACAMERA_OK)
100  RETURN_CASE(ACAMERA_ERROR_UNKNOWN)
101  RETURN_CASE(ACAMERA_ERROR_INVALID_PARAMETER)
102  RETURN_CASE(ACAMERA_ERROR_CAMERA_DISCONNECTED)
103  RETURN_CASE(ACAMERA_ERROR_NOT_ENOUGH_MEMORY)
104  RETURN_CASE(ACAMERA_ERROR_METADATA_NOT_FOUND)
105  RETURN_CASE(ACAMERA_ERROR_CAMERA_DEVICE)
106  RETURN_CASE(ACAMERA_ERROR_CAMERA_SERVICE)
107  RETURN_CASE(ACAMERA_ERROR_SESSION_CLOSED)
108  RETURN_CASE(ACAMERA_ERROR_INVALID_OPERATION)
109  RETURN_CASE(ACAMERA_ERROR_STREAM_CONFIGURE_FAIL)
110  RETURN_CASE(ACAMERA_ERROR_CAMERA_IN_USE)
111  RETURN_CASE(ACAMERA_ERROR_MAX_CAMERA_IN_USE)
112  RETURN_CASE(ACAMERA_ERROR_CAMERA_DISABLED)
113  RETURN_CASE(ACAMERA_ERROR_PERMISSION_DENIED)
114  RETURN_DEFAULT(ACAMERA_ERROR_UNKNOWN)
115  }
116 }
117 
118 static const char *media_status_string(media_status_t val)
119 {
120  switch(val) {
121  RETURN_CASE(AMEDIA_OK)
122  RETURN_CASE(AMEDIA_ERROR_UNKNOWN)
123  RETURN_CASE(AMEDIA_ERROR_MALFORMED)
124  RETURN_CASE(AMEDIA_ERROR_UNSUPPORTED)
125  RETURN_CASE(AMEDIA_ERROR_INVALID_OBJECT)
126  RETURN_CASE(AMEDIA_ERROR_INVALID_PARAMETER)
127  RETURN_CASE(AMEDIA_ERROR_INVALID_OPERATION)
128  RETURN_CASE(AMEDIA_DRM_NOT_PROVISIONED)
129  RETURN_CASE(AMEDIA_DRM_RESOURCE_BUSY)
130  RETURN_CASE(AMEDIA_DRM_DEVICE_REVOKED)
131  RETURN_CASE(AMEDIA_DRM_SHORT_BUFFER)
132  RETURN_CASE(AMEDIA_DRM_SESSION_NOT_OPENED)
133  RETURN_CASE(AMEDIA_DRM_TAMPER_DETECTED)
134  RETURN_CASE(AMEDIA_DRM_VERIFY_FAILED)
135  RETURN_CASE(AMEDIA_DRM_NEED_KEY)
136  RETURN_CASE(AMEDIA_DRM_LICENSE_EXPIRED)
137  RETURN_CASE(AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE)
138  RETURN_CASE(AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED)
139  RETURN_CASE(AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE)
140  RETURN_CASE(AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE)
141  RETURN_CASE(AMEDIA_IMGREADER_IMAGE_NOT_LOCKED)
142  RETURN_DEFAULT(AMEDIA_ERROR_UNKNOWN)
143  }
144 }
145 
146 static const char *error_state_callback_string(int val)
147 {
148  switch(val) {
149  RETURN_CASE(ERROR_CAMERA_IN_USE)
150  RETURN_CASE(ERROR_MAX_CAMERAS_IN_USE)
151  RETURN_CASE(ERROR_CAMERA_DISABLED)
152  RETURN_CASE(ERROR_CAMERA_DEVICE)
153  RETURN_CASE(ERROR_CAMERA_SERVICE)
154  default:
155  return "ERROR_CAMERA_UNKNOWN";
156  }
157 }
158 
159 static void camera_dev_disconnected(void *context, ACameraDevice *device)
160 {
161  AVFormatContext *avctx = context;
162  AndroidCameraCtx *ctx = avctx->priv_data;
163  atomic_store(&ctx->exit, 1);
164  av_log(avctx, AV_LOG_ERROR, "Camera with id %s disconnected.\n",
165  ACameraDevice_getId(device));
166 }
167 
168 static void camera_dev_error(void *context, ACameraDevice *device, int error)
169 {
170  AVFormatContext *avctx = context;
171  AndroidCameraCtx *ctx = avctx->priv_data;
172  atomic_store(&ctx->exit, 1);
173  av_log(avctx, AV_LOG_ERROR, "Error %s on camera with id %s.\n",
174  error_state_callback_string(error), ACameraDevice_getId(device));
175 }
176 
177 static int open_camera(AVFormatContext *avctx)
178 {
179  AndroidCameraCtx *ctx = avctx->priv_data;
180  camera_status_t ret;
181  ACameraIdList *camera_ids;
182 
183  ret = ACameraManager_getCameraIdList(ctx->camera_mgr, &camera_ids);
184  if (ret != ACAMERA_OK) {
185  av_log(avctx, AV_LOG_ERROR, "Failed to get camera id list, error: %s.\n",
187  return AVERROR_EXTERNAL;
188  }
189 
190  if (ctx->camera_index < camera_ids->numCameras) {
191  ctx->camera_id = av_strdup(camera_ids->cameraIds[ctx->camera_index]);
192  if (!ctx->camera_id) {
193  av_log(avctx, AV_LOG_ERROR, "Failed to allocate memory for camera_id.\n");
194  return AVERROR(ENOMEM);
195  }
196  } else {
197  av_log(avctx, AV_LOG_ERROR, "No camera with index %d available.\n",
198  ctx->camera_index);
199  return AVERROR(ENXIO);
200  }
201 
202  ACameraManager_deleteCameraIdList(camera_ids);
203 
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",
208  ctx->camera_id, camera_status_string(ret));
209  return AVERROR_EXTERNAL;
210  }
211 
212  ctx->camera_state_callbacks.context = avctx;
213  ctx->camera_state_callbacks.onDisconnected = camera_dev_disconnected;
214  ctx->camera_state_callbacks.onError = camera_dev_error;
215 
216  ret = ACameraManager_openCamera(ctx->camera_mgr, ctx->camera_id,
217  &ctx->camera_state_callbacks, &ctx->camera_dev);
218  if (ret != ACAMERA_OK) {
219  av_log(avctx, AV_LOG_ERROR, "Failed to open camera with id %s, error: %s.\n",
220  ctx->camera_id, camera_status_string(ret));
221  return AVERROR_EXTERNAL;
222  }
223 
224  return 0;
225 }
226 
228 {
229  AndroidCameraCtx *ctx = avctx->priv_data;
230  ACameraMetadata_const_entry lens_facing;
231  ACameraMetadata_const_entry sensor_orientation;
232 
233  ACameraMetadata_getConstEntry(ctx->camera_metadata,
234  ACAMERA_LENS_FACING, &lens_facing);
235  ACameraMetadata_getConstEntry(ctx->camera_metadata,
236  ACAMERA_SENSOR_ORIENTATION, &sensor_orientation);
237 
238  ctx->lens_facing = lens_facing.data.u8[0];
239  ctx->sensor_orientation = sensor_orientation.data.i32[0];
240 }
241 
243 {
244  AndroidCameraCtx *ctx = avctx->priv_data;
245  ACameraMetadata_const_entry available_configs;
246  int found = 0;
247 
248  ACameraMetadata_getConstEntry(ctx->camera_metadata,
249  ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
250  &available_configs);
251 
252  for (int i = 0; i < available_configs.count; i++) {
253  int32_t input = available_configs.data.i32[i * 4 + 3];
254  int32_t format = available_configs.data.i32[i * 4 + 0];
255 
256  if (input) {
257  continue;
258  }
259 
260  if (format == IMAGE_FORMAT_ANDROID) {
261  int32_t width = available_configs.data.i32[i * 4 + 1];
262  int32_t height = available_configs.data.i32[i * 4 + 2];
263 
264  //Same ratio
265  if ((ctx->requested_width == width && ctx->requested_height == height) ||
266  (ctx->requested_width == height && ctx->requested_height == width)) {
267  ctx->width = width;
268  ctx->height = height;
269  found = 1;
270  break;
271  }
272  }
273  }
274 
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];
278 
279  av_log(avctx, AV_LOG_WARNING,
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);
282  }
283 
284  return;
285 }
286 
287 static void match_framerate(AVFormatContext *avctx)
288 {
289  AndroidCameraCtx *ctx = avctx->priv_data;
290  ACameraMetadata_const_entry available_framerates;
291  int found = 0;
292  int current_best_match = -1;
293  int requested_framerate = av_q2d(ctx->framerate);
294 
295  ACameraMetadata_getConstEntry(ctx->camera_metadata,
296  ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
297  &available_framerates);
298 
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];
302 
303  if (requested_framerate == max) {
304  if (min == max) {
305  ctx->framerate_range[0] = min;
306  ctx->framerate_range[1] = max;
307  found = 1;
308  break;
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;
313  }
314  } else {
315  current_best_match = i;
316  }
317  }
318  }
319 
320  if (!found) {
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];
324 
325  } else {
326  ctx->framerate_range[0] = available_framerates.data.i32[0];
327  ctx->framerate_range[1] = available_framerates.data.i32[1];
328  }
329 
330  av_log(avctx, AV_LOG_WARNING,
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]);
333  }
334 
335  return;
336 }
337 
338 static int get_image_format(AVFormatContext *avctx, AImage *image)
339 {
340  AndroidCameraCtx *ctx = avctx->priv_data;
341  int32_t image_pixelstrides[2];
342  uint8_t *image_plane_data[2];
343  int plane_data_length[2];
344 
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]);
348  }
349 
350  if (image_pixelstrides[0] != image_pixelstrides[1]) {
351  av_log(avctx, AV_LOG_ERROR,
352  "Pixel strides of U and V plane should have been the same.\n");
353  return AVERROR_EXTERNAL;
354  }
355 
356  switch (image_pixelstrides[0]) {
357  case 1:
358  ctx->image_format = AV_PIX_FMT_YUV420P;
359  break;
360  case 2:
361  if (image_plane_data[0] < image_plane_data[1]) {
362  ctx->image_format = AV_PIX_FMT_NV12;
363  } else {
364  ctx->image_format = AV_PIX_FMT_NV21;
365  }
366  break;
367  default:
368  av_log(avctx, AV_LOG_ERROR,
369  "Unknown pixel stride %d of U and V plane, cannot determine camera image format.\n",
370  image_pixelstrides[0]);
371  return AVERROR(ENOSYS);
372  }
373 
374  return 0;
375 }
376 
377 static void image_available(void *context, AImageReader *reader)
378 {
379  AVFormatContext *avctx = context;
380  AndroidCameraCtx *ctx = avctx->priv_data;
381  media_status_t media_status;
382  int ret = 0;
383 
384  AImage *image;
385  int64_t image_timestamp;
386  int32_t image_linestrides[4];
387  uint8_t *image_plane_data[4];
388  int plane_data_length[4];
389 
390  AVPacket pkt;
391  int pkt_buffer_size = 0;
392 
393  media_status = AImageReader_acquireLatestImage(reader, &image);
394  if (media_status != AMEDIA_OK) {
395  if (media_status == AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) {
396  av_log(avctx, AV_LOG_WARNING,
397  "An image reader frame was discarded");
398  } else {
399  av_log(avctx, AV_LOG_ERROR,
400  "Failed to acquire latest image from image reader, error: %s.\n",
401  media_status_string(media_status));
403  }
404  goto error;
405  }
406 
407  // Silently drop frames when exit is set
408  if (atomic_load(&ctx->exit)) {
409  goto error;
410  }
411 
412  // Determine actual image format
413  if (!atomic_load(&ctx->got_image_format)) {
414  ret = get_image_format(avctx, image);
415  if (ret < 0) {
416  av_log(avctx, AV_LOG_ERROR,
417  "Could not get image format of camera.\n");
418  goto error;
419  } else {
420  atomic_store(&ctx->got_image_format, 1);
421  }
422  }
423 
424  pkt_buffer_size = av_image_get_buffer_size(ctx->image_format, ctx->width, ctx->height, 32);
425  AImage_getTimestamp(image, &image_timestamp);
426 
427  AImage_getPlaneRowStride(image, 0, &image_linestrides[0]);
428  AImage_getPlaneData(image, 0, &image_plane_data[0], &plane_data_length[0]);
429 
430  switch (ctx->image_format) {
431  case AV_PIX_FMT_YUV420P:
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]);
436  break;
437  case AV_PIX_FMT_NV12:
438  AImage_getPlaneRowStride(image, 1, &image_linestrides[1]);
439  AImage_getPlaneData(image, 1, &image_plane_data[1], &plane_data_length[1]);
440  break;
441  case AV_PIX_FMT_NV21:
442  AImage_getPlaneRowStride(image, 2, &image_linestrides[1]);
443  AImage_getPlaneData(image, 2, &image_plane_data[1], &plane_data_length[1]);
444  break;
445  default:
446  av_log(avctx, AV_LOG_ERROR, "Unsupported camera image format.\n");
447  ret = AVERROR(ENOSYS);
448  goto error;
449  }
450 
451  ret = av_new_packet(&pkt, pkt_buffer_size);
452  if (ret < 0) {
453  av_log(avctx, AV_LOG_ERROR,
454  "Failed to create new av packet, error: %s.\n", av_err2str(ret));
455  goto error;
456  }
457 
459  pkt.pts = image_timestamp;
460  av_image_copy_to_buffer(pkt.data, pkt_buffer_size,
461  (const uint8_t * const *) image_plane_data,
462  image_linestrides, ctx->image_format,
463  ctx->width, ctx->height, 32);
464 
466 
467 error:
468  if (ret < 0) {
469  if (ret != AVERROR(EAGAIN)) {
470  av_log(avctx, AV_LOG_ERROR,
471  "Error while processing new image, error: %s.\n", av_err2str(ret));
473  atomic_store(&ctx->exit, 1);
474  } else {
475  av_log(avctx, AV_LOG_WARNING,
476  "Input queue was full, dropping frame, consider raising the input_queue_size option (current value: %d)\n",
477  ctx->input_queue_size);
478  }
479  if (pkt_buffer_size) {
481  }
482  }
483 
484  AImage_delete(image);
485 
486  return;
487 }
488 
490 {
491  AndroidCameraCtx *ctx = avctx->priv_data;
492  media_status_t ret;
493 
494  ret = AImageReader_new(ctx->width, ctx->height, IMAGE_FORMAT_ANDROID,
495  MAX_BUF_COUNT, &ctx->image_reader);
496  if (ret != AMEDIA_OK) {
497  av_log(avctx, AV_LOG_ERROR,
498  "Failed to create image reader, error: %s.\n", media_status_string(ret));
499  return AVERROR_EXTERNAL;
500  }
501 
502  ctx->image_listener.context = avctx;
503  ctx->image_listener.onImageAvailable = image_available;
504 
505  ret = AImageReader_setImageListener(ctx->image_reader, &ctx->image_listener);
506  if (ret != AMEDIA_OK) {
507  av_log(avctx, AV_LOG_ERROR,
508  "Failed to set image listener on image reader, error: %s.\n",
510  return AVERROR_EXTERNAL;
511  }
512 
513  ret = AImageReader_getWindow(ctx->image_reader, &ctx->image_reader_window);
514  if (ret != AMEDIA_OK) {
515  av_log(avctx, AV_LOG_ERROR,
516  "Could not get image reader window, error: %s.\n",
518  return AVERROR_EXTERNAL;
519  }
520 
521  return 0;
522 }
523 
524 static void capture_session_closed(void *context, ACameraCaptureSession *session)
525 {
526  av_log(context, AV_LOG_INFO, "Android camera capture session was closed.\n");
527 }
528 
529 static void capture_session_ready(void *context, ACameraCaptureSession *session)
530 {
531  av_log(context, AV_LOG_INFO, "Android camera capture session is ready.\n");
532 }
533 
534 static void capture_session_active(void *context, ACameraCaptureSession *session)
535 {
536  av_log(context, AV_LOG_INFO, "Android camera capture session is active.\n");
537 }
538 
540 {
541  AndroidCameraCtx *ctx = avctx->priv_data;
542  camera_status_t ret;
543 
544  ret = ACaptureSessionOutputContainer_create(&ctx->capture_session_output_container);
545  if (ret != ACAMERA_OK) {
546  av_log(avctx, AV_LOG_ERROR,
547  "Failed to create capture session output container, error: %s.\n",
549  return AVERROR_EXTERNAL;
550  }
551 
552  ANativeWindow_acquire(ctx->image_reader_window);
553 
554  ret = ACaptureSessionOutput_create(ctx->image_reader_window, &ctx->capture_session_output);
555  if (ret != ACAMERA_OK) {
556  av_log(avctx, AV_LOG_ERROR,
557  "Failed to create capture session container, error: %s.\n",
559  return AVERROR_EXTERNAL;
560  }
561 
562  ret = ACaptureSessionOutputContainer_add(ctx->capture_session_output_container,
563  ctx->capture_session_output);
564  if (ret != ACAMERA_OK) {
565  av_log(avctx, AV_LOG_ERROR,
566  "Failed to add output to output container, error: %s.\n",
568  return AVERROR_EXTERNAL;
569  }
570 
571  ret = ACameraOutputTarget_create(ctx->image_reader_window, &ctx->camera_output_target);
572  if (ret != ACAMERA_OK) {
573  av_log(avctx, AV_LOG_ERROR,
574  "Failed to create camera output target, error: %s.\n",
576  return AVERROR_EXTERNAL;
577  }
578 
579  ret = ACameraDevice_createCaptureRequest(ctx->camera_dev, TEMPLATE_RECORD, &ctx->capture_request);
580  if (ret != ACAMERA_OK) {
581  av_log(avctx, AV_LOG_ERROR,
582  "Failed to create capture request, error: %s.\n",
584  return AVERROR_EXTERNAL;
585  }
586 
587  ret = ACaptureRequest_setEntry_i32(ctx->capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,
588  2, ctx->framerate_range);
589  if (ret != ACAMERA_OK) {
590  av_log(avctx, AV_LOG_ERROR,
591  "Failed to set target fps range in capture request, error: %s.\n",
593  return AVERROR_EXTERNAL;
594  }
595 
596  ret = ACaptureRequest_addTarget(ctx->capture_request, ctx->camera_output_target);
597  if (ret != ACAMERA_OK) {
598  av_log(avctx, AV_LOG_ERROR,
599  "Failed to add capture request capture request, error: %s.\n",
601  return AVERROR_EXTERNAL;
602  }
603 
604  ctx->capture_session_state_callbacks.context = avctx;
605  ctx->capture_session_state_callbacks.onClosed = capture_session_closed;
606  ctx->capture_session_state_callbacks.onReady = capture_session_ready;
607  ctx->capture_session_state_callbacks.onActive = capture_session_active;
608 
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) {
612  av_log(avctx, AV_LOG_ERROR,
613  "Failed to create capture session, error: %s.\n",
615  return AVERROR_EXTERNAL;
616  }
617 
618  ret = ACameraCaptureSession_setRepeatingRequest(ctx->capture_session, NULL, 1, &ctx->capture_request, NULL);
619  if (ret != ACAMERA_OK) {
620  av_log(avctx, AV_LOG_ERROR,
621  "Failed to set repeating request on capture session, error: %s.\n",
623  return AVERROR_EXTERNAL;
624  }
625 
626  return 0;
627 }
628 
630 {
631  AndroidCameraCtx *ctx = avctx->priv_data;
632 
633  while (!atomic_load(&ctx->got_image_format) && !atomic_load(&ctx->exit)) {
634  //Wait until first frame arrived and actual image format was determined
635  usleep(1000);
636  }
637 
638  return atomic_load(&ctx->got_image_format);
639 }
640 
642 {
643  AndroidCameraCtx *ctx = avctx->priv_data;
644  AVPacketSideData *side_data;
645  int32_t display_matrix[9];
646 
647  av_display_rotation_set(display_matrix, ctx->sensor_orientation);
648 
649  if (ctx->lens_facing == ACAMERA_LENS_FACING_FRONT) {
650  av_display_matrix_flip(display_matrix, 1, 0);
651  }
652 
656  sizeof(display_matrix), 0);
657 
658  if (!side_data) {
659  return AVERROR(ENOMEM);
660  }
661 
662  memcpy(side_data->data, display_matrix, sizeof(display_matrix));
663 
664  return 0;
665 }
666 
668 {
669  AndroidCameraCtx *ctx = avctx->priv_data;
670  AVStream *st;
671  AVCodecParameters *codecpar;
672 
673  st = avformat_new_stream(avctx, NULL);
674  if (!st) {
675  return AVERROR(ENOMEM);
676  }
677 
678  st->id = VIDEO_STREAM_INDEX;
679  st->avg_frame_rate = (AVRational) { ctx->framerate_range[1], 1 };
680  st->r_frame_rate = (AVRational) { ctx->framerate_range[1], 1 };
681 
682  if (!wait_for_image_format(avctx)) {
683  return AVERROR_EXTERNAL;
684  }
685 
686  codecpar = st->codecpar;
687  codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
688  codecpar->codec_id = AV_CODEC_ID_RAWVIDEO;
689  codecpar->format = ctx->image_format;
690  codecpar->width = ctx->width;
691  codecpar->height = ctx->height;
692 
694 
695  return add_display_matrix(avctx, st);
696 }
697 
699 {
700  AndroidCameraCtx *ctx = avctx->priv_data;
701 
702  atomic_store(&ctx->exit, 1);
703 
704  if (ctx->capture_session) {
705  ACameraCaptureSession_stopRepeating(ctx->capture_session);
706  // Following warning is emitted, after capture session closed callback is received:
707  // ACameraCaptureSession: Device is closed but session 0 is not notified
708  // Seems to be a bug in Android, we can ignore this
709  ACameraCaptureSession_close(ctx->capture_session);
710  ctx->capture_session = NULL;
711  }
712 
713  if (ctx->capture_request) {
714  ACaptureRequest_removeTarget(ctx->capture_request, ctx->camera_output_target);
715  ACaptureRequest_free(ctx->capture_request);
716  ctx->capture_request = NULL;
717  }
718 
719  if (ctx->camera_output_target) {
720  ACameraOutputTarget_free(ctx->camera_output_target);
721  ctx->camera_output_target = NULL;
722  }
723 
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;
729  }
730 
731  if (ctx->image_reader_window) {
732  ANativeWindow_release(ctx->image_reader_window);
733  ctx->image_reader_window = NULL;
734  }
735 
736  if (ctx->capture_session_output_container) {
737  ACaptureSessionOutputContainer_free(ctx->capture_session_output_container);
738  ctx->capture_session_output_container = NULL;
739  }
740 
741  if (ctx->camera_dev) {
742  ACameraDevice_close(ctx->camera_dev);
743  ctx->camera_dev = NULL;
744  }
745 
746  if (ctx->image_reader) {
747  AImageReader_delete(ctx->image_reader);
748  ctx->image_reader = NULL;
749  }
750 
751  if (ctx->camera_metadata) {
752  ACameraMetadata_free(ctx->camera_metadata);
753  ctx->camera_metadata = NULL;
754  }
755 
756  av_freep(&ctx->camera_id);
757 
758  if (ctx->camera_mgr) {
759  ACameraManager_delete(ctx->camera_mgr);
760  ctx->camera_mgr = NULL;
761  }
762 
763  if (ctx->input_queue) {
764  AVPacket pkt;
766  while (av_thread_message_queue_recv(ctx->input_queue, &pkt, AV_THREAD_MESSAGE_NONBLOCK) >= 0) {
768  }
769  av_thread_message_queue_free(&ctx->input_queue);
770  }
771 
772  return 0;
773 }
774 
776 {
777  AndroidCameraCtx *ctx = avctx->priv_data;
778  int ret;
779 
780  atomic_init(&ctx->got_image_format, 0);
781  atomic_init(&ctx->exit, 0);
782 
783  ret = av_thread_message_queue_alloc(&ctx->input_queue, ctx->input_queue_size, sizeof(AVPacket));
784  if (ret < 0) {
785  av_log(avctx, AV_LOG_ERROR,
786  "Failed to allocate input queue, error: %s.\n", av_err2str(ret));
787  goto error;
788  }
789 
790  ctx->camera_mgr = ACameraManager_create();
791  if (!ctx->camera_mgr) {
792  av_log(avctx, AV_LOG_ERROR, "Failed to create Android camera manager.\n");
794  goto error;
795  }
796 
797  ret = open_camera(avctx);
798  if (ret < 0) {
799  av_log(avctx, AV_LOG_ERROR, "Failed to open camera.\n");
800  goto error;
801  }
802 
803  get_sensor_orientation(avctx);
804  match_video_size(avctx);
805  match_framerate(avctx);
806 
807  ret = create_image_reader(avctx);
808  if (ret < 0) {
809  goto error;
810  }
811 
812  ret = create_capture_session(avctx);
813  if (ret < 0) {
814  goto error;
815  }
816 
817  ret = add_video_stream(avctx);
818 
819 error:
820  if (ret < 0) {
822  av_log(avctx, AV_LOG_ERROR, "Failed to open android_camera.\n");
823  }
824 
825  return ret;
826 }
827 
829 {
830  AndroidCameraCtx *ctx = avctx->priv_data;
831  int ret;
832 
833  if (!atomic_load(&ctx->exit)) {
834  ret = av_thread_message_queue_recv(ctx->input_queue, pkt,
836  } else {
837  ret = AVERROR_EOF;
838  }
839 
840  if (ret < 0) {
841  return ret;
842  } else {
843  return pkt->size;
844  }
845 }
846 
847 #define OFFSET(x) offsetof(AndroidCameraCtx, x)
848 #define DEC AV_OPT_FLAG_DECODING_PARAM
849 static const AVOption options[] = {
850  { "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 },
851  { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "30"}, 0, INT_MAX, DEC },
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 },
854  { NULL },
855 };
856 
858  .class_name = "android_camera indev",
859  .item_name = av_default_item_name,
860  .option = options,
861  .version = LIBAVUTIL_VERSION_INT,
863 };
864 
866  .p.name = "android_camera",
867  .p.long_name = NULL_IF_CONFIG_SMALL("Android camera input device"),
868  .p.flags = AVFMT_NOFILE,
869  .p.priv_class = &android_camera_class,
870  .priv_data_size = sizeof(AndroidCameraCtx),
874 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:429
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
AndroidCameraCtx::capture_session_output
ACaptureSessionOutput * capture_session_output
Definition: android_camera.c:85
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
options
static const AVOption options[]
Definition: android_camera.c:849
AVERROR
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
opt.h
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AndroidCameraCtx::lens_facing
uint8_t lens_facing
Definition: android_camera.c:69
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AV_OPT_TYPE_VIDEO_RATE
@ AV_OPT_TYPE_VIDEO_RATE
Underlying C type is AVRational.
Definition: opt.h:315
DEC
#define DEC
Definition: android_camera.c:848
int64_t
long long int64_t
Definition: coverity.c:34
error_state_callback_string
static const char * error_state_callback_string(int val)
Definition: android_camera.c:146
capture_session_closed
static void capture_session_closed(void *context, ACameraCaptureSession *session)
Definition: android_camera.c:524
image_available
static void image_available(void *context, AImageReader *reader)
Definition: android_camera.c:377
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:65
AV_THREAD_MESSAGE_NONBLOCK
@ AV_THREAD_MESSAGE_NONBLOCK
Perform non-blocking operation.
Definition: threadmessage.h:31
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:390
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
AVPacket::data
uint8_t * data
Definition: packet.h:539
AVOption
AVOption.
Definition: opt.h:429
capture_session_ready
static void capture_session_ready(void *context, ACameraCaptureSession *session)
Definition: android_camera.c:529
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:837
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
max
#define max(a, b)
Definition: cuda_runtime.h:33
AndroidCameraCtx::camera_id
char * camera_id
Definition: android_camera.c:77
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:410
AndroidCameraCtx::capture_session_output_container
ACaptureSessionOutputContainer * capture_session_output_container
Definition: android_camera.c:84
android_camera_read_close
static int android_camera_read_close(AVFormatContext *avctx)
Definition: android_camera.c:698
AndroidCameraCtx::image_reader_window
ANativeWindow * image_reader_window
Definition: android_camera.c:83
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:862
AndroidCameraCtx::capture_request
ACaptureRequest * capture_request
Definition: android_camera.c:87
camera_dev_disconnected
static void camera_dev_disconnected(void *context, ACameraDevice *device)
Definition: android_camera.c:159
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
val
static double val(void *priv, double ch)
Definition: aeval.c:77
av_thread_message_queue_recv
int av_thread_message_queue_recv(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Receive a message from the queue.
Definition: threadmessage.c:177
VIDEO_STREAM_INDEX
#define VIDEO_STREAM_INDEX
Definition: android_camera.c:54
AndroidCameraCtx::input_queue
AVThreadMessageQueue * input_queue
Definition: android_camera.c:91
AndroidCameraCtx
Definition: android_camera.c:60
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
av_thread_message_queue_send
int av_thread_message_queue_send(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Send a message on the queue.
Definition: threadmessage.c:161
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AndroidCameraCtx::framerate_range
int32_t framerate_range[2]
Definition: android_camera.c:73
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1451
format
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
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
add_video_stream
static int add_video_stream(AVFormatContext *avctx)
Definition: android_camera.c:667
AndroidCameraCtx::input_queue_size
int input_queue_size
Definition: android_camera.c:67
AVPacketSideData::data
uint8_t * data
Definition: packet.h:391
ctx
AVFormatContext * ctx
Definition: movenc.c:49
android_camera_read_header
static int android_camera_read_header(AVFormatContext *avctx)
Definition: android_camera.c:775
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AVThreadMessageQueue
Definition: threadmessage.c:30
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
AndroidCameraCtx::sensor_orientation
int32_t sensor_orientation
Definition: android_camera.c:70
context
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 context
Definition: writing_filters.txt:91
AVFormatContext
Format I/O context.
Definition: avformat.h:1300
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:771
framerate
float framerate
Definition: av1_levels.c:29
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:540
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
MAX_BUF_COUNT
#define MAX_BUF_COUNT
Definition: android_camera.c:53
NULL
#define NULL
Definition: coverity.c:32
android_camera_read_packet
static int android_camera_read_packet(AVFormatContext *avctx, AVPacket *pkt)
Definition: android_camera.c:828
match_framerate
static void match_framerate(AVFormatContext *avctx)
Definition: android_camera.c:287
RETURN_CASE
#define RETURN_CASE(x)
Definition: android_camera.c:57
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
get_image_format
static int get_image_format(AVFormatContext *avctx, AImage *image)
Definition: android_camera.c:338
get_sensor_orientation
static void get_sensor_orientation(AVFormatContext *avctx)
Definition: android_camera.c:227
AndroidCameraCtx::framerate
AVRational framerate
Definition: android_camera.c:65
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
Underlying C type is two consecutive integers.
Definition: opt.h:303
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AndroidCameraCtx::requested_height
int requested_height
Definition: android_camera.c:64
parseutils.h
AndroidCameraCtx::camera_index
int camera_index
Definition: android_camera.c:66
open_camera
static int open_camera(AVFormatContext *avctx)
Definition: android_camera.c:177
time.h
AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT
@ AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT
Definition: log.h:41
AndroidCameraCtx::width
int width
Definition: android_camera.c:71
camera_status_string
static const char * camera_status_string(camera_status_t val)
Definition: android_camera.c:96
AndroidCameraCtx::camera_metadata
ACameraMetadata * camera_metadata
Definition: android_camera.c:78
AVPacket::size
int size
Definition: packet.h:540
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
height
#define height
Definition: dsp.h:85
threadmessage.h
AndroidCameraCtx::image_format
int image_format
Definition: android_camera.c:74
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
AndroidCameraCtx::requested_width
int requested_width
Definition: android_camera.c:63
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
AndroidCameraCtx::capture_session_state_callbacks
ACameraCaptureSession_stateCallbacks capture_session_state_callbacks
Definition: android_camera.c:88
VIDEO_TIMEBASE_ANDROID
#define VIDEO_TIMEBASE_ANDROID
Definition: android_camera.c:55
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:41
media_status_string
static const char * media_status_string(media_status_t val)
Definition: android_camera.c:118
av_image_get_buffer_size
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.
Definition: imgutils.c:466
camera_dev_error
static void camera_dev_error(void *context, ACameraDevice *device, int error)
Definition: android_camera.c:168
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
OFFSET
#define OFFSET(x)
Definition: android_camera.c:847
AndroidCameraCtx::capture_session
ACameraCaptureSession * capture_session
Definition: android_camera.c:89
AndroidCameraCtx::camera_state_callbacks
ACameraDevice_StateCallbacks camera_state_callbacks
Definition: android_camera.c:80
input
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
Definition: filter_design.txt:172
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
av_thread_message_queue_alloc
int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, unsigned nelem, unsigned elsize)
Allocate a new message queue.
Definition: threadmessage.c:45
IMAGE_FORMAT_ANDROID
#define IMAGE_FORMAT_ANDROID
Definition: android_camera.c:51
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:532
AVCodecParameters::height
int height
Definition: codec_par.h:135
AndroidCameraCtx::camera_mgr
ACameraManager * camera_mgr
Definition: android_camera.c:76
display.h
av_thread_message_queue_set_err_send
void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, int err)
Set the sending error code.
Definition: threadmessage.c:193
android_camera_class
static const AVClass android_camera_class
Definition: android_camera.c:857
demux.h
AV_PIX_FMT_NV21
@ AV_PIX_FMT_NV21
as above, but U and V bytes are swapped
Definition: pixfmt.h:97
add_display_matrix
static int add_display_matrix(AVFormatContext *avctx, AVStream *st)
Definition: android_camera.c:641
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:81
AVFMT_FLAG_NONBLOCK
#define AVFMT_FLAG_NONBLOCK
Do not block when reading packets from input.
Definition: avformat.h:1454
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:760
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:748
pixfmt.h
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:80
avformat.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:706
match_video_size
static void match_video_size(AVFormatContext *avctx)
Definition: android_camera.c:242
AndroidCameraCtx::height
int height
Definition: android_camera.c:72
capture_session_active
static void capture_session_active(void *context, ACameraCaptureSession *session)
Definition: android_camera.c:534
AndroidCameraCtx::image_reader
AImageReader * image_reader
Definition: android_camera.c:81
ff_android_camera_demuxer
const FFInputFormat ff_android_camera_demuxer
Definition: android_camera.c:865
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
wait_for_image_format
static int wait_for_image_format(AVFormatContext *avctx)
Definition: android_camera.c:629
RETURN_DEFAULT
#define RETURN_DEFAULT(x)
Definition: android_camera.c:58
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:914
AndroidCameraCtx::camera_dev
ACameraDevice * camera_dev
Definition: android_camera.c:79
AVPacket::stream_index
int stream_index
Definition: packet.h:541
create_capture_session
static int create_capture_session(AVFormatContext *avctx)
Definition: android_camera.c:539
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
AVCodecParameters::format
int format
Definition: codec_par.h:92
AndroidCameraCtx::image_listener
AImageReader_ImageListener image_listener
Definition: android_camera.c:82
av_image_copy_to_buffer
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.
Definition: imgutils.c:501
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:516
AndroidCameraCtx::camera_output_target
ACameraOutputTarget * camera_output_target
Definition: android_camera.c:86
av_thread_message_queue_free
void av_thread_message_queue_free(AVThreadMessageQueue **mq)
Free a message queue.
Definition: threadmessage.c:96
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
FFInputFormat
Definition: demux.h:37
int32_t
int32_t
Definition: audioconvert.c:56
imgutils.h
av_thread_message_queue_set_err_recv
void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, int err)
Set the receiving error code.
Definition: threadmessage.c:204
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AndroidCameraCtx::exit
atomic_int exit
Definition: android_camera.c:92
avstring.h
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
width
#define width
Definition: dsp.h:85
create_image_reader
static int create_image_reader(AVFormatContext *avctx)
Definition: android_camera.c:489
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1328
AndroidCameraCtx::got_image_format
atomic_int got_image_format
Definition: android_camera.c:93
min
float min
Definition: vorbis_enc_data.h:429