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