FFmpeg
mediacodec_wrapper.c
Go to the documentation of this file.
1 /*
2  * Android MediaCodec Wrapper
3  *
4  * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
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 <dlfcn.h>
24 #include <jni.h>
25 #include <stdbool.h>
26 #include <media/NdkMediaFormat.h>
27 #include <media/NdkMediaCodec.h>
28 #include <android/native_window_jni.h>
29 
30 #include "libavutil/avassert.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/avstring.h"
33 
34 #include "avcodec.h"
35 #include "ffjni.h"
36 #include "mediacodec_wrapper.h"
37 
39 
41  jmethodID init_id;
43 
44  jmethodID get_codec_count_id;
46 
48  jmethodID get_name_id;
51  jmethodID is_encoder_id;
53 
55  jfieldID color_formats_id;
57 
59  jfieldID profile_id;
60  jfieldID level_id;
61 };
62 
63 static const struct FFJniField jni_amediacodeclist_mapping[] = {
64  { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_list_class), 1 },
65  { "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, init_id), 0 },
66  { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, find_decoder_for_format_id), 0 },
67 
68  { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_count_id), 1 },
69  { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_info_at_id), 1 },
70 
71  { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_info_class), 1 },
72  { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_name_id), 1 },
73  { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_capabilities_id), 1 },
74  { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_supported_types_id), 1 },
75  { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_encoder_id), 1 },
76  { "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_software_only_id), 0 },
77 
78  { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_capabilities_class), 1 },
79  { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, color_formats_id), 1 },
80  { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_levels_id), 1 },
81 
82  { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_profile_level_class), 1 },
83  { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_id), 1 },
84  { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, level_id), 1 },
85 
86  { NULL }
87 };
88 
90 
92 
93  jmethodID init_id;
94 
95  jmethodID contains_key_id;
96 
97  jmethodID get_integer_id;
98  jmethodID get_long_id;
99  jmethodID get_float_id;
100  jmethodID get_bytebuffer_id;
101  jmethodID get_string_id;
102 
103  jmethodID set_integer_id;
104  jmethodID set_long_id;
105  jmethodID set_float_id;
106  jmethodID set_bytebuffer_id;
107  jmethodID set_string_id;
108 
109  jmethodID to_string_id;
110 
111 };
112 
113 static const struct FFJniField jni_amediaformat_mapping[] = {
114  { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaFormatFields, mediaformat_class), 1 },
115 
116  { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 },
117 
118  { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD,offsetof(struct JNIAMediaFormatFields, contains_key_id), 1 },
119 
120  { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_integer_id), 1 },
121  { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_long_id), 1 },
122  { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_float_id), 1 },
123  { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_bytebuffer_id), 1 },
124  { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_string_id), 1 },
125 
126  { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_integer_id), 1 },
127  { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_long_id), 1 },
128  { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_float_id), 1 },
129  { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_bytebuffer_id), 1 },
130  { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_string_id), 1 },
131 
132  { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, to_string_id), 1 },
133 
134  { NULL }
135 };
136 
137 static const AVClass amediaformat_class = {
138  .class_name = "amediaformat",
139  .item_name = av_default_item_name,
140  .version = LIBAVUTIL_VERSION_INT,
141 };
142 
143 typedef struct FFAMediaFormatJni {
145 
147  jobject object;
149 
151 
153 
155 
159 
163 
165 
169 
170  jmethodID get_name_id;
171 
172  jmethodID configure_id;
173  jmethodID start_id;
174  jmethodID flush_id;
175  jmethodID stop_id;
176  jmethodID release_id;
177 
179 
184 
190 
193 
195 
196  jmethodID init_id;
197 
198  jfieldID flags_id;
199  jfieldID offset_id;
201  jfieldID size_id;
202 
203 };
204 
205 static const struct FFJniField jni_amediacodec_mapping[] = {
206  { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediacodec_class), 1 },
207 
208  { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_try_again_later_id), 1 },
209  { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_buffers_changed_id), 1 },
210  { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_format_changed_id), 1 },
211 
212  { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_codec_config_id), 1 },
213  { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_end_of_stream_id), 1 },
214  { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_key_frame_id), 0 },
215 
216  { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, configure_flag_encode_id), 1 },
217 
218  { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_by_codec_name_id), 1 },
219  { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_decoder_by_type_id), 1 },
220  { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_encoder_by_type_id), 1 },
221 
222  { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_name_id), 1 },
223 
224  { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, configure_id), 1 },
225  { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, start_id), 1 },
226  { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, flush_id), 1 },
227  { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, stop_id), 1 },
228  { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_id), 1 },
229 
230  { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_format_id), 1 },
231 
232  { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_input_buffer_id), 1 },
233  { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, queue_input_buffer_id), 1 },
234  { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffer_id), 0 },
235  { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffers_id), 1 },
236 
237  { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_output_buffer_id), 1 },
238  { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffer_id), 0 },
239  { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffers_id), 1 },
240  { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_id), 1 },
241  { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_at_time_id), 0 },
242 
243  { "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, set_input_surface_id), 0 },
244  { "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, signal_end_of_input_stream_id), 0 },
245 
246  { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediainfo_class), 1 },
247 
248  { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, init_id), 1 },
249  { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, flags_id), 1 },
250  { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, offset_id), 1 },
251  { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, presentation_time_us_id), 1 },
252  { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, size_id), 1 },
253 
254  { NULL }
255 };
256 
257 static const AVClass amediacodec_class = {
258  .class_name = "amediacodec",
259  .item_name = av_default_item_name,
260  .version = LIBAVUTIL_VERSION_INT,
261 };
262 
263 typedef struct FFAMediaCodecJni {
265 
267 
268  jobject object;
269  jobject buffer_info;
270 
271  jobject input_buffers;
272  jobject output_buffers;
273 
277 
281 
283 
286 
288 
289 #define JNI_GET_ENV_OR_RETURN(env, log_ctx, ret) do { \
290  (env) = ff_jni_get_env(log_ctx); \
291  if (!(env)) { \
292  return ret; \
293  } \
294 } while (0)
295 
296 #define JNI_GET_ENV_OR_RETURN_VOID(env, log_ctx) do { \
297  (env) = ff_jni_get_env(log_ctx); \
298  if (!(env)) { \
299  return; \
300  } \
301 } while (0)
302 
304 {
305  // Copy and modified from MediaCodecInfo.java
306  static const int AVCProfileBaseline = 0x01;
307  static const int AVCProfileMain = 0x02;
308  static const int AVCProfileExtended = 0x04;
309  static const int AVCProfileHigh = 0x08;
310  static const int AVCProfileHigh10 = 0x10;
311  static const int AVCProfileHigh422 = 0x20;
312  static const int AVCProfileHigh444 = 0x40;
313  static const int AVCProfileConstrainedBaseline = 0x10000;
314  static const int AVCProfileConstrainedHigh = 0x80000;
315 
316  static const int HEVCProfileMain = 0x01;
317  static const int HEVCProfileMain10 = 0x02;
318  static const int HEVCProfileMainStill = 0x04;
319  static const int HEVCProfileMain10HDR10 = 0x1000;
320  static const int HEVCProfileMain10HDR10Plus = 0x2000;
321 
322  // Unused yet.
323  (void)AVCProfileConstrainedHigh;
324  (void)HEVCProfileMain10HDR10;
325  (void)HEVCProfileMain10HDR10Plus;
326 
327  if (avctx->codec_id == AV_CODEC_ID_H264) {
328  switch(avctx->profile) {
330  return AVCProfileBaseline;
332  return AVCProfileConstrainedBaseline;
334  return AVCProfileMain;
335  break;
337  return AVCProfileExtended;
339  return AVCProfileHigh;
342  return AVCProfileHigh10;
345  return AVCProfileHigh422;
349  return AVCProfileHigh444;
350  }
351  } else if (avctx->codec_id == AV_CODEC_ID_HEVC) {
352  switch (avctx->profile) {
354  return HEVCProfileMain;
356  return HEVCProfileMainStill;
358  return HEVCProfileMain10;
359  }
360  }
361 
362  return -1;
363 }
364 
365 char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx)
366 {
367  int ret;
368  int i;
369  int codec_count;
370  int found_codec = 0;
371  char *name = NULL;
372  char *supported_type = NULL;
373 
374  JNIEnv *env = NULL;
375  struct JNIAMediaCodecListFields jfields = { 0 };
376  struct JNIAMediaFormatFields mediaformat_jfields = { 0 };
377 
378  jobject codec_name = NULL;
379 
380  jobject info = NULL;
381  jobject type = NULL;
382  jobjectArray types = NULL;
383 
384  jobject capabilities = NULL;
385  jobject profile_level = NULL;
386  jobjectArray profile_levels = NULL;
387 
388  JNI_GET_ENV_OR_RETURN(env, log_ctx, NULL);
389 
390  if ((ret = ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx)) < 0) {
391  goto done;
392  }
393 
394  if ((ret = ff_jni_init_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx)) < 0) {
395  goto done;
396  }
397 
398  codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id);
399  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
400  goto done;
401  }
402 
403  for(i = 0; i < codec_count; i++) {
404  int j;
405  int type_count;
406  int is_encoder;
407 
408  info = (*env)->CallStaticObjectMethod(env, jfields.mediacodec_list_class, jfields.get_codec_info_at_id, i);
409  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
410  goto done;
411  }
412 
413  types = (*env)->CallObjectMethod(env, info, jfields.get_supported_types_id);
414  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
415  goto done;
416  }
417 
418  is_encoder = (*env)->CallBooleanMethod(env, info, jfields.is_encoder_id);
419  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
420  goto done;
421  }
422 
423  if (is_encoder != encoder) {
424  goto done_with_info;
425  }
426 
427  if (jfields.is_software_only_id) {
428  int is_software_only = (*env)->CallBooleanMethod(env, info, jfields.is_software_only_id);
429  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
430  goto done;
431  }
432 
433  if (is_software_only) {
434  goto done_with_info;
435  }
436  }
437 
438  codec_name = (*env)->CallObjectMethod(env, info, jfields.get_name_id);
439  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
440  goto done;
441  }
442 
443  name = ff_jni_jstring_to_utf_chars(env, codec_name, log_ctx);
444  if (!name) {
445  goto done;
446  }
447 
448  if (codec_name) {
449  (*env)->DeleteLocalRef(env, codec_name);
450  codec_name = NULL;
451  }
452 
453  /* Skip software decoders */
454  if (
455  strstr(name, "OMX.google") ||
456  strstr(name, "OMX.ffmpeg") ||
457  (strstr(name, "OMX.SEC") && strstr(name, ".sw.")) ||
458  !strcmp(name, "OMX.qcom.video.decoder.hevcswvdec")) {
459  goto done_with_info;
460  }
461 
462  type_count = (*env)->GetArrayLength(env, types);
463  for (j = 0; j < type_count; j++) {
464  int k;
465  int profile_count;
466 
467  type = (*env)->GetObjectArrayElement(env, types, j);
468  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
469  goto done;
470  }
471 
472  supported_type = ff_jni_jstring_to_utf_chars(env, type, log_ctx);
473  if (!supported_type) {
474  goto done;
475  }
476 
477  if (av_strcasecmp(supported_type, mime)) {
478  goto done_with_type;
479  }
480 
481  capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, type);
482  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
483  goto done;
484  }
485 
486  profile_levels = (*env)->GetObjectField(env, capabilities, jfields.profile_levels_id);
487  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
488  goto done;
489  }
490 
491  profile_count = (*env)->GetArrayLength(env, profile_levels);
492  if (!profile_count) {
493  found_codec = 1;
494  }
495  for (k = 0; k < profile_count; k++) {
496  int supported_profile = 0;
497 
498  if (profile < 0) {
499  found_codec = 1;
500  break;
501  }
502 
503  profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k);
504  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
505  goto done;
506  }
507 
508  supported_profile = (*env)->GetIntField(env, profile_level, jfields.profile_id);
509  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
510  goto done;
511  }
512 
513  found_codec = profile == supported_profile;
514 
515  if (profile_level) {
516  (*env)->DeleteLocalRef(env, profile_level);
517  profile_level = NULL;
518  }
519 
520  if (found_codec) {
521  break;
522  }
523  }
524 
525 done_with_type:
526  if (profile_levels) {
527  (*env)->DeleteLocalRef(env, profile_levels);
528  profile_levels = NULL;
529  }
530 
531  if (capabilities) {
532  (*env)->DeleteLocalRef(env, capabilities);
533  capabilities = NULL;
534  }
535 
536  if (type) {
537  (*env)->DeleteLocalRef(env, type);
538  type = NULL;
539  }
540 
541  av_freep(&supported_type);
542 
543  if (found_codec) {
544  break;
545  }
546  }
547 
548 done_with_info:
549  if (info) {
550  (*env)->DeleteLocalRef(env, info);
551  info = NULL;
552  }
553 
554  if (types) {
555  (*env)->DeleteLocalRef(env, types);
556  types = NULL;
557  }
558 
559  if (found_codec) {
560  break;
561  }
562 
563  av_freep(&name);
564  }
565 
566 done:
567  if (codec_name) {
568  (*env)->DeleteLocalRef(env, codec_name);
569  }
570 
571  if (info) {
572  (*env)->DeleteLocalRef(env, info);
573  }
574 
575  if (type) {
576  (*env)->DeleteLocalRef(env, type);
577  }
578 
579  if (types) {
580  (*env)->DeleteLocalRef(env, types);
581  }
582 
583  if (capabilities) {
584  (*env)->DeleteLocalRef(env, capabilities);
585  }
586 
587  if (profile_level) {
588  (*env)->DeleteLocalRef(env, profile_level);
589  }
590 
591  if (profile_levels) {
592  (*env)->DeleteLocalRef(env, profile_levels);
593  }
594 
595  av_freep(&supported_type);
596 
597  ff_jni_reset_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx);
598  ff_jni_reset_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx);
599 
600  if (!found_codec) {
601  av_freep(&name);
602  }
603 
604  return name;
605 }
606 
608 {
609  JNIEnv *env = NULL;
611  jobject object = NULL;
612 
613  format = av_mallocz(sizeof(*format));
614  if (!format) {
615  return NULL;
616  }
617  format->api = media_format_jni;
618 
619  env = ff_jni_get_env(format);
620  if (!env) {
621  av_freep(&format);
622  return NULL;
623  }
624 
625  if (ff_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) {
626  goto fail;
627  }
628 
629  object = (*env)->NewObject(env, format->jfields.mediaformat_class, format->jfields.init_id);
630  if (!object) {
631  goto fail;
632  }
633 
634  format->object = (*env)->NewGlobalRef(env, object);
635  if (!format->object) {
636  goto fail;
637  }
638 
639 fail:
640  if (object) {
641  (*env)->DeleteLocalRef(env, object);
642  }
643 
644  if (!format->object) {
646  av_freep(&format);
647  }
648 
649  return (FFAMediaFormat *)format;
650 }
651 
653 {
654  JNIEnv *env = NULL;
656 
657  format = av_mallocz(sizeof(*format));
658  if (!format) {
659  return NULL;
660  }
661  format->api = media_format_jni;
662 
663  env = ff_jni_get_env(format);
664  if (!env) {
665  av_freep(&format);
666  return NULL;
667  }
668 
669  if (ff_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) {
670  goto fail;
671  }
672 
673  format->object = (*env)->NewGlobalRef(env, object);
674  if (!format->object) {
675  goto fail;
676  }
677 
678  return (FFAMediaFormat *)format;
679 fail:
681 
682  av_freep(&format);
683 
684  return NULL;
685 }
686 
688 {
689  int ret = 0;
691  JNIEnv *env = NULL;
692 
693  if (!format) {
694  return 0;
695  }
696 
698 
699  (*env)->DeleteGlobalRef(env, format->object);
700  format->object = NULL;
701 
703 
704  av_freep(&format);
705 
706  return ret;
707 }
708 
710 {
711  char *ret = NULL;
713  JNIEnv *env = NULL;
714  jstring description = NULL;
715 
716  av_assert0(format != NULL);
717 
719 
720  description = (*env)->CallObjectMethod(env, format->object, format->jfields.to_string_id);
721  if (ff_jni_exception_check(env, 1, NULL) < 0) {
722  goto fail;
723  }
724 
726 fail:
727  if (description) {
728  (*env)->DeleteLocalRef(env, description);
729  }
730 
731  return ret;
732 }
733 
735 {
736  int ret = 1;
738  JNIEnv *env = NULL;
739  jstring key = NULL;
740  jboolean contains_key;
741 
742  av_assert0(format != NULL);
743 
744  JNI_GET_ENV_OR_RETURN(env, format, 0);
745 
747  if (!key) {
748  ret = 0;
749  goto fail;
750  }
751 
752  contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
753  if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
754  ret = 0;
755  goto fail;
756  }
757 
758  *out = (*env)->CallIntMethod(env, format->object, format->jfields.get_integer_id, key);
759  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
760  ret = 0;
761  goto fail;
762  }
763 
764  ret = 1;
765 fail:
766  if (key) {
767  (*env)->DeleteLocalRef(env, key);
768  }
769 
770  return ret;
771 }
772 
773 static int mediaformat_jni_getInt64(FFAMediaFormat* ctx, const char *name, int64_t *out)
774 {
775  int ret = 1;
777  JNIEnv *env = NULL;
778  jstring key = NULL;
779  jboolean contains_key;
780 
781  av_assert0(format != NULL);
782 
783  JNI_GET_ENV_OR_RETURN(env, format, 0);
784 
786  if (!key) {
787  ret = 0;
788  goto fail;
789  }
790 
791  contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
792  if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
793  ret = 0;
794  goto fail;
795  }
796 
797  *out = (*env)->CallLongMethod(env, format->object, format->jfields.get_long_id, key);
798  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
799  ret = 0;
800  goto fail;
801  }
802 
803  ret = 1;
804 fail:
805  if (key) {
806  (*env)->DeleteLocalRef(env, key);
807  }
808 
809  return ret;
810 }
811 
812 static int mediaformat_jni_getFloat(FFAMediaFormat* ctx, const char *name, float *out)
813 {
814  int ret = 1;
816  JNIEnv *env = NULL;
817  jstring key = NULL;
818  jboolean contains_key;
819 
820  av_assert0(format != NULL);
821 
822  JNI_GET_ENV_OR_RETURN(env, format, 0);
823 
825  if (!key) {
826  ret = 0;
827  goto fail;
828  }
829 
830  contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
831  if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
832  ret = 0;
833  goto fail;
834  }
835 
836  *out = (*env)->CallFloatMethod(env, format->object, format->jfields.get_float_id, key);
837  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
838  ret = 0;
839  goto fail;
840  }
841 
842  ret = 1;
843 fail:
844  if (key) {
845  (*env)->DeleteLocalRef(env, key);
846  }
847 
848  return ret;
849 }
850 
851 static int mediaformat_jni_getBuffer(FFAMediaFormat* ctx, const char *name, void** data, size_t *size)
852 {
853  int ret = 1;
855  JNIEnv *env = NULL;
856  jstring key = NULL;
857  jboolean contains_key;
858  jobject result = NULL;
859 
860  av_assert0(format != NULL);
861 
862  JNI_GET_ENV_OR_RETURN(env, format, 0);
863 
865  if (!key) {
866  ret = 0;
867  goto fail;
868  }
869 
870  contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
871  if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
872  ret = 0;
873  goto fail;
874  }
875 
876  result = (*env)->CallObjectMethod(env, format->object, format->jfields.get_bytebuffer_id, key);
877  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
878  ret = 0;
879  goto fail;
880  }
881 
882  *data = (*env)->GetDirectBufferAddress(env, result);
883  *size = (*env)->GetDirectBufferCapacity(env, result);
884 
885  if (*data && *size) {
886  void *src = *data;
887  *data = av_malloc(*size);
888  if (!*data) {
889  ret = 0;
890  goto fail;
891  }
892 
893  memcpy(*data, src, *size);
894  }
895 
896  ret = 1;
897 fail:
898  if (key) {
899  (*env)->DeleteLocalRef(env, key);
900  }
901 
902  if (result) {
903  (*env)->DeleteLocalRef(env, result);
904  }
905 
906  return ret;
907 }
908 
909 static int mediaformat_jni_getString(FFAMediaFormat* ctx, const char *name, const char **out)
910 {
911  int ret = 1;
913  JNIEnv *env = NULL;
914  jstring key = NULL;
915  jboolean contains_key;
916  jstring result = NULL;
917 
918  av_assert0(format != NULL);
919 
920  JNI_GET_ENV_OR_RETURN(env, format, 0);
921 
923  if (!key) {
924  ret = 0;
925  goto fail;
926  }
927 
928  contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key);
929  if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) {
930  ret = 0;
931  goto fail;
932  }
933 
934  result = (*env)->CallObjectMethod(env, format->object, format->jfields.get_string_id, key);
935  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
936  ret = 0;
937  goto fail;
938  }
939 
941  if (!*out) {
942  ret = 0;
943  goto fail;
944  }
945 
946  ret = 1;
947 fail:
948  if (key) {
949  (*env)->DeleteLocalRef(env, key);
950  }
951 
952  if (result) {
953  (*env)->DeleteLocalRef(env, result);
954  }
955 
956  return ret;
957 }
958 
960 {
961  JNIEnv *env = NULL;
962  jstring key = NULL;
964 
965  av_assert0(format != NULL);
966 
968 
970  if (!key) {
971  goto fail;
972  }
973 
974  (*env)->CallVoidMethod(env, format->object, format->jfields.set_integer_id, key, value);
975  if (ff_jni_exception_check(env, 1, format) < 0) {
976  goto fail;
977  }
978 
979 fail:
980  if (key) {
981  (*env)->DeleteLocalRef(env, key);
982  }
983 }
984 
985 static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int64_t value)
986 {
987  JNIEnv *env = NULL;
988  jstring key = NULL;
990 
991  av_assert0(format != NULL);
992 
994 
996  if (!key) {
997  goto fail;
998  }
999 
1000  (*env)->CallVoidMethod(env, format->object, format->jfields.set_long_id, key, value);
1001  if (ff_jni_exception_check(env, 1, format) < 0) {
1002  goto fail;
1003  }
1004 
1005 fail:
1006  if (key) {
1007  (*env)->DeleteLocalRef(env, key);
1008  }
1009 }
1010 
1011 static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, float value)
1012 {
1013  JNIEnv *env = NULL;
1014  jstring key = NULL;
1016 
1017  av_assert0(format != NULL);
1018 
1020 
1022  if (!key) {
1023  goto fail;
1024  }
1025 
1026  (*env)->CallVoidMethod(env, format->object, format->jfields.set_float_id, key, value);
1027  if (ff_jni_exception_check(env, 1, format) < 0) {
1028  goto fail;
1029  }
1030 
1031 fail:
1032  if (key) {
1033  (*env)->DeleteLocalRef(env, key);
1034  }
1035 }
1036 
1037 static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, const char* value)
1038 {
1039  JNIEnv *env = NULL;
1040  jstring key = NULL;
1041  jstring string = NULL;
1043 
1044  av_assert0(format != NULL);
1045 
1047 
1049  if (!key) {
1050  goto fail;
1051  }
1052 
1053  string = ff_jni_utf_chars_to_jstring(env, value, format);
1054  if (!string) {
1055  goto fail;
1056  }
1057 
1058  (*env)->CallVoidMethod(env, format->object, format->jfields.set_string_id, key, string);
1059  if (ff_jni_exception_check(env, 1, format) < 0) {
1060  goto fail;
1061  }
1062 
1063 fail:
1064  if (key) {
1065  (*env)->DeleteLocalRef(env, key);
1066  }
1067 
1068  if (string) {
1069  (*env)->DeleteLocalRef(env, string);
1070  }
1071 }
1072 
1073 static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, void* data, size_t size)
1074 {
1075  JNIEnv *env = NULL;
1076  jstring key = NULL;
1077  jobject buffer = NULL;
1078  void *buffer_data = NULL;
1080 
1081  av_assert0(format != NULL);
1082 
1084 
1086  if (!key) {
1087  goto fail;
1088  }
1089 
1090  if (!data || !size) {
1091  goto fail;
1092  }
1093 
1095  if (!buffer_data) {
1096  goto fail;
1097  }
1098 
1099  memcpy(buffer_data, data, size);
1100 
1101  buffer = (*env)->NewDirectByteBuffer(env, buffer_data, size);
1102  if (!buffer) {
1103  goto fail;
1104  }
1105 
1106  (*env)->CallVoidMethod(env, format->object, format->jfields.set_bytebuffer_id, key, buffer);
1107  if (ff_jni_exception_check(env, 1, format) < 0) {
1108  goto fail;
1109  }
1110 
1111 fail:
1112  if (key) {
1113  (*env)->DeleteLocalRef(env, key);
1114  }
1115 
1116  if (buffer) {
1117  (*env)->DeleteLocalRef(env, buffer);
1118  }
1119 }
1120 
1122 {
1123  int ret = 0;
1124  JNIEnv *env = NULL;
1125 
1127 
1128  codec->INFO_TRY_AGAIN_LATER = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_try_again_later_id);
1129  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1130  goto fail;
1131  }
1132 
1133  codec->BUFFER_FLAG_CODEC_CONFIG = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_codec_config_id);
1134  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1135  goto fail;
1136  }
1137 
1138  codec->BUFFER_FLAG_END_OF_STREAM = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_end_of_stream_id);
1139  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1140  goto fail;
1141  }
1142 
1143  if (codec->jfields.buffer_flag_key_frame_id) {
1144  codec->BUFFER_FLAG_KEY_FRAME = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_key_frame_id);
1145  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1146  goto fail;
1147  }
1148  }
1149 
1150  codec->CONFIGURE_FLAG_ENCODE = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.configure_flag_encode_id);
1151  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1152  goto fail;
1153  }
1154 
1155  codec->INFO_TRY_AGAIN_LATER = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_try_again_later_id);
1156  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1157  goto fail;
1158  }
1159 
1160  codec->INFO_OUTPUT_BUFFERS_CHANGED = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_output_buffers_changed_id);
1161  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1162  goto fail;
1163  }
1164 
1165  codec->INFO_OUTPUT_FORMAT_CHANGED = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_output_format_changed_id);
1166  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1167  goto fail;
1168  }
1169 
1170 fail:
1171 
1172  return ret;
1173 }
1174 
1175 #define CREATE_CODEC_BY_NAME 0
1176 #define CREATE_DECODER_BY_TYPE 1
1177 #define CREATE_ENCODER_BY_TYPE 2
1178 
1179 static inline FFAMediaCodec *codec_create(int method, const char *arg)
1180 {
1181  int ret = -1;
1182  JNIEnv *env = NULL;
1183  FFAMediaCodecJni *codec = NULL;
1184  jstring jarg = NULL;
1185  jobject object = NULL;
1186  jobject buffer_info = NULL;
1187  jmethodID create_id = NULL;
1188 
1189  codec = av_mallocz(sizeof(*codec));
1190  if (!codec) {
1191  return NULL;
1192  }
1193  codec->api = media_codec_jni;
1194 
1195  env = ff_jni_get_env(codec);
1196  if (!env) {
1197  av_freep(&codec);
1198  return NULL;
1199  }
1200 
1201  if (ff_jni_init_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec) < 0) {
1202  goto fail;
1203  }
1204 
1205  jarg = ff_jni_utf_chars_to_jstring(env, arg, codec);
1206  if (!jarg) {
1207  goto fail;
1208  }
1209 
1210  switch (method) {
1211  case CREATE_CODEC_BY_NAME: create_id = codec->jfields.create_by_codec_name_id; break;
1212  case CREATE_DECODER_BY_TYPE: create_id = codec->jfields.create_decoder_by_type_id; break;
1213  case CREATE_ENCODER_BY_TYPE: create_id = codec->jfields.create_encoder_by_type_id; break;
1214  default:
1215  av_assert0(0);
1216  }
1217 
1218  object = (*env)->CallStaticObjectMethod(env,
1219  codec->jfields.mediacodec_class,
1220  create_id,
1221  jarg);
1222  if (ff_jni_exception_check(env, 1, codec) < 0) {
1223  goto fail;
1224  }
1225 
1226  codec->object = (*env)->NewGlobalRef(env, object);
1227  if (!codec->object) {
1228  goto fail;
1229  }
1230 
1231  if (codec_init_static_fields(codec) < 0) {
1232  goto fail;
1233  }
1234 
1236  codec->has_get_i_o_buffer = 1;
1237  }
1238 
1239  buffer_info = (*env)->NewObject(env, codec->jfields.mediainfo_class, codec->jfields.init_id);
1240  if (ff_jni_exception_check(env, 1, codec) < 0) {
1241  goto fail;
1242  }
1243 
1244  codec->buffer_info = (*env)->NewGlobalRef(env, buffer_info);
1245  if (!codec->buffer_info) {
1246  goto fail;
1247  }
1248 
1249  ret = 0;
1250 fail:
1251  if (jarg) {
1252  (*env)->DeleteLocalRef(env, jarg);
1253  }
1254 
1255  if (object) {
1256  (*env)->DeleteLocalRef(env, object);
1257  }
1258 
1259  if (buffer_info) {
1260  (*env)->DeleteLocalRef(env, buffer_info);
1261  }
1262 
1263  if (ret < 0) {
1264  if (codec->object) {
1265  (*env)->DeleteGlobalRef(env, codec->object);
1266  }
1267 
1268  if (codec->buffer_info) {
1269  (*env)->DeleteGlobalRef(env, codec->buffer_info);
1270  }
1271 
1272  ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
1273  av_freep(&codec);
1274  }
1275 
1276  return (FFAMediaCodec *)codec;
1277 }
1278 
1279 #define DECLARE_FF_AMEDIACODEC_CREATE_FUNC(name, method) \
1280 static FFAMediaCodec *mediacodec_jni_##name(const char *arg) \
1281 { \
1282  return codec_create(method, arg); \
1283 } \
1284 
1288 
1290 {
1291  int ret = 0;
1293  JNIEnv *env = NULL;
1294 
1295  if (!codec) {
1296  return 0;
1297  }
1298 
1300 
1301  (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_id);
1302  if (ff_jni_exception_check(env, 1, codec) < 0) {
1304  }
1305 
1306  (*env)->DeleteGlobalRef(env, codec->input_buffers);
1307  codec->input_buffers = NULL;
1308 
1309  (*env)->DeleteGlobalRef(env, codec->output_buffers);
1310  codec->output_buffers = NULL;
1311 
1312  (*env)->DeleteGlobalRef(env, codec->object);
1313  codec->object = NULL;
1314 
1315  (*env)->DeleteGlobalRef(env, codec->buffer_info);
1316  codec->buffer_info = NULL;
1317 
1318  ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
1319 
1320  av_freep(&codec);
1321 
1322  return ret;
1323 }
1324 
1326 {
1327  char *ret = NULL;
1328  JNIEnv *env = NULL;
1329  jobject *name = NULL;
1331 
1332  JNI_GET_ENV_OR_RETURN(env, codec, NULL);
1333 
1334  name = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_name_id);
1335  if (ff_jni_exception_check(env, 1, codec) < 0) {
1336  goto fail;
1337  }
1338 
1339  ret = ff_jni_jstring_to_utf_chars(env, name, codec);
1340 
1341 fail:
1342  if (name) {
1343  (*env)->DeleteLocalRef(env, name);
1344  }
1345 
1346  return ret;
1347 }
1348 
1350  const FFAMediaFormat* format_ctx,
1352  void *crypto,
1353  uint32_t flags)
1354 {
1355  int ret = 0;
1356  JNIEnv *env = NULL;
1358  const FFAMediaFormatJni *format = (FFAMediaFormatJni *)format_ctx;
1359  jobject *surface = window ? window->surface : NULL;
1360 
1362 
1363  if (flags & codec->CONFIGURE_FLAG_ENCODE) {
1364  if (surface && !codec->jfields.set_input_surface_id) {
1365  av_log(ctx, AV_LOG_ERROR, "System doesn't support setInputSurface\n");
1366  return AVERROR_EXTERNAL;
1367  }
1368 
1369  (*env)->CallVoidMethod(env, codec->object, codec->jfields.configure_id, format->object, NULL, NULL, flags);
1370  if (ff_jni_exception_check(env, 1, codec) < 0)
1371  return AVERROR_EXTERNAL;
1372 
1373  if (!surface)
1374  return 0;
1375 
1376  (*env)->CallVoidMethod(env, codec->object, codec->jfields.set_input_surface_id, surface);
1377  if (ff_jni_exception_check(env, 1, codec) < 0)
1378  return AVERROR_EXTERNAL;
1379  return 0;
1380  } else {
1381  (*env)->CallVoidMethod(env, codec->object, codec->jfields.configure_id, format->object, surface, NULL, flags);
1382  }
1383  if (ff_jni_exception_check(env, 1, codec) < 0) {
1385  goto fail;
1386  }
1387 
1388 fail:
1389  return ret;
1390 }
1391 
1393 {
1394  int ret = 0;
1395  JNIEnv *env = NULL;
1397 
1399 
1400  (*env)->CallVoidMethod(env, codec->object, codec->jfields.start_id);
1401  if (ff_jni_exception_check(env, 1, codec) < 0) {
1403  goto fail;
1404  }
1405 
1406 fail:
1407  return ret;
1408 }
1409 
1411 {
1412  int ret = 0;
1413  JNIEnv *env = NULL;
1415 
1417 
1418  (*env)->CallVoidMethod(env, codec->object, codec->jfields.stop_id);
1419  if (ff_jni_exception_check(env, 1, codec) < 0) {
1421  goto fail;
1422  }
1423 
1424 fail:
1425  return ret;
1426 }
1427 
1429 {
1430  int ret = 0;
1431  JNIEnv *env = NULL;
1433 
1435 
1436  (*env)->CallVoidMethod(env, codec->object, codec->jfields.flush_id);
1437  if (ff_jni_exception_check(env, 1, codec) < 0) {
1439  goto fail;
1440  }
1441 
1442 fail:
1443  return ret;
1444 }
1445 
1446 static int mediacodec_jni_releaseOutputBuffer(FFAMediaCodec* ctx, size_t idx, int render)
1447 {
1448  int ret = 0;
1449  JNIEnv *env = NULL;
1451 
1453 
1454  (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_id, (jint)idx, (jboolean)render);
1455  if (ff_jni_exception_check(env, 1, codec) < 0) {
1457  goto fail;
1458  }
1459 
1460 fail:
1461  return ret;
1462 }
1463 
1464 static int mediacodec_jni_releaseOutputBufferAtTime(FFAMediaCodec *ctx, size_t idx, int64_t timestampNs)
1465 {
1466  int ret = 0;
1467  JNIEnv *env = NULL;
1469 
1471 
1472  (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, (jlong)timestampNs);
1473  if (ff_jni_exception_check(env, 1, codec) < 0) {
1475  goto fail;
1476  }
1477 
1478 fail:
1479  return ret;
1480 }
1481 
1482 static ssize_t mediacodec_jni_dequeueInputBuffer(FFAMediaCodec* ctx, int64_t timeoutUs)
1483 {
1484  int ret = 0;
1485  JNIEnv *env = NULL;
1487 
1489 
1490  ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_input_buffer_id, timeoutUs);
1491  if (ff_jni_exception_check(env, 1, codec) < 0) {
1493  goto fail;
1494  }
1495 
1496 fail:
1497  return ret;
1498 }
1499 
1500 static int mediacodec_jni_queueInputBuffer(FFAMediaCodec* ctx, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
1501 {
1502  int ret = 0;
1503  JNIEnv *env = NULL;
1505 
1507 
1508  (*env)->CallVoidMethod(env, codec->object, codec->jfields.queue_input_buffer_id, (jint)idx, (jint)offset, (jint)size, time, flags);
1509  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1511  goto fail;
1512  }
1513 
1514 fail:
1515  return ret;
1516 }
1517 
1519 {
1520  int ret = 0;
1521  JNIEnv *env = NULL;
1523 
1525 
1526  ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_output_buffer_id, codec->buffer_info, timeoutUs);
1527  if (ff_jni_exception_check(env, 1, codec) < 0) {
1528  return AVERROR_EXTERNAL;
1529  }
1530 
1531  info->flags = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.flags_id);
1532  if (ff_jni_exception_check(env, 1, codec) < 0) {
1533  return AVERROR_EXTERNAL;
1534  }
1535 
1536  info->offset = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.offset_id);
1537  if (ff_jni_exception_check(env, 1, codec) < 0) {
1538  return AVERROR_EXTERNAL;
1539  }
1540 
1541  info->presentationTimeUs = (*env)->GetLongField(env, codec->buffer_info, codec->jfields.presentation_time_us_id);
1542  if (ff_jni_exception_check(env, 1, codec) < 0) {
1543  return AVERROR_EXTERNAL;
1544  }
1545 
1546  info->size = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.size_id);
1547  if (ff_jni_exception_check(env, 1, codec) < 0) {
1548  return AVERROR_EXTERNAL;
1549  }
1550 
1551  return ret;
1552 }
1553 
1554 static uint8_t* mediacodec_jni_getInputBuffer(FFAMediaCodec* ctx, size_t idx, size_t *out_size)
1555 {
1556  uint8_t *ret = NULL;
1557  JNIEnv *env = NULL;
1559  jobject buffer = NULL;
1560  jobject input_buffers = NULL;
1561 
1562  JNI_GET_ENV_OR_RETURN(env, codec, NULL);
1563 
1564  if (codec->has_get_i_o_buffer) {
1565  buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffer_id, (jint)idx);
1566  if (ff_jni_exception_check(env, 1, codec) < 0) {
1567  goto fail;
1568  }
1569  } else {
1570  if (!codec->input_buffers) {
1571  input_buffers = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffers_id);
1572  if (ff_jni_exception_check(env, 1, codec) < 0) {
1573  goto fail;
1574  }
1575 
1576  codec->input_buffers = (*env)->NewGlobalRef(env, input_buffers);
1577  if (ff_jni_exception_check(env, 1, codec) < 0) {
1578  goto fail;
1579  }
1580  }
1581 
1582  buffer = (*env)->GetObjectArrayElement(env, codec->input_buffers, idx);
1583  if (ff_jni_exception_check(env, 1, codec) < 0) {
1584  goto fail;
1585  }
1586  }
1587 
1588  ret = (*env)->GetDirectBufferAddress(env, buffer);
1589  *out_size = (*env)->GetDirectBufferCapacity(env, buffer);
1590 fail:
1591  if (buffer) {
1592  (*env)->DeleteLocalRef(env, buffer);
1593  }
1594 
1595  if (input_buffers) {
1596  (*env)->DeleteLocalRef(env, input_buffers);
1597  }
1598 
1599  return ret;
1600 }
1601 
1602 static uint8_t* mediacodec_jni_getOutputBuffer(FFAMediaCodec* ctx, size_t idx, size_t *out_size)
1603 {
1604  uint8_t *ret = NULL;
1605  JNIEnv *env = NULL;
1607  jobject buffer = NULL;
1608  jobject output_buffers = NULL;
1609 
1610  JNI_GET_ENV_OR_RETURN(env, codec, NULL);
1611 
1612  if (codec->has_get_i_o_buffer) {
1613  buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffer_id, (jint)idx);
1614  if (ff_jni_exception_check(env, 1, codec) < 0) {
1615  goto fail;
1616  }
1617  } else {
1618  if (!codec->output_buffers) {
1619  output_buffers = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffers_id);
1620  if (ff_jni_exception_check(env, 1, codec) < 0) {
1621  goto fail;
1622  }
1623 
1624  codec->output_buffers = (*env)->NewGlobalRef(env, output_buffers);
1625  if (ff_jni_exception_check(env, 1, codec) < 0) {
1626  goto fail;
1627  }
1628  }
1629 
1630  buffer = (*env)->GetObjectArrayElement(env, codec->output_buffers, idx);
1631  if (ff_jni_exception_check(env, 1, codec) < 0) {
1632  goto fail;
1633  }
1634  }
1635 
1636  ret = (*env)->GetDirectBufferAddress(env, buffer);
1637  *out_size = (*env)->GetDirectBufferCapacity(env, buffer);
1638 fail:
1639  if (buffer) {
1640  (*env)->DeleteLocalRef(env, buffer);
1641  }
1642 
1643  if (output_buffers) {
1644  (*env)->DeleteLocalRef(env, output_buffers);
1645  }
1646 
1647  return ret;
1648 }
1649 
1651 {
1652  FFAMediaFormat *ret = NULL;
1653  JNIEnv *env = NULL;
1655 
1656  jobject mediaformat = NULL;
1657 
1658  JNI_GET_ENV_OR_RETURN(env, codec, NULL);
1659 
1660  mediaformat = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_format_id);
1661  if (ff_jni_exception_check(env, 1, codec) < 0) {
1662  goto fail;
1663  }
1664 
1665  ret = mediaformat_jni_newFromObject(mediaformat);
1666 fail:
1667  if (mediaformat) {
1668  (*env)->DeleteLocalRef(env, mediaformat);
1669  }
1670 
1671  return ret;
1672 }
1673 
1675 {
1677  return idx == codec->INFO_TRY_AGAIN_LATER;
1678 }
1679 
1681 {
1683  return idx == codec->INFO_OUTPUT_BUFFERS_CHANGED;
1684 }
1685 
1687 {
1689  return idx == codec->INFO_OUTPUT_FORMAT_CHANGED;
1690 }
1691 
1693 {
1695  return codec->BUFFER_FLAG_CODEC_CONFIG;
1696 }
1697 
1699 {
1701  return codec->BUFFER_FLAG_END_OF_STREAM;
1702 }
1703 
1705 {
1707  return codec->BUFFER_FLAG_KEY_FRAME;
1708 }
1709 
1711 {
1713  return codec->CONFIGURE_FLAG_ENCODE;
1714 }
1715 
1717 {
1718  int ret = 0;
1720 
1721  if (!codec->has_get_i_o_buffer) {
1722  if (codec->output_buffers) {
1723  JNIEnv *env = NULL;
1724 
1725  env = ff_jni_get_env(codec);
1726  if (!env) {
1728  goto fail;
1729  }
1730 
1731  (*env)->DeleteGlobalRef(env, codec->output_buffers);
1732  codec->output_buffers = NULL;
1733  }
1734  }
1735 
1736 fail:
1737  return ret;
1738 }
1739 
1741 {
1742  JNIEnv *env = NULL;
1744 
1746 
1747  (*env)->CallVoidMethod(env, codec->object, codec->jfields.signal_end_of_input_stream_id);
1748  if (ff_jni_exception_check(env, 1, codec) < 0) {
1749  return AVERROR_EXTERNAL;
1750  }
1751 
1752  return 0;
1753 }
1754 
1755 static const FFAMediaFormat media_format_jni = {
1757 
1758  .create = mediaformat_jni_new,
1760 
1761  .toString = mediaformat_jni_toString,
1762 
1763  .getInt32 = mediaformat_jni_getInt32,
1764  .getInt64 = mediaformat_jni_getInt64,
1765  .getFloat = mediaformat_jni_getFloat,
1766  .getBuffer = mediaformat_jni_getBuffer,
1767  .getString = mediaformat_jni_getString,
1768 
1769  .setInt32 = mediaformat_jni_setInt32,
1770  .setInt64 = mediaformat_jni_setInt64,
1771  .setFloat = mediaformat_jni_setFloat,
1772  .setString = mediaformat_jni_setString,
1773  .setBuffer = mediaformat_jni_setBuffer,
1774 };
1775 
1776 static const FFAMediaCodec media_codec_jni = {
1778 
1779  .getName = mediacodec_jni_getName,
1780 
1781  .createCodecByName = mediacodec_jni_createCodecByName,
1782  .createDecoderByType = mediacodec_jni_createDecoderByType,
1783  .createEncoderByType = mediacodec_jni_createEncoderByType,
1784  .delete = mediacodec_jni_delete,
1785 
1786  .configure = mediacodec_jni_configure,
1787  .start = mediacodec_jni_start,
1788  .stop = mediacodec_jni_stop,
1789  .flush = mediacodec_jni_flush,
1790 
1791  .getInputBuffer = mediacodec_jni_getInputBuffer,
1792  .getOutputBuffer = mediacodec_jni_getOutputBuffer,
1793 
1794  .dequeueInputBuffer = mediacodec_jni_dequeueInputBuffer,
1795  .queueInputBuffer = mediacodec_jni_queueInputBuffer,
1796 
1797  .dequeueOutputBuffer = mediacodec_jni_dequeueOutputBuffer,
1798  .getOutputFormat = mediacodec_jni_getOutputFormat,
1799 
1800  .releaseOutputBuffer = mediacodec_jni_releaseOutputBuffer,
1801  .releaseOutputBufferAtTime = mediacodec_jni_releaseOutputBufferAtTime,
1802 
1803  .infoTryAgainLater = mediacodec_jni_infoTryAgainLater,
1804  .infoOutputBuffersChanged = mediacodec_jni_infoOutputBuffersChanged,
1805  .infoOutputFormatChanged = mediacodec_jni_infoOutputFormatChanged,
1806 
1807  .getBufferFlagCodecConfig = mediacodec_jni_getBufferFlagCodecConfig,
1808  .getBufferFlagEndOfStream = mediacodec_jni_getBufferFlagEndOfStream,
1809  .getBufferFlagKeyFrame = mediacodec_jni_getBufferFlagKeyFrame,
1810 
1811  .getConfigureFlagEncode = mediacodec_jni_getConfigureFlagEncode,
1812  .cleanOutputBuffers = mediacodec_jni_cleanOutputBuffers,
1813  .signalEndOfInputStream = mediacodec_jni_signalEndOfInputStream,
1814 };
1815 
1816 typedef struct FFAMediaFormatNdk {
1818 
1819  void *libmedia;
1820  AMediaFormat *impl;
1821 
1822  AMediaFormat *(*new)(void);
1823  media_status_t (*delete)(AMediaFormat*);
1824 
1825  const char* (*toString)(AMediaFormat*);
1826 
1827  bool (*getInt32)(AMediaFormat*, const char *name, int32_t *out);
1828  bool (*getInt64)(AMediaFormat*, const char *name, int64_t *out);
1829  bool (*getFloat)(AMediaFormat*, const char *name, float *out);
1830  bool (*getSize)(AMediaFormat*, const char *name, size_t *out);
1831  bool (*getBuffer)(AMediaFormat*, const char *name, void** data, size_t *size);
1832  bool (*getString)(AMediaFormat*, const char *name, const char **out);
1833  bool (*getRect)(AMediaFormat *, const char *name,
1834  int32_t *left, int32_t *top, int32_t *right, int32_t *bottom);
1835 
1836  void (*setInt32)(AMediaFormat*, const char* name, int32_t value);
1837  void (*setInt64)(AMediaFormat*, const char* name, int64_t value);
1838  void (*setFloat)(AMediaFormat*, const char* name, float value);
1839  void (*setString)(AMediaFormat*, const char* name, const char* value);
1840  void (*setBuffer)(AMediaFormat*, const char* name, const void* data, size_t size);
1841  void (*setRect)(AMediaFormat *, const char *name,
1842  int32_t left, int32_t top, int32_t right, int32_t bottom);
1844 
1845 typedef struct FFAMediaCodecNdk {
1847 
1848  void *libmedia;
1849  AMediaCodec *impl;
1850  ANativeWindow *window;
1851 
1852  AMediaCodec* (*createCodecByName)(const char *name);
1853  AMediaCodec* (*createDecoderByType)(const char *mime_type);
1854  AMediaCodec* (*createEncoderByType)(const char *mime_type);
1855  media_status_t (*delete)(AMediaCodec*);
1856 
1857  media_status_t (*configure)(AMediaCodec *,
1858  const AMediaFormat *format,
1859  ANativeWindow *surface,
1860  AMediaCrypto *crypto,
1861  uint32_t flags);
1862  media_status_t (*start)(AMediaCodec*);
1863  media_status_t (*stop)(AMediaCodec*);
1864  media_status_t (*flush)(AMediaCodec*);
1865 
1866  uint8_t* (*getInputBuffer)(AMediaCodec*, size_t idx, size_t *out_size);
1867  uint8_t* (*getOutputBuffer)(AMediaCodec*, size_t idx, size_t *out_size);
1868 
1869  ssize_t (*dequeueInputBuffer)(AMediaCodec*, int64_t timeoutUs);
1870  media_status_t (*queueInputBuffer)(AMediaCodec*, size_t idx,
1871  long offset, size_t size,
1872  uint64_t time, uint32_t flags);
1873 
1874  ssize_t (*dequeueOutputBuffer)(AMediaCodec*, AMediaCodecBufferInfo *info, int64_t timeoutUs);
1875  AMediaFormat* (*getOutputFormat)(AMediaCodec*);
1876 
1877  media_status_t (*releaseOutputBuffer)(AMediaCodec*, size_t idx, bool render);
1878  media_status_t (*releaseOutputBufferAtTime)(AMediaCodec *mData, size_t idx, int64_t timestampNs);
1879 
1880  // Available since API level 28.
1881  media_status_t (*getName)(AMediaCodec*, char** out_name);
1882  void (*releaseName)(AMediaCodec*, char* name);
1883 
1884  // Available since API level 26.
1885  media_status_t (*setInputSurface)(AMediaCodec*, ANativeWindow *);
1886  media_status_t (*signalEndOfInputStream)(AMediaCodec *);
1888 
1891 
1893  .class_name = "amediaformat_ndk",
1894  .item_name = av_default_item_name,
1895  .version = LIBAVUTIL_VERSION_INT,
1896 };
1897 
1899  .class_name = "amediacodec_ndk",
1900  .item_name = av_default_item_name,
1901  .version = LIBAVUTIL_VERSION_INT,
1902 };
1903 
1904 static FFAMediaFormat *mediaformat_ndk_create(AMediaFormat *impl)
1905 {
1907  if (!format)
1908  return NULL;
1909 
1910  format->api = media_format_ndk;
1911 
1912  format->libmedia = dlopen("libmediandk.so", RTLD_NOW);
1913  if (!format->libmedia)
1914  goto error;
1915 
1916 #define GET_OPTIONAL_SYMBOL(sym) \
1917  format->sym = dlsym(format->libmedia, "AMediaFormat_" #sym);
1918 
1919 #define GET_SYMBOL(sym) \
1920  GET_OPTIONAL_SYMBOL(sym) \
1921  if (!format->sym) \
1922  goto error;
1923 
1924  GET_SYMBOL(new)
1925  GET_SYMBOL(delete)
1926 
1927  GET_SYMBOL(toString)
1928 
1929  GET_SYMBOL(getInt32)
1930  GET_SYMBOL(getInt64)
1931  GET_SYMBOL(getFloat)
1932  GET_SYMBOL(getSize)
1933  GET_SYMBOL(getBuffer)
1934  GET_SYMBOL(getString)
1935  GET_OPTIONAL_SYMBOL(getRect)
1936 
1937  GET_SYMBOL(setInt32)
1938  GET_SYMBOL(setInt64)
1939  GET_SYMBOL(setFloat)
1940  GET_SYMBOL(setString)
1941  GET_SYMBOL(setBuffer)
1942  GET_OPTIONAL_SYMBOL(setRect)
1943 
1944 #undef GET_SYMBOL
1945 #undef GET_OPTIONAL_SYMBOL
1946 
1947  if (impl) {
1948  format->impl = impl;
1949  } else {
1950  format->impl = format->new();
1951  if (!format->impl)
1952  goto error;
1953  }
1954 
1955  return (FFAMediaFormat *)format;
1956 
1957 error:
1958  if (format->libmedia)
1959  dlclose(format->libmedia);
1960  av_freep(&format);
1961  return NULL;
1962 }
1963 
1965 {
1966  return mediaformat_ndk_create(NULL);
1967 }
1968 
1970 {
1972  int ret = 0;
1973  if (!format)
1974  return 0;
1975 
1976  av_assert0(format->api.class == &amediaformat_ndk_class);
1977 
1978  if (format->impl && (format->delete(format->impl) != AMEDIA_OK))
1980  if (format->libmedia)
1981  dlclose(format->libmedia);
1982  av_free(format);
1983 
1984  return ret;
1985 }
1986 
1988 {
1990  const char *str = format->toString(format->impl);
1991  return av_strdup(str);
1992 }
1993 
1995 {
1997  return format->getInt32(format->impl, name, out);
1998 }
1999 
2000 static int mediaformat_ndk_getInt64(FFAMediaFormat* ctx, const char *name, int64_t *out)
2001 {
2003  return format->getInt64(format->impl, name, out);
2004 }
2005 
2006 static int mediaformat_ndk_getFloat(FFAMediaFormat* ctx, const char *name, float *out)
2007 {
2009  return format->getFloat(format->impl, name, out);
2010 }
2011 
2012 static int mediaformat_ndk_getBuffer(FFAMediaFormat* ctx, const char *name, void** data, size_t *size)
2013 {
2015  return format->getBuffer(format->impl, name, data, size);
2016 }
2017 
2018 static int mediaformat_ndk_getString(FFAMediaFormat* ctx, const char *name, const char **out)
2019 {
2021  const char *tmp = NULL;
2022  int ret = format->getString(format->impl, name, &tmp);
2023 
2024  if (tmp)
2025  *out = av_strdup(tmp);
2026  return ret;
2027 }
2028 
2030  int32_t *left, int32_t *top, int32_t *right, int32_t *bottom)
2031 {
2033  if (!format->getRect)
2034  return AVERROR_EXTERNAL;
2035  return format->getRect(format->impl, name, left, top, right, bottom);
2036 }
2037 
2039 {
2041  format->setInt32(format->impl, name, value);
2042 }
2043 
2044 static void mediaformat_ndk_setInt64(FFAMediaFormat* ctx, const char* name, int64_t value)
2045 {
2047  format->setInt64(format->impl, name, value);
2048 }
2049 
2050 static void mediaformat_ndk_setFloat(FFAMediaFormat* ctx, const char* name, float value)
2051 {
2053  format->setFloat(format->impl, name, value);
2054 }
2055 
2056 static void mediaformat_ndk_setString(FFAMediaFormat* ctx, const char* name, const char* value)
2057 {
2059  format->setString(format->impl, name, value);
2060 }
2061 
2062 static void mediaformat_ndk_setBuffer(FFAMediaFormat* ctx, const char* name, void* data, size_t size)
2063 {
2065  format->setBuffer(format->impl, name, data, size);
2066 }
2067 
2069  int32_t left, int32_t top, int32_t right, int32_t bottom)
2070 {
2072  if (!format->setRect) {
2073  av_log(ctx, AV_LOG_WARNING, "Doesn't support setRect\n");
2074  return;
2075  }
2076  format->setRect(format->impl, name, left, top, right, bottom);
2077 }
2078 
2080 {
2082  char *ret = NULL;
2083  char *name = NULL;
2084 
2085  if (!codec->getName || !codec->releaseName) {
2086  av_log(ctx, AV_LOG_DEBUG, "getName() unavailable\n");
2087  return ret;
2088  }
2089 
2090  codec->getName(codec->impl, &name);
2091  if (name) {
2092  ret = av_strdup(name);
2093  codec->releaseName(codec->impl, name);
2094  }
2095 
2096  return ret;
2097 }
2098 
2099 static inline FFAMediaCodec *ndk_codec_create(int method, const char *arg) {
2100  FFAMediaCodecNdk *codec = av_mallocz(sizeof(*codec));
2101  const char *lib_name = "libmediandk.so";
2102 
2103  if (!codec)
2104  return NULL;
2105 
2106  codec->api = media_codec_ndk;
2107  codec->libmedia = dlopen(lib_name, RTLD_NOW);
2108  if (!codec->libmedia)
2109  goto error;
2110 
2111 #define GET_SYMBOL(sym, required) \
2112  codec->sym = dlsym(codec->libmedia, "AMediaCodec_" #sym); \
2113  if (!codec->sym) { \
2114  av_log(codec, required ? AV_LOG_ERROR : AV_LOG_INFO, \
2115  #sym "() unavailable from %s\n", lib_name); \
2116  if (required) \
2117  goto error; \
2118  }
2119 
2120  GET_SYMBOL(createCodecByName, 1)
2121  GET_SYMBOL(createDecoderByType, 1)
2122  GET_SYMBOL(createEncoderByType, 1)
2123  GET_SYMBOL(delete, 1)
2124 
2125  GET_SYMBOL(configure, 1)
2126  GET_SYMBOL(start, 1)
2127  GET_SYMBOL(stop, 1)
2128  GET_SYMBOL(flush, 1)
2129 
2130  GET_SYMBOL(getInputBuffer, 1)
2131  GET_SYMBOL(getOutputBuffer, 1)
2132 
2133  GET_SYMBOL(dequeueInputBuffer, 1)
2134  GET_SYMBOL(queueInputBuffer, 1)
2135 
2136  GET_SYMBOL(dequeueOutputBuffer, 1)
2137  GET_SYMBOL(getOutputFormat, 1)
2138 
2139  GET_SYMBOL(releaseOutputBuffer, 1)
2140  GET_SYMBOL(releaseOutputBufferAtTime, 1)
2141 
2142  GET_SYMBOL(getName, 0)
2143  GET_SYMBOL(releaseName, 0)
2144 
2145  GET_SYMBOL(setInputSurface, 0)
2146  GET_SYMBOL(signalEndOfInputStream, 0)
2147 
2148 #undef GET_SYMBOL
2149 
2150  switch (method) {
2151  case CREATE_CODEC_BY_NAME:
2152  codec->impl = codec->createCodecByName(arg);
2153  break;
2155  codec->impl = codec->createDecoderByType(arg);
2156  break;
2158  codec->impl = codec->createEncoderByType(arg);
2159  break;
2160  default:
2161  av_assert0(0);
2162  }
2163  if (!codec->impl)
2164  goto error;
2165 
2166  return (FFAMediaCodec *)codec;
2167 
2168 error:
2169  if (codec->libmedia)
2170  dlclose(codec->libmedia);
2171  av_freep(&codec);
2172  return NULL;
2173 }
2174 
2175 #define DECLARE_NDK_AMEDIACODEC_CREATE_FUNC(name, method) \
2176 static FFAMediaCodec *mediacodec_ndk_##name(const char *arg) \
2177 { \
2178  return ndk_codec_create(method, arg); \
2179 } \
2180 
2184 
2186 {
2188  int ret = 0;
2189 
2190  if (!codec)
2191  return 0;
2192 
2194 
2195  if (codec->impl && (codec->delete(codec->impl) != AMEDIA_OK))
2197  if (codec->window)
2198  ANativeWindow_release(codec->window);
2199  if (codec->libmedia)
2200  dlclose(codec->libmedia);
2201  av_free(codec);
2202 
2203  return ret;
2204 }
2205 
2207  const FFAMediaFormat* format_ctx,
2209  void *crypto,
2210  uint32_t flags)
2211 {
2213  FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)format_ctx;
2214  media_status_t status;
2215  ANativeWindow *native_window = NULL;
2216 
2217  if (window) {
2218  if (window->surface) {
2219  JNIEnv *env = NULL;
2220  JNI_GET_ENV_OR_RETURN(env, ctx, -1);
2221  native_window = ANativeWindow_fromSurface(env, window->surface);
2222  // Save for release
2223  codec->window = native_window;
2224  } else if (window->native_window) {
2225  native_window = window->native_window;
2226  }
2227  }
2228 
2229  if (format_ctx->class != &amediaformat_ndk_class) {
2230  av_log(ctx, AV_LOG_ERROR, "invalid media format\n");
2231  return AVERROR(EINVAL);
2232  }
2233 
2234  if (flags & AMEDIACODEC_CONFIGURE_FLAG_ENCODE) {
2235  if (native_window && !codec->setInputSurface) {
2236  av_log(ctx, AV_LOG_ERROR, "System doesn't support setInputSurface\n");
2237  return AVERROR_EXTERNAL;
2238  }
2239 
2240  status = codec->configure(codec->impl, format->impl, NULL, NULL, flags);
2241  if (status != AMEDIA_OK) {
2242  av_log(codec, AV_LOG_ERROR, "Encoder configure failed, %d\n", status);
2243  return AVERROR_EXTERNAL;
2244  }
2245 
2246  if (!native_window)
2247  return 0;
2248 
2249  status = codec->setInputSurface(codec->impl, native_window);
2250  if (status != AMEDIA_OK) {
2251  av_log(codec, AV_LOG_ERROR, "Encoder set input surface failed, %d\n", status);
2252  return AVERROR_EXTERNAL;
2253  }
2254  } else {
2255  status = codec->configure(codec->impl, format->impl, native_window, NULL, flags);
2256  if (status != AMEDIA_OK) {
2257  av_log(codec, AV_LOG_ERROR, "Decoder configure failed, %d\n", status);
2258  return AVERROR_EXTERNAL;
2259  }
2260  }
2261 
2262  return 0;
2263 }
2264 
2265 #define MEDIACODEC_NDK_WRAPPER(method) \
2266 static int mediacodec_ndk_ ## method(FFAMediaCodec* ctx) \
2267 { \
2268  FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx; \
2269  media_status_t status = codec->method(codec->impl); \
2270  \
2271  if (status != AMEDIA_OK) { \
2272  av_log(codec, AV_LOG_ERROR, #method " failed, %d\n", status); \
2273  return AVERROR_EXTERNAL; \
2274  } \
2275  \
2276  return 0; \
2277 } \
2278 
2282 
2283 static uint8_t* mediacodec_ndk_getInputBuffer(FFAMediaCodec* ctx, size_t idx, size_t *out_size)
2284 {
2286  return codec->getInputBuffer(codec->impl, idx, out_size);
2287 }
2288 
2289 static uint8_t* mediacodec_ndk_getOutputBuffer(FFAMediaCodec* ctx, size_t idx, size_t *out_size)
2290 {
2292  return codec->getOutputBuffer(codec->impl, idx, out_size);
2293 }
2294 
2295 static ssize_t mediacodec_ndk_dequeueInputBuffer(FFAMediaCodec* ctx, int64_t timeoutUs)
2296 {
2298  return codec->dequeueInputBuffer(codec->impl, timeoutUs);
2299 }
2300 
2302  off_t offset, size_t size,
2303  uint64_t time, uint32_t flags)
2304 {
2306  return codec->queueInputBuffer(codec->impl, idx, offset, size, time, flags);
2307 }
2308 
2310 {
2312  AMediaCodecBufferInfo buf_info = {0};
2313  ssize_t ret;
2314 
2315  ret = codec->dequeueOutputBuffer(codec->impl, &buf_info, timeoutUs);
2316  info->offset = buf_info.offset;
2317  info->size = buf_info.size;
2318  info->presentationTimeUs = buf_info.presentationTimeUs;
2319  info->flags = buf_info.flags;
2320 
2321  return ret;
2322 }
2323 
2325 {
2327  AMediaFormat *format = codec->getOutputFormat(codec->impl);
2328 
2329  if (!format)
2330  return NULL;
2332 }
2333 
2334 static int mediacodec_ndk_releaseOutputBuffer(FFAMediaCodec* ctx, size_t idx, int render)
2335 {
2337  media_status_t status;
2338 
2339  status = codec->releaseOutputBuffer(codec->impl, idx, render);
2340  if (status != AMEDIA_OK) {
2341  av_log(codec, AV_LOG_ERROR, "release output buffer failed, %d\n", status);
2342  return AVERROR_EXTERNAL;
2343  }
2344 
2345  return 0;
2346 }
2347 
2348 static int mediacodec_ndk_releaseOutputBufferAtTime(FFAMediaCodec *ctx, size_t idx, int64_t timestampNs)
2349 {
2351  media_status_t status;
2352 
2353  status = codec->releaseOutputBufferAtTime(codec->impl, idx, timestampNs);
2354  if (status != AMEDIA_OK) {
2355  av_log(codec, AV_LOG_ERROR, "releaseOutputBufferAtTime failed, %d\n", status);
2356  return AVERROR_EXTERNAL;
2357  }
2358 
2359  return 0;
2360 }
2361 
2363 {
2364  return idx == AMEDIACODEC_INFO_TRY_AGAIN_LATER;
2365 }
2366 
2368 {
2369  return idx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED;
2370 }
2371 
2373 {
2374  return idx == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED;
2375 }
2376 
2378 {
2379  return AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG;
2380 }
2381 
2383 {
2384  return AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
2385 }
2386 
2388 {
2389  return 1;
2390 }
2391 
2393 {
2394  return AMEDIACODEC_CONFIGURE_FLAG_ENCODE;
2395 }
2396 
2398 {
2399  return 0;
2400 }
2401 
2403 {
2405  media_status_t status;
2406 
2407  if (!codec->signalEndOfInputStream) {
2408  av_log(codec, AV_LOG_ERROR, "signalEndOfInputStream unavailable\n");
2409  return AVERROR_EXTERNAL;
2410  }
2411 
2412  status = codec->signalEndOfInputStream(codec->impl);
2413  if (status != AMEDIA_OK) {
2414  av_log(codec, AV_LOG_ERROR, "signalEndOfInputStream failed, %d\n", status);
2415  return AVERROR_EXTERNAL;
2416  }
2417  av_log(codec, AV_LOG_DEBUG, "signalEndOfInputStream success\n");
2418 
2419  return 0;
2420 }
2421 
2422 static const FFAMediaFormat media_format_ndk = {
2424 
2425  .create = mediaformat_ndk_new,
2427 
2428  .toString = mediaformat_ndk_toString,
2429 
2430  .getInt32 = mediaformat_ndk_getInt32,
2431  .getInt64 = mediaformat_ndk_getInt64,
2432  .getFloat = mediaformat_ndk_getFloat,
2433  .getBuffer = mediaformat_ndk_getBuffer,
2434  .getString = mediaformat_ndk_getString,
2435  .getRect = mediaformat_ndk_getRect,
2436 
2437  .setInt32 = mediaformat_ndk_setInt32,
2438  .setInt64 = mediaformat_ndk_setInt64,
2439  .setFloat = mediaformat_ndk_setFloat,
2440  .setString = mediaformat_ndk_setString,
2441  .setBuffer = mediaformat_ndk_setBuffer,
2442  .setRect = mediaformat_ndk_setRect,
2443 };
2444 
2445 static const FFAMediaCodec media_codec_ndk = {
2447 
2448  .getName = mediacodec_ndk_getName,
2449 
2450  .createCodecByName = mediacodec_ndk_createCodecByName,
2451  .createDecoderByType = mediacodec_ndk_createDecoderByType,
2452  .createEncoderByType = mediacodec_ndk_createEncoderByType,
2453  .delete = mediacodec_ndk_delete,
2454 
2455  .configure = mediacodec_ndk_configure,
2456  .start = mediacodec_ndk_start,
2457  .stop = mediacodec_ndk_stop,
2458  .flush = mediacodec_ndk_flush,
2459 
2460  .getInputBuffer = mediacodec_ndk_getInputBuffer,
2461  .getOutputBuffer = mediacodec_ndk_getOutputBuffer,
2462 
2463  .dequeueInputBuffer = mediacodec_ndk_dequeueInputBuffer,
2464  .queueInputBuffer = mediacodec_ndk_queueInputBuffer,
2465 
2466  .dequeueOutputBuffer = mediacodec_ndk_dequeueOutputBuffer,
2467  .getOutputFormat = mediacodec_ndk_getOutputFormat,
2468 
2469  .releaseOutputBuffer = mediacodec_ndk_releaseOutputBuffer,
2470  .releaseOutputBufferAtTime = mediacodec_ndk_releaseOutputBufferAtTime,
2471 
2472  .infoTryAgainLater = mediacodec_ndk_infoTryAgainLater,
2473  .infoOutputBuffersChanged = mediacodec_ndk_infoOutputBuffersChanged,
2474  .infoOutputFormatChanged = mediacodec_ndk_infoOutputFormatChanged,
2475 
2476  .getBufferFlagCodecConfig = mediacodec_ndk_getBufferFlagCodecConfig,
2477  .getBufferFlagEndOfStream = mediacodec_ndk_getBufferFlagEndOfStream,
2478  .getBufferFlagKeyFrame = mediacodec_ndk_getBufferFlagKeyFrame,
2479 
2480  .getConfigureFlagEncode = mediacodec_ndk_getConfigureFlagEncode,
2481  .cleanOutputBuffers = mediacodec_ndk_cleanOutputBuffers,
2482  .signalEndOfInputStream = mediacodec_ndk_signalEndOfInputStream,
2483 };
2484 
2486 {
2487  if (ndk)
2488  return media_format_ndk.create();
2489  return media_format_jni.create();
2490 }
2491 
2493 {
2494  if (ndk)
2497 }
2498 
2499 FFAMediaCodec* ff_AMediaCodec_createDecoderByType(const char *mime_type, int ndk)
2500 {
2501  if (ndk)
2502  return media_codec_ndk.createDecoderByType(mime_type);
2503  return media_codec_jni.createDecoderByType(mime_type);
2504 }
2505 
2506 FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type, int ndk)
2507 {
2508  if (ndk)
2509  return media_codec_ndk.createEncoderByType(mime_type);
2510  return media_codec_jni.createEncoderByType(mime_type);
2511 }
2512 
2514 {
2515  int ret = -1;
2516 
2517 #if __ANDROID_API__ >= 24
2518  // android_get_device_api_level() is a static inline before API level 29.
2519  // dlsym() might doesn't work.
2520  //
2521  // We can implement android_get_device_api_level() by
2522  // __system_property_get(), but __system_property_get() has created a lot of
2523  // troubles and is deprecated. So avoid using __system_property_get() for
2524  // now.
2525  //
2526  // Hopy we can remove the conditional compilation finally by bumping the
2527  // required API level.
2528  //
2529  ret = android_get_device_api_level();
2530 #else
2531  JNIEnv *env = NULL;
2532  jclass versionClass;
2533  jfieldID sdkIntFieldID;
2534  JNI_GET_ENV_OR_RETURN(env, avctx, -1);
2535 
2536  versionClass = (*env)->FindClass(env, "android/os/Build$VERSION");
2537  sdkIntFieldID = (*env)->GetStaticFieldID(env, versionClass, "SDK_INT", "I");
2538  ret = (*env)->GetStaticIntField(env, versionClass, sdkIntFieldID);
2539  (*env)->DeleteLocalRef(env, versionClass);
2540 #endif
2541  av_log(avctx, AV_LOG_DEBUG, "device api level %d\n", ret);
2542 
2543  return ret;
2544 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
JNIAMediaCodecFields::create_by_codec_name_id
jmethodID create_by_codec_name_id
Definition: mediacodec_wrapper.c:166
JNIAMediaCodecListFields::get_codec_info_at_id
jmethodID get_codec_info_at_id
Definition: mediacodec_wrapper.c:45
FFAMediaCodecJni::jfields
struct JNIAMediaCodecFields jfields
Definition: mediacodec_wrapper.c:266
JNIAMediaCodecFields::get_output_buffer_id
jmethodID get_output_buffer_id
Definition: mediacodec_wrapper.c:186
JNIAMediaCodecListFields::is_software_only_id
jmethodID is_software_only_id
Definition: mediacodec_wrapper.c:52
mediaformat_ndk_setRect
static void mediaformat_ndk_setRect(FFAMediaFormat *ctx, const char *name, int32_t left, int32_t top, int32_t right, int32_t bottom)
Definition: mediacodec_wrapper.c:2068
FFAMediaCodecJni::api
FFAMediaCodec api
Definition: mediacodec_wrapper.c:264
ff_AMediaCodecList_getCodecNameByType
char * ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx)
Definition: mediacodec_wrapper.c:365
JNIAMediaFormatFields::init_id
jmethodID init_id
Definition: mediacodec_wrapper.c:93
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
JNIAMediaFormatFields
Definition: mediacodec_wrapper.c:89
name
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 name
Definition: writing_filters.txt:88
mediaformat_ndk_getString
static int mediaformat_ndk_getString(FFAMediaFormat *ctx, const char *name, const char **out)
Definition: mediacodec_wrapper.c:2018
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
mediacodec_ndk_getBufferFlagKeyFrame
static int mediacodec_ndk_getBufferFlagKeyFrame(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2387
mediacodec_ndk_releaseOutputBuffer
static int mediacodec_ndk_releaseOutputBuffer(FFAMediaCodec *ctx, size_t idx, int render)
Definition: mediacodec_wrapper.c:2334
amediacodec_ndk_class
static const AVClass amediacodec_ndk_class
Definition: mediacodec_wrapper.c:1898
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
mediaformat_jni_setInt32
static void mediaformat_jni_setInt32(FFAMediaFormat *ctx, const char *name, int32_t value)
Definition: mediacodec_wrapper.c:959
JNIAMediaCodecFields::size_id
jfieldID size_id
Definition: mediacodec_wrapper.c:201
FFAMediaCodecNdk::dequeueInputBuffer
ssize_t(* dequeueInputBuffer)(AMediaCodec *, int64_t timeoutUs)
Definition: mediacodec_wrapper.c:1869
mediacodec_jni_cleanOutputBuffers
static int mediacodec_jni_cleanOutputBuffers(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1716
out
FILE * out
Definition: movenc.c:54
FFAMediaCodecNdk::getOutputFormat
AMediaFormat *(* getOutputFormat)(AMediaCodec *)
Definition: mediacodec_wrapper.c:1875
FFAMediaFormatNdk::setString
void(* setString)(AMediaFormat *, const char *name, const char *value)
Definition: mediacodec_wrapper.c:1839
FFAMediaFormatNdk::impl
AMediaFormat * impl
Definition: mediacodec_wrapper.c:1820
mediacodec_ndk_infoOutputBuffersChanged
static int mediacodec_ndk_infoOutputBuffersChanged(FFAMediaCodec *ctx, ssize_t idx)
Definition: mediacodec_wrapper.c:2367
FF_PROFILE_H264_BASELINE
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:1622
mediacodec_ndk_getInputBuffer
static uint8_t * mediacodec_ndk_getInputBuffer(FFAMediaCodec *ctx, size_t idx, size_t *out_size)
Definition: mediacodec_wrapper.c:2283
mediaformat_jni_delete
static int mediaformat_jni_delete(FFAMediaFormat *ctx)
Definition: mediacodec_wrapper.c:687
JNIAMediaCodecFields::flush_id
jmethodID flush_id
Definition: mediacodec_wrapper.c:174
JNIAMediaCodecFields::get_name_id
jmethodID get_name_id
Definition: mediacodec_wrapper.c:170
JNIAMediaFormatFields::get_float_id
jmethodID get_float_id
Definition: mediacodec_wrapper.c:99
mediaformat_jni_new
static FFAMediaFormat * mediaformat_jni_new(void)
Definition: mediacodec_wrapper.c:607
av_strcasecmp
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:218
FF_PROFILE_H264_CONSTRAINED_BASELINE
#define FF_PROFILE_H264_CONSTRAINED_BASELINE
Definition: avcodec.h:1623
FFAMediaCodecNdk::createCodecByName
AMediaCodec *(* createCodecByName)(const char *name)
Definition: mediacodec_wrapper.c:1852
out_size
int out_size
Definition: movenc.c:55
JNIAMediaCodecListFields::mediacodec_list_class
jclass mediacodec_list_class
Definition: mediacodec_wrapper.c:40
JNIAMediaCodecFields::mediainfo_class
jclass mediainfo_class
Definition: mediacodec_wrapper.c:194
jni_amediacodec_mapping
static const struct FFJniField jni_amediacodec_mapping[]
Definition: mediacodec_wrapper.c:205
mediacodec_jni_queueInputBuffer
static int mediacodec_jni_queueInputBuffer(FFAMediaCodec *ctx, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
Definition: mediacodec_wrapper.c:1500
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
mediaformat_jni_setBuffer
static void mediaformat_jni_setBuffer(FFAMediaFormat *ctx, const char *name, void *data, size_t size)
Definition: mediacodec_wrapper.c:1073
JNIAMediaCodecListFields::get_supported_types_id
jmethodID get_supported_types_id
Definition: mediacodec_wrapper.c:50
data
const char data[16]
Definition: mxf.c:146
FF_PROFILE_H264_HIGH_444_PREDICTIVE
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: avcodec.h:1634
FFAMediaFormatNdk
Definition: mediacodec_wrapper.c:1816
amediacodec_class
static const AVClass amediacodec_class
Definition: mediacodec_wrapper.c:257
FFAMediaCodecNdk::queueInputBuffer
media_status_t(* queueInputBuffer)(AMediaCodec *, size_t idx, long offset, size_t size, uint64_t time, uint32_t flags)
Definition: mediacodec_wrapper.c:1870
JNIAMediaCodecFields::info_try_again_later_id
jfieldID info_try_again_later_id
Definition: mediacodec_wrapper.c:156
FFAMediaCodecNdk::delete
media_status_t(* delete)(AMediaCodec *)
Definition: mediacodec_wrapper.c:1855
mediacodec_jni_infoTryAgainLater
static int mediacodec_jni_infoTryAgainLater(FFAMediaCodec *ctx, ssize_t idx)
Definition: mediacodec_wrapper.c:1674
mediacodec_jni_getBufferFlagEndOfStream
static int mediacodec_jni_getBufferFlagEndOfStream(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1698
ff_jni_reset_jfields
int ff_jni_reset_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
Definition: ffjni.c:375
mediacodec_ndk_getConfigureFlagEncode
static int mediacodec_ndk_getConfigureFlagEncode(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2392
mediacodec_jni_start
static int mediacodec_jni_start(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1392
mediaformat_jni_getString
static int mediaformat_jni_getString(FFAMediaFormat *ctx, const char *name, const char **out)
Definition: mediacodec_wrapper.c:909
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
mediaformat_jni_getInt64
static int mediaformat_jni_getInt64(FFAMediaFormat *ctx, const char *name, int64_t *out)
Definition: mediacodec_wrapper.c:773
FFAMediaCodecNdk
Definition: mediacodec_wrapper.c:1845
JNIAMediaCodecFields::presentation_time_us_id
jfieldID presentation_time_us_id
Definition: mediacodec_wrapper.c:200
JNIAMediaCodecListFields::get_name_id
jmethodID get_name_id
Definition: mediacodec_wrapper.c:48
mediacodec_ndk_cleanOutputBuffers
static int mediacodec_ndk_cleanOutputBuffers(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2397
mediaformat_jni_getInt32
static int mediaformat_jni_getInt32(FFAMediaFormat *ctx, const char *name, int32_t *out)
Definition: mediacodec_wrapper.c:734
mediacodec_jni_getOutputFormat
static FFAMediaFormat * mediacodec_jni_getOutputFormat(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1650
JNIAMediaCodecListFields::is_encoder_id
jmethodID is_encoder_id
Definition: mediacodec_wrapper.c:51
window
static SDL_Window * window
Definition: ffplay.c:365
mediacodec_jni_delete
static int mediacodec_jni_delete(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1289
JNIAMediaCodecListFields::get_codec_count_id
jmethodID get_codec_count_id
Definition: mediacodec_wrapper.c:44
jni_amediacodeclist_mapping
static const struct FFJniField jni_amediacodeclist_mapping[]
Definition: mediacodec_wrapper.c:63
FFAMediaCodecNdk::libmedia
void * libmedia
Definition: mediacodec_wrapper.c:1848
JNIAMediaFormatFields::set_long_id
jmethodID set_long_id
Definition: mediacodec_wrapper.c:104
mediaformat_ndk_getInt32
static int mediaformat_ndk_getInt32(FFAMediaFormat *ctx, const char *name, int32_t *out)
Definition: mediacodec_wrapper.c:1994
fail
#define fail()
Definition: checkasm.h:134
mediaformat_jni_setString
static void mediaformat_jni_setString(FFAMediaFormat *ctx, const char *name, const char *value)
Definition: mediacodec_wrapper.c:1037
JNIAMediaCodecFields::set_input_surface_id
jmethodID set_input_surface_id
Definition: mediacodec_wrapper.c:191
mediacodec_ndk_infoTryAgainLater
static int mediacodec_ndk_infoTryAgainLater(FFAMediaCodec *ctx, ssize_t idx)
Definition: mediacodec_wrapper.c:2362
FFAMediaCodecJni::INFO_OUTPUT_FORMAT_CHANGED
int INFO_OUTPUT_FORMAT_CHANGED
Definition: mediacodec_wrapper.c:276
JNIAMediaFormatFields::set_float_id
jmethodID set_float_id
Definition: mediacodec_wrapper.c:105
JNIAMediaCodecListFields::mediacodec_info_class
jclass mediacodec_info_class
Definition: mediacodec_wrapper.c:47
mediacodec_jni_releaseOutputBufferAtTime
static int mediacodec_jni_releaseOutputBufferAtTime(FFAMediaCodec *ctx, size_t idx, int64_t timestampNs)
Definition: mediacodec_wrapper.c:1464
JNIAMediaFormatFields::to_string_id
jmethodID to_string_id
Definition: mediacodec_wrapper.c:109
FFAMediaFormatNdk::setInt64
void(* setInt64)(AMediaFormat *, const char *name, int64_t value)
Definition: mediacodec_wrapper.c:1837
FF_JNI_CLASS
@ FF_JNI_CLASS
Definition: ffjni.h:90
FF_PROFILE_H264_HIGH
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:1626
type
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 type
Definition: writing_filters.txt:86
JNIAMediaCodecFields::release_id
jmethodID release_id
Definition: mediacodec_wrapper.c:176
FFAMediaFormatJni::api
FFAMediaFormat api
Definition: mediacodec_wrapper.c:144
JNIAMediaCodecFields::get_output_buffers_id
jmethodID get_output_buffers_id
Definition: mediacodec_wrapper.c:187
JNIAMediaCodecFields::release_output_buffer_at_time_id
jmethodID release_output_buffer_at_time_id
Definition: mediacodec_wrapper.c:189
ff_AMediaFormat_new
FFAMediaFormat * ff_AMediaFormat_new(int ndk)
Definition: mediacodec_wrapper.c:2485
mediacodec_jni_dequeueOutputBuffer
static ssize_t mediacodec_jni_dequeueOutputBuffer(FFAMediaCodec *ctx, FFAMediaCodecBufferInfo *info, int64_t timeoutUs)
Definition: mediacodec_wrapper.c:1518
CREATE_CODEC_BY_NAME
#define CREATE_CODEC_BY_NAME
Definition: mediacodec_wrapper.c:1175
FFAMediaFormatNdk::getFloat
bool(* getFloat)(AMediaFormat *, const char *name, float *out)
Definition: mediacodec_wrapper.c:1829
FFAMediaCodecNdk::start
media_status_t(* start)(AMediaCodec *)
Definition: mediacodec_wrapper.c:1862
JNIAMediaCodecFields::buffer_flag_codec_config_id
jfieldID buffer_flag_codec_config_id
Definition: mediacodec_wrapper.c:160
ff_jni_utf_chars_to_jstring
jstring ff_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *log_ctx)
Definition: ffjni.c:128
FFAMediaFormat::delete
int(* delete)(FFAMediaFormat *)
Definition: mediacodec_wrapper.h:67
mediacodec_ndk_getName
static char * mediacodec_ndk_getName(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2079
avassert.h
mediaformat_ndk_getInt64
static int mediaformat_ndk_getInt64(FFAMediaFormat *ctx, const char *name, int64_t *out)
Definition: mediacodec_wrapper.c:2000
description
Tag description
Definition: snow.txt:206
mediacodec_jni_infoOutputBuffersChanged
static int mediacodec_jni_infoOutputBuffersChanged(FFAMediaCodec *ctx, ssize_t idx)
Definition: mediacodec_wrapper.c:1680
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
mediacodec_ndk_queueInputBuffer
static int mediacodec_ndk_queueInputBuffer(FFAMediaCodec *ctx, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
Definition: mediacodec_wrapper.c:2301
FF_PROFILE_HEVC_MAIN
#define FF_PROFILE_HEVC_MAIN
Definition: avcodec.h:1671
FFAMediaCodecNdk::signalEndOfInputStream
media_status_t(* signalEndOfInputStream)(AMediaCodec *)
Definition: mediacodec_wrapper.c:1886
JNIAMediaCodecListFields::profile_id
jfieldID profile_id
Definition: mediacodec_wrapper.c:59
FFAMediaCodecJni::output_buffers
jobject output_buffers
Definition: mediacodec_wrapper.c:272
ff_Build_SDK_INT
int ff_Build_SDK_INT(AVCodecContext *avctx)
Definition: mediacodec_wrapper.c:2513
JNIAMediaCodecListFields::codec_profile_level_class
jclass codec_profile_level_class
Definition: mediacodec_wrapper.c:58
mediacodec_ndk_getBufferFlagCodecConfig
static int mediacodec_ndk_getBufferFlagCodecConfig(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2377
mediaformat_jni_setInt64
static void mediaformat_jni_setInt64(FFAMediaFormat *ctx, const char *name, int64_t value)
Definition: mediacodec_wrapper.c:985
JNIAMediaCodecFields::create_decoder_by_type_id
jmethodID create_decoder_by_type_id
Definition: mediacodec_wrapper.c:167
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
JNIAMediaCodecFields::get_output_format_id
jmethodID get_output_format_id
Definition: mediacodec_wrapper.c:178
FF_PROFILE_H264_EXTENDED
#define FF_PROFILE_H264_EXTENDED
Definition: avcodec.h:1625
mediacodec_ndk_dequeueInputBuffer
static ssize_t mediacodec_ndk_dequeueInputBuffer(FFAMediaCodec *ctx, int64_t timeoutUs)
Definition: mediacodec_wrapper.c:2295
JNI_GET_ENV_OR_RETURN_VOID
#define JNI_GET_ENV_OR_RETURN_VOID(env, log_ctx)
Definition: mediacodec_wrapper.c:296
info
MIPS optimizations info
Definition: mips.txt:2
JNIAMediaCodecFields::get_input_buffer_id
jmethodID get_input_buffer_id
Definition: mediacodec_wrapper.c:182
FFAMediaCodecNdk::setInputSurface
media_status_t(* setInputSurface)(AMediaCodec *, ANativeWindow *)
Definition: mediacodec_wrapper.c:1885
FFAMediaFormatNdk::getInt64
bool(* getInt64)(AMediaFormat *, const char *name, int64_t *out)
Definition: mediacodec_wrapper.c:1828
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
JNIAMediaCodecFields::offset_id
jfieldID offset_id
Definition: mediacodec_wrapper.c:199
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
mediaformat_jni_newFromObject
static FFAMediaFormat * mediaformat_jni_newFromObject(void *object)
Definition: mediacodec_wrapper.c:652
JNIAMediaCodecListFields::find_decoder_for_format_id
jmethodID find_decoder_for_format_id
Definition: mediacodec_wrapper.c:42
mediaformat_ndk_getFloat
static int mediaformat_ndk_getFloat(FFAMediaFormat *ctx, const char *name, float *out)
Definition: mediacodec_wrapper.c:2006
key
const char * key
Definition: hwcontext_opencl.c:174
JNIAMediaCodecFields::dequeue_input_buffer_id
jmethodID dequeue_input_buffer_id
Definition: mediacodec_wrapper.c:180
mediacodec_jni_getBufferFlagKeyFrame
static int mediacodec_jni_getBufferFlagKeyFrame(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1704
FFAMediaFormatNdk::getString
bool(* getString)(AMediaFormat *, const char *name, const char **out)
Definition: mediacodec_wrapper.c:1832
FFAMediaCodecJni::CONFIGURE_FLAG_ENCODE
int CONFIGURE_FLAG_ENCODE
Definition: mediacodec_wrapper.c:282
ff_jni_init_jfields
int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
Definition: ffjni.c:286
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:441
arg
const char * arg
Definition: jacosubdec.c:67
FFAMediaFormatNdk::setFloat
void(* setFloat)(AMediaFormat *, const char *name, float value)
Definition: mediacodec_wrapper.c:1838
mediaformat_ndk_setBuffer
static void mediaformat_ndk_setBuffer(FFAMediaFormat *ctx, const char *name, void *data, size_t size)
Definition: mediacodec_wrapper.c:2062
JNIAMediaCodecFields::queue_input_buffer_id
jmethodID queue_input_buffer_id
Definition: mediacodec_wrapper.c:181
mediaformat_ndk_setInt32
static void mediaformat_ndk_setInt32(FFAMediaFormat *ctx, const char *name, int32_t value)
Definition: mediacodec_wrapper.c:2038
JNIAMediaFormatFields::get_string_id
jmethodID get_string_id
Definition: mediacodec_wrapper.c:101
GET_SYMBOL
#define GET_SYMBOL(sym)
mediaformat_ndk_getRect
static int mediaformat_ndk_getRect(FFAMediaFormat *ctx, const char *name, int32_t *left, int32_t *top, int32_t *right, int32_t *bottom)
Definition: mediacodec_wrapper.c:2029
JNIAMediaCodecListFields
Definition: mediacodec_wrapper.c:38
jni_amediaformat_mapping
static const struct FFJniField jni_amediaformat_mapping[]
Definition: mediacodec_wrapper.c:113
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
JNIAMediaCodecFields::create_encoder_by_type_id
jmethodID create_encoder_by_type_id
Definition: mediacodec_wrapper.c:168
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
ff_AMediaCodec_createCodecByName
FFAMediaCodec * ff_AMediaCodec_createCodecByName(const char *name, int ndk)
Definition: mediacodec_wrapper.c:2492
FF_JNI_METHOD
@ FF_JNI_METHOD
Definition: ffjni.h:93
JNIAMediaCodecFields::stop_id
jmethodID stop_id
Definition: mediacodec_wrapper.c:175
NULL
#define NULL
Definition: coverity.c:32
mediacodec_ndk_getBufferFlagEndOfStream
static int mediacodec_ndk_getBufferFlagEndOfStream(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2382
FFAMediaCodecJni::input_buffers
jobject input_buffers
Definition: mediacodec_wrapper.c:271
JNIAMediaCodecFields::release_output_buffer_id
jmethodID release_output_buffer_id
Definition: mediacodec_wrapper.c:188
FFAMediaCodecBufferInfo
Definition: mediacodec_wrapper.h:172
FFAMediaCodecJni::has_get_i_o_buffer
int has_get_i_o_buffer
Definition: mediacodec_wrapper.c:284
FFAMediaCodecJni::BUFFER_FLAG_KEY_FRAME
int BUFFER_FLAG_KEY_FRAME
Definition: mediacodec_wrapper.c:280
FFJniField
Definition: ffjni.h:102
GET_OPTIONAL_SYMBOL
#define GET_OPTIONAL_SYMBOL(sym)
media_codec_ndk
static const FFAMediaCodec media_codec_ndk
Definition: mediacodec_wrapper.c:1890
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
FFAMediaCodecNdk::api
FFAMediaCodec api
Definition: mediacodec_wrapper.c:1846
mediacodec_jni_releaseOutputBuffer
static int mediacodec_jni_releaseOutputBuffer(FFAMediaCodec *ctx, size_t idx, int render)
Definition: mediacodec_wrapper.c:1446
ff_AMediaCodec_createEncoderByType
FFAMediaCodec * ff_AMediaCodec_createEncoderByType(const char *mime_type, int ndk)
Definition: mediacodec_wrapper.c:2506
FF_PROFILE_HEVC_MAIN_10
#define FF_PROFILE_HEVC_MAIN_10
Definition: avcodec.h:1672
mediacodec_jni_getName
static char * mediacodec_jni_getName(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1325
ff_jni_get_env
JNIEnv * ff_jni_get_env(void *log_ctx)
Definition: ffjni.c:52
JNIAMediaCodecFields::get_input_buffers_id
jmethodID get_input_buffers_id
Definition: mediacodec_wrapper.c:183
FFAMediaFormatNdk::setInt32
void(* setInt32)(AMediaFormat *, const char *name, int32_t value)
Definition: mediacodec_wrapper.c:1836
FFAMediaCodecJni::INFO_OUTPUT_BUFFERS_CHANGED
int INFO_OUTPUT_BUFFERS_CHANGED
Definition: mediacodec_wrapper.c:275
JNIAMediaCodecFields::buffer_flag_end_of_stream_id
jfieldID buffer_flag_end_of_stream_id
Definition: mediacodec_wrapper.c:161
JNIAMediaCodecFields::info_output_format_changed_id
jfieldID info_output_format_changed_id
Definition: mediacodec_wrapper.c:158
mediaformat_ndk_getBuffer
static int mediaformat_ndk_getBuffer(FFAMediaFormat *ctx, const char *name, void **data, size_t *size)
Definition: mediacodec_wrapper.c:2012
DECLARE_FF_AMEDIACODEC_CREATE_FUNC
#define DECLARE_FF_AMEDIACODEC_CREATE_FUNC(name, method)
Definition: mediacodec_wrapper.c:1279
JNIAMediaCodecFields::init_id
jmethodID init_id
Definition: mediacodec_wrapper.c:196
mediacodec_jni_dequeueInputBuffer
static ssize_t mediacodec_jni_dequeueInputBuffer(FFAMediaCodec *ctx, int64_t timeoutUs)
Definition: mediacodec_wrapper.c:1482
JNIAMediaCodecListFields::get_codec_capabilities_id
jmethodID get_codec_capabilities_id
Definition: mediacodec_wrapper.c:49
FFAMediaCodecNdk::getName
media_status_t(* getName)(AMediaCodec *, char **out_name)
Definition: mediacodec_wrapper.c:1881
FFAMediaFormatNdk::getRect
bool(* getRect)(AMediaFormat *, const char *name, int32_t *left, int32_t *top, int32_t *right, int32_t *bottom)
Definition: mediacodec_wrapper.c:1833
JNIAMediaCodecFields
Definition: mediacodec_wrapper.c:152
mediaformat_jni_getFloat
static int mediaformat_jni_getFloat(FFAMediaFormat *ctx, const char *name, float *out)
Definition: mediacodec_wrapper.c:812
JNIAMediaCodecFields::configure_id
jmethodID configure_id
Definition: mediacodec_wrapper.c:172
JNIAMediaCodecFields::configure_flag_encode_id
jfieldID configure_flag_encode_id
Definition: mediacodec_wrapper.c:164
JNIAMediaFormatFields::mediaformat_class
jclass mediaformat_class
Definition: mediacodec_wrapper.c:91
FFAMediaCodecNdk::createEncoderByType
AMediaCodec *(* createEncoderByType)(const char *mime_type)
Definition: mediacodec_wrapper.c:1854
FF_PROFILE_H264_HIGH_422
#define FF_PROFILE_H264_HIGH_422
Definition: avcodec.h:1630
FFAMediaCodecNdk::getInputBuffer
uint8_t *(* getInputBuffer)(AMediaCodec *, size_t idx, size_t *out_size)
Definition: mediacodec_wrapper.c:1866
FFAMediaFormatNdk::setBuffer
void(* setBuffer)(AMediaFormat *, const char *name, const void *data, size_t size)
Definition: mediacodec_wrapper.c:1840
media_format_jni
static const FFAMediaFormat media_format_jni
Definition: mediacodec_wrapper.c:150
FFAMediaCodec::createDecoderByType
FFAMediaCodec *(* createDecoderByType)(const char *mime_type)
Definition: mediacodec_wrapper.h:187
FFAMediaCodec::createCodecByName
FFAMediaCodec *(* createCodecByName)(const char *name)
Definition: mediacodec_wrapper.h:186
size
int size
Definition: twinvq_data.h:10344
JNIAMediaFormatFields::get_long_id
jmethodID get_long_id
Definition: mediacodec_wrapper.c:98
media_format_ndk
static const FFAMediaFormat media_format_ndk
Definition: mediacodec_wrapper.c:1889
CREATE_ENCODER_BY_TYPE
#define CREATE_ENCODER_BY_TYPE
Definition: mediacodec_wrapper.c:1177
JNIAMediaFormatFields::set_bytebuffer_id
jmethodID set_bytebuffer_id
Definition: mediacodec_wrapper.c:106
DECLARE_NDK_AMEDIACODEC_CREATE_FUNC
#define DECLARE_NDK_AMEDIACODEC_CREATE_FUNC(name, method)
Definition: mediacodec_wrapper.c:2175
mediacodec_ndk_dequeueOutputBuffer
static ssize_t mediacodec_ndk_dequeueOutputBuffer(FFAMediaCodec *ctx, FFAMediaCodecBufferInfo *info, int64_t timeoutUs)
Definition: mediacodec_wrapper.c:2309
FFAMediaCodecNdk::releaseOutputBufferAtTime
media_status_t(* releaseOutputBufferAtTime)(AMediaCodec *mData, size_t idx, int64_t timestampNs)
Definition: mediacodec_wrapper.c:1878
JNIAMediaCodecFields::start_id
jmethodID start_id
Definition: mediacodec_wrapper.c:173
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
offset
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 offset
Definition: writing_filters.txt:86
ff_AMediaCodecProfile_getProfileFromAVCodecContext
int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx)
The following API around MediaCodec and MediaFormat is based on the NDK one provided by Google since ...
Definition: mediacodec_wrapper.c:303
mediacodec_jni_infoOutputFormatChanged
static int mediacodec_jni_infoOutputFormatChanged(FFAMediaCodec *ctx, ssize_t idx)
Definition: mediacodec_wrapper.c:1686
JNIAMediaFormatFields::get_integer_id
jmethodID get_integer_id
Definition: mediacodec_wrapper.c:97
amediaformat_ndk_class
static const AVClass amediaformat_ndk_class
Definition: mediacodec_wrapper.c:1892
ff_AMediaCodec_createDecoderByType
FFAMediaCodec * ff_AMediaCodec_createDecoderByType(const char *mime_type, int ndk)
Definition: mediacodec_wrapper.c:2499
ff_jni_jstring_to_utf_chars
char * ff_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx)
Definition: ffjni.c:98
FFAMediaCodecNdk::impl
AMediaCodec * impl
Definition: mediacodec_wrapper.c:1849
FFAMediaCodec::class
const AVClass * class
Definition: mediacodec_wrapper.h:182
mediaformat_ndk_new
static FFAMediaFormat * mediaformat_ndk_new(void)
Definition: mediacodec_wrapper.c:1964
FFAMediaCodecNdk::stop
media_status_t(* stop)(AMediaCodec *)
Definition: mediacodec_wrapper.c:1863
JNIAMediaCodecListFields::color_formats_id
jfieldID color_formats_id
Definition: mediacodec_wrapper.c:55
CREATE_DECODER_BY_TYPE
#define CREATE_DECODER_BY_TYPE
Definition: mediacodec_wrapper.c:1176
JNIAMediaFormatFields::set_integer_id
jmethodID set_integer_id
Definition: mediacodec_wrapper.c:103
FF_JNI_FIELD
@ FF_JNI_FIELD
Definition: ffjni.h:91
mediaformat_ndk_create
static FFAMediaFormat * mediaformat_ndk_create(AMediaFormat *impl)
Definition: mediacodec_wrapper.c:1904
mediacodec_jni_flush
static int mediacodec_jni_flush(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1428
buffer_data
Definition: avio_reading.c:37
FFANativeWindow
Definition: mediacodec_surface.h:28
mediacodec_ndk_delete
static int mediacodec_ndk_delete(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2185
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
mediacodec_wrapper.h
FF_PROFILE_HEVC_MAIN_STILL_PICTURE
#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE
Definition: avcodec.h:1673
ffjni.h
FFAMediaCodec
Definition: mediacodec_wrapper.h:181
mediacodec_ndk_getOutputFormat
static FFAMediaFormat * mediacodec_ndk_getOutputFormat(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2324
FFAMediaCodecNdk::getOutputBuffer
uint8_t *(* getOutputBuffer)(AMediaCodec *, size_t idx, size_t *out_size)
Definition: mediacodec_wrapper.c:1867
mediacodec_ndk_signalEndOfInputStream
static int mediacodec_ndk_signalEndOfInputStream(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:2402
FFAMediaCodecNdk::window
ANativeWindow * window
Definition: mediacodec_wrapper.c:1850
FFAMediaFormatJni::jfields
struct JNIAMediaFormatFields jfields
Definition: mediacodec_wrapper.c:146
JNIAMediaCodecFields::buffer_flag_key_frame_id
jfieldID buffer_flag_key_frame_id
Definition: mediacodec_wrapper.c:162
JNIAMediaCodecFields::signal_end_of_input_stream_id
jmethodID signal_end_of_input_stream_id
Definition: mediacodec_wrapper.c:192
ff_jni_exception_check
int ff_jni_exception_check(JNIEnv *env, int log, void *log_ctx)
Definition: ffjni.c:253
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:226
value
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 value
Definition: writing_filters.txt:86
FFAMediaCodecJni::BUFFER_FLAG_END_OF_STREAM
int BUFFER_FLAG_END_OF_STREAM
Definition: mediacodec_wrapper.c:279
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:264
FFAMediaCodecJni::INFO_TRY_AGAIN_LATER
int INFO_TRY_AGAIN_LATER
Definition: mediacodec_wrapper.c:274
FFAMediaFormatNdk::getInt32
bool(* getInt32)(AMediaFormat *, const char *name, int32_t *out)
Definition: mediacodec_wrapper.c:1827
FFAMediaCodecNdk::dequeueOutputBuffer
ssize_t(* dequeueOutputBuffer)(AMediaCodec *, AMediaCodecBufferInfo *info, int64_t timeoutUs)
Definition: mediacodec_wrapper.c:1874
profile
int profile
Definition: mxfenc.c:2006
FF_PROFILE_H264_HIGH_10_INTRA
#define FF_PROFILE_H264_HIGH_10_INTRA
Definition: avcodec.h:1628
FFAMediaCodec::createEncoderByType
FFAMediaCodec *(* createEncoderByType)(const char *mime_type)
Definition: mediacodec_wrapper.h:188
avcodec.h
FFAMediaCodecNdk::createDecoderByType
AMediaCodec *(* createDecoderByType)(const char *mime_type)
Definition: mediacodec_wrapper.c:1853
mediaformat_ndk_setFloat
static void mediaformat_ndk_setFloat(FFAMediaFormat *ctx, const char *name, float value)
Definition: mediacodec_wrapper.c:2050
FF_PROFILE_H264_HIGH_444_INTRA
#define FF_PROFILE_H264_HIGH_444_INTRA
Definition: avcodec.h:1635
JNIAMediaCodecFields::mediacodec_class
jclass mediacodec_class
Definition: mediacodec_wrapper.c:154
ret
ret
Definition: filter_design.txt:187
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
FFAMediaFormat::create
FFAMediaFormat *(* create)(void)
Definition: mediacodec_wrapper.h:66
codec_init_static_fields
static int codec_init_static_fields(FFAMediaCodecJni *codec)
Definition: mediacodec_wrapper.c:1121
mediacodec_jni_getBufferFlagCodecConfig
static int mediacodec_jni_getBufferFlagCodecConfig(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1692
JNIAMediaFormatFields::get_bytebuffer_id
jmethodID get_bytebuffer_id
Definition: mediacodec_wrapper.c:100
FFAMediaFormatNdk::getSize
bool(* getSize)(AMediaFormat *, const char *name, size_t *out)
Definition: mediacodec_wrapper.c:1830
FF_PROFILE_H264_HIGH_444
#define FF_PROFILE_H264_HIGH_444
Definition: avcodec.h:1633
FF_JNI_STATIC_FIELD
@ FF_JNI_STATIC_FIELD
Definition: ffjni.h:92
FFAMediaFormatNdk::setRect
void(* setRect)(AMediaFormat *, const char *name, int32_t left, int32_t top, int32_t right, int32_t bottom)
Definition: mediacodec_wrapper.c:1841
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
mediacodec_jni_getInputBuffer
static uint8_t * mediacodec_jni_getInputBuffer(FFAMediaCodec *ctx, size_t idx, size_t *out_size)
Definition: mediacodec_wrapper.c:1554
FFAMediaCodecJni::buffer_info
jobject buffer_info
Definition: mediacodec_wrapper.c:269
FF_PROFILE_H264_HIGH_422_INTRA
#define FF_PROFILE_H264_HIGH_422_INTRA
Definition: avcodec.h:1631
AVCodecContext
main external API structure.
Definition: avcodec.h:431
mediacodec_jni_getConfigureFlagEncode
static int mediacodec_jni_getConfigureFlagEncode(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1710
JNI_GET_ENV_OR_RETURN
#define JNI_GET_ENV_OR_RETURN(env, log_ctx, ret)
Definition: mediacodec_wrapper.c:289
JNIAMediaCodecListFields::profile_levels_id
jfieldID profile_levels_id
Definition: mediacodec_wrapper.c:56
FFAMediaCodecJni::object
jobject object
Definition: mediacodec_wrapper.c:268
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1583
mediacodec_ndk_getOutputBuffer
static uint8_t * mediacodec_ndk_getOutputBuffer(FFAMediaCodec *ctx, size_t idx, size_t *out_size)
Definition: mediacodec_wrapper.c:2289
mediacodec_jni_signalEndOfInputStream
static int mediacodec_jni_signalEndOfInputStream(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1740
FFAMediaFormatNdk::libmedia
void * libmedia
Definition: mediacodec_wrapper.c:1819
FF_PROFILE_H264_MAIN
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:1624
amediaformat_class
static const AVClass amediaformat_class
Definition: mediacodec_wrapper.c:137
JNIAMediaCodecListFields::init_id
jmethodID init_id
Definition: mediacodec_wrapper.c:41
FFAMediaCodecJni::BUFFER_FLAG_CODEC_CONFIG
int BUFFER_FLAG_CODEC_CONFIG
Definition: mediacodec_wrapper.c:278
FFAMediaFormatJni
Definition: mediacodec_wrapper.c:143
mediaformat_ndk_toString
static char * mediaformat_ndk_toString(FFAMediaFormat *ctx)
Definition: mediacodec_wrapper.c:1987
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:280
mediacodec_jni_configure
static int mediacodec_jni_configure(FFAMediaCodec *ctx, const FFAMediaFormat *format_ctx, FFANativeWindow *window, void *crypto, uint32_t flags)
Definition: mediacodec_wrapper.c:1349
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:367
mem.h
FFAMediaFormatNdk::getBuffer
bool(* getBuffer)(AMediaFormat *, const char *name, void **data, size_t *size)
Definition: mediacodec_wrapper.c:1831
mediaformat_jni_getBuffer
static int mediaformat_jni_getBuffer(FFAMediaFormat *ctx, const char *name, void **data, size_t *size)
Definition: mediacodec_wrapper.c:851
JNIAMediaCodecListFields::level_id
jfieldID level_id
Definition: mediacodec_wrapper.c:60
JNIAMediaCodecFields::dequeue_output_buffer_id
jmethodID dequeue_output_buffer_id
Definition: mediacodec_wrapper.c:185
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
mediaformat_ndk_setInt64
static void mediaformat_ndk_setInt64(FFAMediaFormat *ctx, const char *name, int64_t value)
Definition: mediacodec_wrapper.c:2044
mediacodec_jni_stop
static int mediacodec_jni_stop(FFAMediaCodec *ctx)
Definition: mediacodec_wrapper.c:1410
FF_JNI_STATIC_METHOD
@ FF_JNI_STATIC_METHOD
Definition: ffjni.h:94
FFAMediaFormat::class
const AVClass * class
Definition: mediacodec_wrapper.h:64
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
FF_PROFILE_H264_HIGH_10
#define FF_PROFILE_H264_HIGH_10
Definition: avcodec.h:1627
ndk_codec_create
static FFAMediaCodec * ndk_codec_create(int method, const char *arg)
Definition: mediacodec_wrapper.c:2099
JNIAMediaCodecFields::info_output_buffers_changed_id
jfieldID info_output_buffers_changed_id
Definition: mediacodec_wrapper.c:157
int32_t
int32_t
Definition: audioconvert.c:56
convert_header.str
string str
Definition: convert_header.py:20
MEDIACODEC_NDK_WRAPPER
#define MEDIACODEC_NDK_WRAPPER(method)
Definition: mediacodec_wrapper.c:2265
FFAMediaCodecNdk::configure
media_status_t(* configure)(AMediaCodec *, const AMediaFormat *format, ANativeWindow *surface, AMediaCrypto *crypto, uint32_t flags)
Definition: mediacodec_wrapper.c:1857
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
FFAMediaCodecJni
Definition: mediacodec_wrapper.c:263
mediacodec_jni_getOutputBuffer
static uint8_t * mediacodec_jni_getOutputBuffer(FFAMediaCodec *ctx, size_t idx, size_t *out_size)
Definition: mediacodec_wrapper.c:1602
mediacodec_ndk_releaseOutputBufferAtTime
static int mediacodec_ndk_releaseOutputBufferAtTime(FFAMediaCodec *ctx, size_t idx, int64_t timestampNs)
Definition: mediacodec_wrapper.c:2348
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
JNIAMediaCodecFields::flags_id
jfieldID flags_id
Definition: mediacodec_wrapper.c:198
FFAMediaCodecNdk::releaseName
void(* releaseName)(AMediaCodec *, char *name)
Definition: mediacodec_wrapper.c:1882
FFAMediaFormatNdk::api
FFAMediaFormat api
Definition: mediacodec_wrapper.c:1817
avstring.h
jni.h
media_codec_jni
static const FFAMediaCodec media_codec_jni
Definition: mediacodec_wrapper.c:287
JNIAMediaFormatFields::contains_key_id
jmethodID contains_key_id
Definition: mediacodec_wrapper.c:95
mediacodec_ndk_infoOutputFormatChanged
static int mediacodec_ndk_infoOutputFormatChanged(FFAMediaCodec *ctx, ssize_t idx)
Definition: mediacodec_wrapper.c:2372
FFAMediaCodecNdk::flush
media_status_t(* flush)(AMediaCodec *)
Definition: mediacodec_wrapper.c:1864
mediaformat_jni_toString
static char * mediaformat_jni_toString(FFAMediaFormat *ctx)
Definition: mediacodec_wrapper.c:709
JNIAMediaCodecListFields::codec_capabilities_class
jclass codec_capabilities_class
Definition: mediacodec_wrapper.c:54
mediaformat_ndk_setString
static void mediaformat_ndk_setString(FFAMediaFormat *ctx, const char *name, const char *value)
Definition: mediacodec_wrapper.c:2056
FFAMediaFormat
Definition: mediacodec_wrapper.h:63
JNIAMediaFormatFields::set_string_id
jmethodID set_string_id
Definition: mediacodec_wrapper.c:107
mediaformat_ndk_delete
static int mediaformat_ndk_delete(FFAMediaFormat *ctx)
Definition: mediacodec_wrapper.c:1969
codec_create
static FFAMediaCodec * codec_create(int method, const char *arg)
Definition: mediacodec_wrapper.c:1179
FFAMediaFormatJni::object
jobject object
Definition: mediacodec_wrapper.c:147
FFAMediaCodecNdk::releaseOutputBuffer
media_status_t(* releaseOutputBuffer)(AMediaCodec *, size_t idx, bool render)
Definition: mediacodec_wrapper.c:1877
mediaformat_jni_setFloat
static void mediaformat_jni_setFloat(FFAMediaFormat *ctx, const char *name, float value)
Definition: mediacodec_wrapper.c:1011
mediacodec_ndk_configure
static int mediacodec_ndk_configure(FFAMediaCodec *ctx, const FFAMediaFormat *format_ctx, FFANativeWindow *window, void *crypto, uint32_t flags)
Definition: mediacodec_wrapper.c:2206