FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 <jni.h>
24 
25 #include "libavutil/avassert.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/avstring.h"
28 
29 #include "avcodec.h"
30 #include "ffjni.h"
31 #include "version.h"
32 #include "mediacodec_wrapper.h"
33 
35 
37  jmethodID init_id;
39 
40  jmethodID get_codec_count_id;
42 
44  jmethodID get_name_id;
47  jmethodID is_encoder_id;
48 
50  jfieldID color_formats_id;
52 
54  jfieldID profile_id;
55  jfieldID level_id;
56 
64 
68 
69 };
70 
71 static const struct FFJniField jni_amediacodeclist_mapping[] = {
72  { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_list_class), 1 },
73  { "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, init_id), 0 },
74  { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, find_decoder_for_format_id), 0 },
75 
76  { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_count_id), 1 },
77  { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_info_at_id), 1 },
78 
79  { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_info_class), 1 },
80  { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_name_id), 1 },
81  { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_capabilities_id), 1 },
82  { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_supported_types_id), 1 },
83  { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_encoder_id), 1 },
84 
85  { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_capabilities_class), 1 },
86  { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, color_formats_id), 1 },
87  { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_levels_id), 1 },
88 
89  { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_profile_level_class), 1 },
90  { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_id), 1 },
91  { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, level_id), 1 },
92 
93  { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileBaseline", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_baseline_id), 1 },
94  { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileMain", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_main_id), 1 },
95  { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileExtended", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_extended_id), 1 },
96  { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high_id), 1 },
97  { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high10_id), 1 },
98  { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh422", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high422_id), 1 },
99  { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh444", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high444_id), 1 },
100 
101  { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main_id), 0 },
102  { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main10_id), 0 },
103  { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain10HDR10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main10_hdr10_id), 0 },
104 
105  { NULL }
106 };
107 
109 
111 
112  jmethodID init_id;
113 
114  jmethodID get_integer_id;
115  jmethodID get_long_id;
116  jmethodID get_float_id;
117  jmethodID get_bytebuffer_id;
118  jmethodID get_string_id;
119 
120  jmethodID set_integer_id;
121  jmethodID set_long_id;
122  jmethodID set_float_id;
123  jmethodID set_bytebuffer_id;
124  jmethodID set_string_id;
125 
126  jmethodID to_string_id;
127 
128 };
129 
130 static const struct FFJniField jni_amediaformat_mapping[] = {
131  { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaFormatFields, mediaformat_class), 1 },
132 
133  { "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 },
134 
135  { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_integer_id), 1 },
136  { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_long_id), 1 },
137  { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_float_id), 1 },
138  { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_bytebuffer_id), 1 },
139  { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_string_id), 1 },
140 
141  { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_integer_id), 1 },
142  { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_long_id), 1 },
143  { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_float_id), 1 },
144  { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_bytebuffer_id), 1 },
145  { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_string_id), 1 },
146 
147  { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, to_string_id), 1 },
148 
149  { NULL }
150 };
151 
152 static const AVClass amediaformat_class = {
153  .class_name = "amediaformat",
154  .item_name = av_default_item_name,
155  .version = LIBAVCODEC_VERSION_INT,
156 };
157 
159 
160  const AVClass *class;
162  jobject object;
163 };
164 
166 
168 
172 
176 
178 
182 
183  jmethodID get_name_id;
184 
185  jmethodID configure_id;
186  jmethodID start_id;
187  jmethodID flush_id;
188  jmethodID stop_id;
189  jmethodID release_id;
190 
192 
197 
203 
205 
206  jmethodID init_id;
207 
208  jfieldID flags_id;
209  jfieldID offset_id;
211  jfieldID size_id;
212 
213 };
214 
215 static const struct FFJniField jni_amediacodec_mapping[] = {
216  { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediacodec_class), 1 },
217 
218  { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_try_again_later_id), 1 },
219  { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_buffers_changed_id), 1 },
220  { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_format_changed_id), 1 },
221 
222  { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_codec_config_id), 1 },
223  { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_end_of_stream_id), 1 },
224  { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_key_frame_id), 0 },
225 
226  { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, configure_flag_encode_id), 1 },
227 
228  { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_by_codec_name_id), 1 },
229  { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_decoder_by_type_id), 1 },
230  { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_encoder_by_type_id), 1 },
231 
232  { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_name_id), 1 },
233 
234  { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, configure_id), 1 },
235  { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, start_id), 1 },
236  { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, flush_id), 1 },
237  { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, stop_id), 1 },
238  { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_id), 1 },
239 
240  { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_format_id), 1 },
241 
242  { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_input_buffer_id), 1 },
243  { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, queue_input_buffer_id), 1 },
244  { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffer_id), 0 },
245  { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffers_id), 1 },
246 
247  { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_output_buffer_id), 1 },
248  { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffer_id), 0 },
249  { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffers_id), 1 },
250  { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_id), 1 },
251  { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_at_time_id), 0 },
252 
253  { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediainfo_class), 1 },
254 
255  { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, init_id), 1 },
256  { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, flags_id), 1 },
257  { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, offset_id), 1 },
258  { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, presentation_time_us_id), 1 },
259  { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, size_id), 1 },
260 
261  { NULL }
262 };
263 
264 static const AVClass amediacodec_class = {
265  .class_name = "amediacodec",
266  .item_name = av_default_item_name,
267  .version = LIBAVCODEC_VERSION_INT,
268 };
269 
271 
272  const AVClass *class;
273 
275 
276  jobject object;
277 
278  jobject input_buffers;
279  jobject output_buffers;
280 
284 
288 
290 
292 };
293 
294 #define JNI_GET_ENV_OR_RETURN(env, log_ctx, ret) do { \
295  (env) = ff_jni_get_env(log_ctx); \
296  if (!(env)) { \
297  return ret; \
298  } \
299 } while (0)
300 
301 #define JNI_GET_ENV_OR_RETURN_VOID(env, log_ctx) do { \
302  (env) = ff_jni_get_env(log_ctx); \
303  if (!(env)) { \
304  return; \
305  } \
306 } while (0)
307 
309 {
310  int ret = -1;
311 
312  JNIEnv *env = NULL;
313  struct JNIAMediaCodecListFields jfields = { 0 };
314  jfieldID field_id = 0;
315 
316  JNI_GET_ENV_OR_RETURN(env, avctx, -1);
317 
318  if (ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, avctx) < 0) {
319  goto done;
320  }
321 
322  if (avctx->codec_id == AV_CODEC_ID_H264) {
323  switch(avctx->profile) {
326  field_id = jfields.avc_profile_baseline_id;
327  break;
329  field_id = jfields.avc_profile_main_id;
330  break;
332  field_id = jfields.avc_profile_extended_id;
333  break;
335  field_id = jfields.avc_profile_high_id;
336  break;
339  field_id = jfields.avc_profile_high10_id;
340  break;
343  field_id = jfields.avc_profile_high422_id;
344  break;
348  field_id = jfields.avc_profile_high444_id;
349  break;
350  }
351  } else if (avctx->codec_id == AV_CODEC_ID_HEVC) {
352  switch (avctx->profile) {
355  field_id = jfields.hevc_profile_main_id;
356  break;
358  field_id = jfields.hevc_profile_main10_id;
359  break;
360  }
361  }
362 
363  if (field_id) {
364  ret = (*env)->GetStaticIntField(env, jfields.codec_profile_level_class, field_id);
365  if (ff_jni_exception_check(env, 1, avctx) < 0) {
366  ret = -1;
367  goto done;
368  }
369  }
370 
371 done:
372  ff_jni_reset_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, avctx);
373 
374  return ret;
375 }
376 
377 char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx)
378 {
379  int ret;
380  int i;
381  int codec_count;
382  int found_codec = 0;
383  char *name = NULL;
384  char *supported_type = NULL;
385 
386  JNIEnv *env = NULL;
387  struct JNIAMediaCodecListFields jfields = { 0 };
388  struct JNIAMediaFormatFields mediaformat_jfields = { 0 };
389 
390  jobject format = NULL;
391  jobject codec = NULL;
392  jobject codec_name = NULL;
393 
394  jobject info = NULL;
395  jobject type = NULL;
396  jobjectArray types = NULL;
397 
398  jobject capabilities = NULL;
399  jobject profile_level = NULL;
400  jobjectArray profile_levels = NULL;
401 
402  JNI_GET_ENV_OR_RETURN(env, log_ctx, NULL);
403 
404  if ((ret = ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx)) < 0) {
405  goto done;
406  }
407 
408  if ((ret = ff_jni_init_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx)) < 0) {
409  goto done;
410  }
411 
412  codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id);
413  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
414  goto done;
415  }
416 
417  for(i = 0; i < codec_count; i++) {
418  int j;
419  int type_count;
420  int is_encoder;
421 
422  info = (*env)->CallStaticObjectMethod(env, jfields.mediacodec_list_class, jfields.get_codec_info_at_id, i);
423  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
424  goto done;
425  }
426 
427  types = (*env)->CallObjectMethod(env, info, jfields.get_supported_types_id);
428  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
429  goto done;
430  }
431 
432  is_encoder = (*env)->CallBooleanMethod(env, info, jfields.is_encoder_id);
433  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
434  goto done;
435  }
436 
437  if (is_encoder != encoder) {
438  goto done_with_info;
439  }
440 
441  type_count = (*env)->GetArrayLength(env, types);
442  for (j = 0; j < type_count; j++) {
443  int k;
444  int profile_count;
445 
446  type = (*env)->GetObjectArrayElement(env, types, j);
447  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
448  goto done;
449  }
450 
451  supported_type = ff_jni_jstring_to_utf_chars(env, type, log_ctx);
452  if (!supported_type) {
453  goto done;
454  }
455 
456  if (!av_strcasecmp(supported_type, mime)) {
457  codec_name = (*env)->CallObjectMethod(env, info, jfields.get_name_id);
458  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
459  goto done;
460  }
461 
462  name = ff_jni_jstring_to_utf_chars(env, codec_name, log_ctx);
463  if (!name) {
464  goto done;
465  }
466 
467  if (strstr(name, "OMX.google")) {
468  av_freep(&name);
469  goto done_with_type;
470  }
471 
472  capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, type);
473  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
474  goto done;
475  }
476 
477  profile_levels = (*env)->GetObjectField(env, capabilities, jfields.profile_levels_id);
478  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
479  goto done;
480  }
481 
482  profile_count = (*env)->GetArrayLength(env, profile_levels);
483  if (!profile_count) {
484  found_codec = 1;
485  }
486  for (k = 0; k < profile_count; k++) {
487  int supported_profile = 0;
488 
489  if (profile < 0) {
490  found_codec = 1;
491  break;
492  }
493 
494  profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k);
495  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
496  goto done;
497  }
498 
499  supported_profile = (*env)->GetIntField(env, profile_level, jfields.profile_id);
500  if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
501  goto done;
502  }
503 
504  found_codec = profile == supported_profile;
505 
506  if (profile_level) {
507  (*env)->DeleteLocalRef(env, profile_level);
508  profile_level = NULL;
509  }
510 
511  if (found_codec) {
512  break;
513  }
514  }
515  }
516 
517 done_with_type:
518  if (profile_levels) {
519  (*env)->DeleteLocalRef(env, profile_levels);
520  profile_levels = NULL;
521  }
522 
523  if (capabilities) {
524  (*env)->DeleteLocalRef(env, capabilities);
525  capabilities = NULL;
526  }
527 
528  if (type) {
529  (*env)->DeleteLocalRef(env, type);
530  type = NULL;
531  }
532 
533  av_freep(&supported_type);
534 
535  if (found_codec) {
536  break;
537  }
538 
539  av_freep(&name);
540  }
541 
542 done_with_info:
543  if (info) {
544  (*env)->DeleteLocalRef(env, info);
545  info = NULL;
546  }
547 
548  if (types) {
549  (*env)->DeleteLocalRef(env, types);
550  types = NULL;
551  }
552 
553  if (found_codec) {
554  break;
555  }
556  }
557 
558 done:
559  if (format) {
560  (*env)->DeleteLocalRef(env, format);
561  }
562 
563  if (codec) {
564  (*env)->DeleteLocalRef(env, codec);
565  }
566 
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(FFAMediaFormat));
614  if (!format) {
615  return NULL;
616  }
617  format->class = &amediaformat_class;
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) {
645  ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
646  av_freep(&format);
647  }
648 
649  return format;
650 }
651 
653 {
654  JNIEnv *env = NULL;
656 
657  format = av_mallocz(sizeof(FFAMediaFormat));
658  if (!format) {
659  return NULL;
660  }
661  format->class = &amediaformat_class;
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 format;
679 fail:
680  ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
681 
682  av_freep(&format);
683 
684  return NULL;
685 }
686 
688 {
689  int ret = 0;
690 
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 
702  ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
703 
704  av_freep(&format);
705 
706  return ret;
707 }
708 
710 {
711  char *ret = NULL;
712 
713  JNIEnv *env = NULL;
714  jstring description = NULL;
715 
716  av_assert0(format != NULL);
717 
718  JNI_GET_ENV_OR_RETURN(env, format, NULL);
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 
725  ret = ff_jni_jstring_to_utf_chars(env, description, format);
726 fail:
727  if (description) {
728  (*env)->DeleteLocalRef(env, description);
729  }
730 
731  return ret;
732 }
733 
735 {
736  int ret = 1;
737 
738  JNIEnv *env = NULL;
739  jstring key = NULL;
740 
741  av_assert0(format != NULL);
742 
743  JNI_GET_ENV_OR_RETURN(env, format, 0);
744 
745  key = ff_jni_utf_chars_to_jstring(env, name, format);
746  if (!key) {
747  ret = 0;
748  goto fail;
749  }
750 
751  *out = (*env)->CallIntMethod(env, format->object, format->jfields.get_integer_id, key);
752  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
753  ret = 0;
754  goto fail;
755  }
756 
757  ret = 1;
758 fail:
759  if (key) {
760  (*env)->DeleteLocalRef(env, key);
761  }
762 
763  return ret;
764 }
765 
767 {
768  int ret = 1;
769 
770  JNIEnv *env = NULL;
771  jstring key = NULL;
772 
773  av_assert0(format != NULL);
774 
775  JNI_GET_ENV_OR_RETURN(env, format, 0);
776 
777  key = ff_jni_utf_chars_to_jstring(env, name, format);
778  if (!key) {
779  ret = 0;
780  goto fail;
781  }
782 
783  *out = (*env)->CallLongMethod(env, format->object, format->jfields.get_long_id, key);
784  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
785  ret = 0;
786  goto fail;
787  }
788 
789  ret = 1;
790 fail:
791  if (key) {
792  (*env)->DeleteLocalRef(env, key);
793  }
794 
795  return ret;
796 }
797 
799 {
800  int ret = 1;
801 
802  JNIEnv *env = NULL;
803  jstring key = NULL;
804 
805  av_assert0(format != NULL);
806 
807  JNI_GET_ENV_OR_RETURN(env, format, 0);
808 
809  key = ff_jni_utf_chars_to_jstring(env, name, format);
810  if (!key) {
811  ret = 0;
812  goto fail;
813  }
814 
815  *out = (*env)->CallFloatMethod(env, format->object, format->jfields.get_float_id, key);
816  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
817  ret = 0;
818  goto fail;
819  }
820 
821  ret = 1;
822 fail:
823  if (key) {
824  (*env)->DeleteLocalRef(env, key);
825  }
826 
827  return ret;
828 }
829 
830 int ff_AMediaFormat_getBuffer(FFAMediaFormat* format, const char *name, void** data, size_t *size)
831 {
832  int ret = 1;
833 
834  JNIEnv *env = NULL;
835  jstring key = NULL;
836  jobject result = NULL;
837 
838  av_assert0(format != NULL);
839 
840  JNI_GET_ENV_OR_RETURN(env, format, 0);
841 
842  key = ff_jni_utf_chars_to_jstring(env, name, format);
843  if (!key) {
844  ret = 0;
845  goto fail;
846  }
847 
848  result = (*env)->CallObjectMethod(env, format->object, format->jfields.get_bytebuffer_id, key);
849  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
850  ret = 0;
851  goto fail;
852  }
853 
854  *data = (*env)->GetDirectBufferAddress(env, result);
855  *size = (*env)->GetDirectBufferCapacity(env, result);
856 
857  if (*data && *size) {
858  void *src = *data;
859  *data = av_malloc(*size);
860  if (!*data) {
861  ret = 0;
862  goto fail;
863  }
864 
865  memcpy(*data, src, *size);
866  }
867 
868  ret = 1;
869 fail:
870  if (key) {
871  (*env)->DeleteLocalRef(env, key);
872  }
873 
874  if (result) {
875  (*env)->DeleteLocalRef(env, result);
876  }
877 
878  return ret;
879 }
880 
881 int ff_AMediaFormat_getString(FFAMediaFormat* format, const char *name, const char **out)
882 {
883  int ret = 1;
884 
885  JNIEnv *env = NULL;
886  jstring key = NULL;
887  jstring result = NULL;
888 
889  av_assert0(format != NULL);
890 
891  JNI_GET_ENV_OR_RETURN(env, format, 0);
892 
893  key = ff_jni_utf_chars_to_jstring(env, name, format);
894  if (!key) {
895  ret = 0;
896  goto fail;
897  }
898 
899  result = (*env)->CallObjectMethod(env, format->object, format->jfields.get_string_id, key);
900  if ((ret = ff_jni_exception_check(env, 1, format)) < 0) {
901  ret = 0;
902  goto fail;
903  }
904 
905  *out = ff_jni_jstring_to_utf_chars(env, result, format);
906  if (!*out) {
907  ret = 0;
908  goto fail;
909  }
910 
911  ret = 1;
912 fail:
913  if (key) {
914  (*env)->DeleteLocalRef(env, key);
915  }
916 
917  if (result) {
918  (*env)->DeleteLocalRef(env, result);
919  }
920 
921  return ret;
922 }
923 
925 {
926  JNIEnv *env = NULL;
927  jstring key = NULL;
928 
929  av_assert0(format != NULL);
930 
931  JNI_GET_ENV_OR_RETURN_VOID(env, format);
932 
933  key = ff_jni_utf_chars_to_jstring(env, name, format);
934  if (!key) {
935  goto fail;
936  }
937 
938  (*env)->CallVoidMethod(env, format->object, format->jfields.set_integer_id, key, value);
939  if (ff_jni_exception_check(env, 1, format) < 0) {
940  goto fail;
941  }
942 
943 fail:
944  if (key) {
945  (*env)->DeleteLocalRef(env, key);
946  }
947 }
948 
950 {
951  JNIEnv *env = NULL;
952  jstring key = NULL;
953 
954  av_assert0(format != NULL);
955 
956  JNI_GET_ENV_OR_RETURN_VOID(env, format);
957 
958  key = ff_jni_utf_chars_to_jstring(env, name, format);
959  if (!key) {
960  goto fail;
961  }
962 
963  (*env)->CallVoidMethod(env, format->object, format->jfields.set_long_id, key, value);
964  if (ff_jni_exception_check(env, 1, format) < 0) {
965  goto fail;
966  }
967 
968 fail:
969  if (key) {
970  (*env)->DeleteLocalRef(env, key);
971  }
972 }
973 
975 {
976  JNIEnv *env = NULL;
977  jstring key = NULL;
978 
979  av_assert0(format != NULL);
980 
981  JNI_GET_ENV_OR_RETURN_VOID(env, format);
982 
983  key = ff_jni_utf_chars_to_jstring(env, name, format);
984  if (!key) {
985  goto fail;
986  }
987 
988  (*env)->CallVoidMethod(env, format->object, format->jfields.set_float_id, key, value);
989  if (ff_jni_exception_check(env, 1, format) < 0) {
990  goto fail;
991  }
992 
993 fail:
994  if (key) {
995  (*env)->DeleteLocalRef(env, key);
996  }
997 }
998 
999 void ff_AMediaFormat_setString(FFAMediaFormat* format, const char* name, const char* value)
1000 {
1001  JNIEnv *env = NULL;
1002  jstring key = NULL;
1003  jstring string = NULL;
1004 
1005  av_assert0(format != NULL);
1006 
1007  JNI_GET_ENV_OR_RETURN_VOID(env, format);
1008 
1009  key = ff_jni_utf_chars_to_jstring(env, name, format);
1010  if (!key) {
1011  goto fail;
1012  }
1013 
1014  string = ff_jni_utf_chars_to_jstring(env, value, format);
1015  if (!string) {
1016  goto fail;
1017  }
1018 
1019  (*env)->CallVoidMethod(env, format->object, format->jfields.set_string_id, key, string);
1020  if (ff_jni_exception_check(env, 1, format) < 0) {
1021  goto fail;
1022  }
1023 
1024 fail:
1025  if (key) {
1026  (*env)->DeleteLocalRef(env, key);
1027  }
1028 
1029  if (string) {
1030  (*env)->DeleteLocalRef(env, string);
1031  }
1032 }
1033 
1034 void ff_AMediaFormat_setBuffer(FFAMediaFormat* format, const char* name, void* data, size_t size)
1035 {
1036  JNIEnv *env = NULL;
1037  jstring key = NULL;
1038  jobject buffer = NULL;
1039  void *buffer_data = NULL;
1040 
1041  av_assert0(format != NULL);
1042 
1043  JNI_GET_ENV_OR_RETURN_VOID(env, format);
1044 
1045  key = ff_jni_utf_chars_to_jstring(env, name, format);
1046  if (!key) {
1047  goto fail;
1048  }
1049 
1050  if (!data || !size) {
1051  goto fail;
1052  }
1053 
1054  buffer_data = av_malloc(size);
1055  if (!buffer_data) {
1056  goto fail;
1057  }
1058 
1059  memcpy(buffer_data, data, size);
1060 
1061  buffer = (*env)->NewDirectByteBuffer(env, buffer_data, size);
1062  if (!buffer) {
1063  goto fail;
1064  }
1065 
1066  (*env)->CallVoidMethod(env, format->object, format->jfields.set_bytebuffer_id, key, buffer);
1067  if (ff_jni_exception_check(env, 1, format) < 0) {
1068  goto fail;
1069  }
1070 
1071 fail:
1072  if (key) {
1073  (*env)->DeleteLocalRef(env, key);
1074  }
1075 
1076  if (buffer) {
1077  (*env)->DeleteLocalRef(env, buffer);
1078  }
1079 }
1080 
1082 {
1083  int ret = 0;
1084  JNIEnv *env = NULL;
1085 
1087 
1088  codec->INFO_TRY_AGAIN_LATER = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_try_again_later_id);
1089  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1090  goto fail;
1091  }
1092 
1093  codec->BUFFER_FLAG_CODEC_CONFIG = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_codec_config_id);
1094  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1095  goto fail;
1096  }
1097 
1098  codec->BUFFER_FLAG_END_OF_STREAM = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_end_of_stream_id);
1099  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1100  goto fail;
1101  }
1102 
1103  if (codec->jfields.buffer_flag_key_frame_id) {
1104  codec->BUFFER_FLAG_KEY_FRAME = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_key_frame_id);
1105  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1106  goto fail;
1107  }
1108  }
1109 
1110  codec->CONFIGURE_FLAG_ENCODE = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.configure_flag_encode_id);
1111  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1112  goto fail;
1113  }
1114 
1115  codec->INFO_TRY_AGAIN_LATER = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_try_again_later_id);
1116  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1117  goto fail;
1118  }
1119 
1120  codec->INFO_OUTPUT_BUFFERS_CHANGED = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_output_buffers_changed_id);
1121  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1122  goto fail;
1123  }
1124 
1125  codec->INFO_OUTPUT_FORMAT_CHANGED = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_output_format_changed_id);
1126  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1127  goto fail;
1128  }
1129 
1130 fail:
1131 
1132  return ret;
1133 }
1134 
1136 {
1137  int ret = -1;
1138  JNIEnv *env = NULL;
1139  FFAMediaCodec *codec = NULL;
1140  jstring codec_name = NULL;
1141  jobject object = NULL;
1142 
1143  codec = av_mallocz(sizeof(FFAMediaCodec));
1144  if (!codec) {
1145  return NULL;
1146  }
1147  codec->class = &amediacodec_class;
1148 
1149  env = ff_jni_get_env(codec);
1150  if (!env) {
1151  av_freep(&codec);
1152  return NULL;
1153  }
1154 
1155  if (ff_jni_init_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec) < 0) {
1156  goto fail;
1157  }
1158 
1159  codec_name = ff_jni_utf_chars_to_jstring(env, name, codec);
1160  if (!codec_name) {
1161  goto fail;
1162  }
1163 
1164  object = (*env)->CallStaticObjectMethod(env, codec->jfields.mediacodec_class, codec->jfields.create_by_codec_name_id, codec_name);
1165  if (ff_jni_exception_check(env, 1, codec) < 0) {
1166  goto fail;
1167  }
1168 
1169  codec->object = (*env)->NewGlobalRef(env, object);
1170  if (!codec->object) {
1171  goto fail;
1172  }
1173 
1174  if (codec_init_static_fields(codec) < 0) {
1175  goto fail;
1176  }
1177 
1179  codec->has_get_i_o_buffer = 1;
1180  }
1181 
1182  ret = 0;
1183 fail:
1184  if (codec_name) {
1185  (*env)->DeleteLocalRef(env, codec_name);
1186  }
1187 
1188  if (object) {
1189  (*env)->DeleteLocalRef(env, object);
1190  }
1191 
1192  if (ret < 0) {
1193  ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
1194  av_freep(&codec);
1195  }
1196 
1197  return codec;
1198 }
1199 
1201 {
1202  int ret = -1;
1203  JNIEnv *env = NULL;
1204  FFAMediaCodec *codec = NULL;
1205  jstring mime_type = NULL;
1206  jobject object = NULL;
1207 
1208  codec = av_mallocz(sizeof(FFAMediaCodec));
1209  if (!codec) {
1210  return NULL;
1211  }
1212  codec->class = &amediacodec_class;
1213 
1214  env = ff_jni_get_env(codec);
1215  if (!env) {
1216  av_freep(&codec);
1217  return NULL;
1218  }
1219 
1220  if (ff_jni_init_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec) < 0) {
1221  goto fail;
1222  }
1223 
1224  mime_type = ff_jni_utf_chars_to_jstring(env, mime, codec);
1225  if (!mime_type) {
1226  goto fail;
1227  }
1228 
1229  object = (*env)->CallStaticObjectMethod(env, codec->jfields.mediacodec_class, codec->jfields.create_decoder_by_type_id, mime_type);
1230  if (ff_jni_exception_check(env, 1, codec) < 0) {
1231  goto fail;
1232  }
1233 
1234  codec->object = (*env)->NewGlobalRef(env, object);
1235  if (!codec->object) {
1236  goto fail;
1237  }
1238 
1239  if (codec_init_static_fields(codec) < 0) {
1240  goto fail;
1241  }
1242 
1244  codec->has_get_i_o_buffer = 1;
1245  }
1246 
1247  ret = 0;
1248 fail:
1249  if (mime_type) {
1250  (*env)->DeleteLocalRef(env, mime_type);
1251  }
1252 
1253  if (object) {
1254  (*env)->DeleteLocalRef(env, object);
1255  }
1256 
1257  if (ret < 0) {
1258  ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
1259  av_freep(&codec);
1260  }
1261 
1262  return codec;
1263 }
1264 
1266 {
1267  int ret = -1;
1268  JNIEnv *env = NULL;
1269  FFAMediaCodec *codec = NULL;
1270  jstring mime_type = NULL;
1271  jobject object = NULL;
1272 
1273  codec = av_mallocz(sizeof(FFAMediaCodec));
1274  if (!codec) {
1275  return NULL;
1276  }
1277  codec->class = &amediacodec_class;
1278 
1279  env = ff_jni_get_env(codec);
1280  if (!env) {
1281  av_freep(&codec);
1282  return NULL;
1283  }
1284 
1285  if (ff_jni_init_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec) < 0) {
1286  goto fail;
1287  }
1288 
1289  mime_type = ff_jni_utf_chars_to_jstring(env, mime, codec);
1290  if (!mime_type) {
1291  goto fail;
1292  }
1293 
1294  object = (*env)->CallStaticObjectMethod(env, codec->jfields.mediacodec_class, codec->jfields.create_encoder_by_type_id, mime_type);
1295  if (ff_jni_exception_check(env, 1, codec) < 0) {
1296  goto fail;
1297  }
1298 
1299  codec->object = (*env)->NewGlobalRef(env, object);
1300  if (!codec->object) {
1301  goto fail;
1302  }
1303 
1304  if (codec_init_static_fields(codec) < 0) {
1305  goto fail;
1306  }
1307 
1309  codec->has_get_i_o_buffer = 1;
1310  }
1311 
1312  ret = 0;
1313 fail:
1314  if (mime_type) {
1315  (*env)->DeleteLocalRef(env, mime_type);
1316  }
1317 
1318  if (object) {
1319  (*env)->DeleteLocalRef(env, object);
1320  }
1321 
1322  if (ret < 0) {
1323  ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
1324  av_freep(&codec);
1325  }
1326 
1327  return codec;
1328 }
1329 
1331 {
1332  int ret = 0;
1333 
1334  JNIEnv *env = NULL;
1335 
1336  if (!codec) {
1337  return 0;
1338  }
1339 
1341 
1342  (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_id);
1343  if (ff_jni_exception_check(env, 1, codec) < 0) {
1344  ret = AVERROR_EXTERNAL;
1345  }
1346 
1347  (*env)->DeleteGlobalRef(env, codec->object);
1348  codec->object = NULL;
1349 
1350  ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
1351 
1352  av_freep(&codec);
1353 
1354  return ret;
1355 }
1356 
1358 {
1359  char *ret = NULL;
1360  JNIEnv *env = NULL;
1361  jobject *name = NULL;
1362 
1363  JNI_GET_ENV_OR_RETURN(env, codec, NULL);
1364 
1365  name = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_name_id);
1366  if (ff_jni_exception_check(env, 1, codec) < 0) {
1367  goto fail;
1368  }
1369 
1370  ret = ff_jni_jstring_to_utf_chars(env, name, codec);
1371 
1372 fail:
1373  return ret;
1374 }
1375 
1376 int ff_AMediaCodec_configure(FFAMediaCodec* codec, const FFAMediaFormat* format, void* surface, void *crypto, uint32_t flags)
1377 {
1378  int ret = 0;
1379  JNIEnv *env = NULL;
1380 
1382 
1383  (*env)->CallVoidMethod(env, codec->object, codec->jfields.configure_id, format->object, surface, NULL, flags);
1384  if (ff_jni_exception_check(env, 1, codec) < 0) {
1385  ret = AVERROR_EXTERNAL;
1386  goto fail;
1387  }
1388 
1389 fail:
1390  return ret;
1391 }
1392 
1394 {
1395  int ret = 0;
1396  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) {
1402  ret = AVERROR_EXTERNAL;
1403  goto fail;
1404  }
1405 
1406 fail:
1407  return ret;
1408 }
1409 
1411 {
1412  int ret = 0;
1413  JNIEnv *env = NULL;
1414 
1416 
1417  (*env)->CallVoidMethod(env, codec->object, codec->jfields.stop_id);
1418  if (ff_jni_exception_check(env, 1, codec) < 0) {
1419  ret = AVERROR_EXTERNAL;
1420  goto fail;
1421  }
1422 
1423 fail:
1424  return ret;
1425 }
1426 
1428 {
1429  int ret = 0;
1430  JNIEnv *env = NULL;
1431 
1433 
1434  (*env)->CallVoidMethod(env, codec->object, codec->jfields.flush_id);
1435  if (ff_jni_exception_check(env, 1, codec) < 0) {
1436  ret = AVERROR_EXTERNAL;
1437  goto fail;
1438  }
1439 
1440 fail:
1441  return ret;
1442 }
1443 
1444 int ff_AMediaCodec_releaseOutputBuffer(FFAMediaCodec* codec, size_t idx, int render)
1445 {
1446  int ret = 0;
1447  JNIEnv *env = NULL;
1448 
1450 
1451  (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_id, (jint)idx, (jboolean)render);
1452  if (ff_jni_exception_check(env, 1, codec) < 0) {
1453  ret = AVERROR_EXTERNAL;
1454  goto fail;
1455  }
1456 
1457 fail:
1458  return ret;
1459 }
1460 
1461 int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, int64_t timestampNs)
1462 {
1463  int ret = 0;
1464  JNIEnv *env = NULL;
1465 
1467 
1468  (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, timestampNs);
1469  if (ff_jni_exception_check(env, 1, codec) < 0) {
1470  ret = AVERROR_EXTERNAL;
1471  goto fail;
1472  }
1473 
1474 fail:
1475  return ret;
1476 }
1477 
1478 ssize_t ff_AMediaCodec_dequeueInputBuffer(FFAMediaCodec* codec, int64_t timeoutUs)
1479 {
1480  int ret = 0;
1481  JNIEnv *env = NULL;
1482 
1484 
1485  ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_input_buffer_id, timeoutUs);
1486  if (ff_jni_exception_check(env, 1, codec) < 0) {
1487  ret = AVERROR_EXTERNAL;
1488  goto fail;
1489  }
1490 
1491 fail:
1492  return ret;
1493 }
1494 
1495 int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec* codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
1496 {
1497  int ret = 0;
1498  JNIEnv *env = NULL;
1499 
1501 
1502  (*env)->CallVoidMethod(env, codec->object, codec->jfields.queue_input_buffer_id, (jint)idx, (jint)offset, (jint)size, time, flags);
1503  if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) {
1504  ret = AVERROR_EXTERNAL;
1505  goto fail;
1506  }
1507 
1508 fail:
1509  return ret;
1510 }
1511 
1513 {
1514  int ret = 0;
1515  JNIEnv *env = NULL;
1516 
1517  jobject mediainfo = NULL;
1518 
1520 
1521  mediainfo = (*env)->NewObject(env, codec->jfields.mediainfo_class, codec->jfields.init_id);
1522  if (ff_jni_exception_check(env, 1, codec) < 0) {
1523  ret = AVERROR_EXTERNAL;
1524  goto fail;
1525  }
1526 
1527  ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_output_buffer_id, mediainfo, timeoutUs);
1528  if (ff_jni_exception_check(env, 1, codec) < 0) {
1529  ret = AVERROR_EXTERNAL;
1530  goto fail;
1531  }
1532 
1533  info->flags = (*env)->GetIntField(env, mediainfo, codec->jfields.flags_id);
1534  if (ff_jni_exception_check(env, 1, codec) < 0) {
1535  ret = AVERROR_EXTERNAL;
1536  goto fail;
1537  }
1538 
1539  info->offset = (*env)->GetIntField(env, mediainfo, codec->jfields.offset_id);
1540  if (ff_jni_exception_check(env, 1, codec) < 0) {
1541  ret = AVERROR_EXTERNAL;
1542  goto fail;
1543  }
1544 
1545  info->presentationTimeUs = (*env)->GetLongField(env, mediainfo, codec->jfields.presentation_time_us_id);
1546  if (ff_jni_exception_check(env, 1, codec) < 0) {
1547  ret = AVERROR_EXTERNAL;
1548  goto fail;
1549  }
1550 
1551  info->size = (*env)->GetIntField(env, mediainfo, codec->jfields.size_id);
1552  if (ff_jni_exception_check(env, 1, codec) < 0) {
1553  ret = AVERROR_EXTERNAL;
1554  goto fail;
1555  }
1556 fail:
1557  if (mediainfo) {
1558  (*env)->DeleteLocalRef(env, mediainfo);
1559  }
1560 
1561  return ret;
1562 }
1563 
1565 {
1566  uint8_t *ret = NULL;
1567  JNIEnv *env = NULL;
1568 
1569  jobject buffer = NULL;
1570  jobject input_buffers = NULL;
1571 
1572  JNI_GET_ENV_OR_RETURN(env, codec, NULL);
1573 
1574  if (codec->has_get_i_o_buffer) {
1575  buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffer_id, (jint)idx);
1576  if (ff_jni_exception_check(env, 1, codec) < 0) {
1577  goto fail;
1578  }
1579  } else {
1580  if (!codec->input_buffers) {
1581  input_buffers = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffers_id);
1582  if (ff_jni_exception_check(env, 1, codec) < 0) {
1583  goto fail;
1584  }
1585 
1586  codec->input_buffers = (*env)->NewGlobalRef(env, input_buffers);
1587  if (ff_jni_exception_check(env, 1, codec) < 0) {
1588  goto fail;
1589  }
1590  }
1591 
1592  buffer = (*env)->GetObjectArrayElement(env, codec->input_buffers, idx);
1593  if (ff_jni_exception_check(env, 1, codec) < 0) {
1594  goto fail;
1595  }
1596  }
1597 
1598  ret = (*env)->GetDirectBufferAddress(env, buffer);
1599  *out_size = (*env)->GetDirectBufferCapacity(env, buffer);
1600 fail:
1601  if (buffer) {
1602  (*env)->DeleteLocalRef(env, buffer);
1603  }
1604 
1605  if (input_buffers) {
1606  (*env)->DeleteLocalRef(env, input_buffers);
1607  }
1608 
1609  return ret;
1610 }
1611 
1613 {
1614  uint8_t *ret = NULL;
1615  JNIEnv *env = NULL;
1616 
1617  jobject buffer = NULL;
1618  jobject output_buffers = NULL;
1619 
1620  JNI_GET_ENV_OR_RETURN(env, codec, NULL);
1621 
1622  if (codec->has_get_i_o_buffer) {
1623  buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffer_id, (jint)idx);
1624  if (ff_jni_exception_check(env, 1, codec) < 0) {
1625  goto fail;
1626  }
1627  } else {
1628  if (!codec->output_buffers) {
1629  output_buffers = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffers_id);
1630  if (ff_jni_exception_check(env, 1, codec) < 0) {
1631  goto fail;
1632  }
1633 
1634  codec->output_buffers = (*env)->NewGlobalRef(env, output_buffers);
1635  if (ff_jni_exception_check(env, 1, codec) < 0) {
1636  goto fail;
1637  }
1638  }
1639 
1640  buffer = (*env)->GetObjectArrayElement(env, codec->output_buffers, idx);
1641  if (ff_jni_exception_check(env, 1, codec) < 0) {
1642  goto fail;
1643  }
1644  }
1645 
1646  ret = (*env)->GetDirectBufferAddress(env, buffer);
1647  *out_size = (*env)->GetDirectBufferCapacity(env, buffer);
1648 fail:
1649  if (buffer) {
1650  (*env)->DeleteLocalRef(env, buffer);
1651  }
1652 
1653  if (output_buffers) {
1654  (*env)->DeleteLocalRef(env, output_buffers);
1655  }
1656 
1657  return ret;
1658 }
1659 
1661 {
1662  FFAMediaFormat *ret = NULL;
1663  JNIEnv *env = NULL;
1664 
1665  jobject mediaformat = NULL;
1666 
1667  JNI_GET_ENV_OR_RETURN(env, codec, NULL);
1668 
1669  mediaformat = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_format_id);
1670  if (ff_jni_exception_check(env, 1, codec) < 0) {
1671  goto fail;
1672  }
1673 
1674  ret = ff_AMediaFormat_newFromObject(mediaformat);
1675 fail:
1676  if (mediaformat) {
1677  (*env)->DeleteLocalRef(env, mediaformat);
1678  }
1679 
1680  return ret;
1681 }
1682 
1684 {
1685  return idx == codec->INFO_TRY_AGAIN_LATER;
1686 }
1687 
1689 {
1690  return idx == codec->INFO_OUTPUT_BUFFERS_CHANGED;
1691 }
1692 
1694 {
1695  return idx == codec->INFO_OUTPUT_FORMAT_CHANGED;
1696 }
1697 
1699 {
1700  return codec->BUFFER_FLAG_CODEC_CONFIG;
1701 }
1702 
1704 {
1705  return codec->BUFFER_FLAG_END_OF_STREAM;
1706 }
1707 
1709 {
1710  return codec->BUFFER_FLAG_KEY_FRAME;
1711 }
1712 
1714 {
1715  return codec->CONFIGURE_FLAG_ENCODE;
1716 }
1717 
1719 {
1720  int ret = 0;
1721 
1722  if (!codec->has_get_i_o_buffer) {
1723  if (codec->output_buffers) {
1724  JNIEnv *env = NULL;
1725 
1726  env = ff_jni_get_env(codec);
1727  if (!env) {
1728  ret = AVERROR_EXTERNAL;
1729  goto fail;
1730  }
1731 
1732  (*env)->DeleteGlobalRef(env, codec->output_buffers);
1733  codec->output_buffers = NULL;
1734  }
1735  }
1736 
1737 fail:
1738  return ret;
1739 }
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:3307
#define NULL
Definition: coverity.c:32
const AVClass * class
int ff_AMediaFormat_getBuffer(FFAMediaFormat *format, const char *name, void **data, size_t *size)
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
int ff_jni_reset_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
Definition: ffjni.c:374
char * ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx)
Memory handling functions.
FFAMediaCodec * ff_AMediaCodec_createCodecByName(const char *name)
void ff_AMediaFormat_setBuffer(FFAMediaFormat *format, const char *name, void *data, size_t size)
static FFAMediaFormat * ff_AMediaFormat_newFromObject(void *object)
struct JNIAMediaFormatFields jfields
int out_size
Definition: movenc.c:55
jstring ff_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, void *log_ctx)
Definition: ffjni.c:127
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:222
static const struct FFJniField jni_amediacodeclist_mapping[]
#define src
Definition: vp8dsp.c:254
int profile
profile
Definition: avcodec.h:3266
static const struct FFJniField jni_amediacodec_mapping[]
static const AVClass amediacodec_class
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: avcodec.h:3317
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:72
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_AMediaCodec_flush(FFAMediaCodec *codec)
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:3305
int ff_AMediaCodec_releaseOutputBuffer(FFAMediaCodec *codec, size_t idx, int render)
uint8_t
#define av_malloc(s)
FFAMediaFormat * ff_AMediaFormat_new(void)
int ff_AMediaCodec_infoOutputBuffersChanged(FFAMediaCodec *codec, ssize_t idx)
#define FF_PROFILE_HEVC_MAIN
Definition: avcodec.h:3354
#define LIBAVCODEC_VERSION_INT
Definition: version.h:34
int ff_AMediaCodec_infoOutputFormatChanged(FFAMediaCodec *codec, ssize_t idx)
FFAMediaCodec * ff_AMediaCodec_createEncoderByType(const char *mime)
static int flags
Definition: log.c:57
#define FF_PROFILE_H264_EXTENDED
Definition: avcodec.h:3308
char * ff_AMediaFormat_toString(FFAMediaFormat *format)
ptrdiff_t size
Definition: opengl_enc.c:101
#define FF_PROFILE_HEVC_MAIN_10
Definition: avcodec.h:3355
int ff_AMediaFormat_getFloat(FFAMediaFormat *format, const char *name, float *out)
Libavcodec version macros.
static const struct FFJniField jni_amediaformat_mapping[]
char * ff_AMediaCodec_getName(FFAMediaCodec *codec)
av_default_item_name
jfieldID info_output_format_changed_id
uint8_t * ff_AMediaCodec_getInputBuffer(FFAMediaCodec *codec, size_t idx, size_t *out_size)
#define FF_PROFILE_H264_HIGH_422
Definition: avcodec.h:3313
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:3309
#define JNI_GET_ENV_OR_RETURN_VOID(env, log_ctx)
simple assert() macros that are a bit more flexible than ISO C assert().
static const uint8_t offset[127][2]
Definition: vf_spp.c:92
#define fail()
Definition: checkasm.h:109
int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec *codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
ssize_t ff_AMediaCodec_dequeueOutputBuffer(FFAMediaCodec *codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs)
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:213
void ff_AMediaFormat_setInt32(FFAMediaFormat *format, const char *name, int32_t value)
char * ff_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx)
Definition: ffjni.c:97
int ff_AMediaCodec_delete(FFAMediaCodec *codec)
int ff_AMediaFormat_getString(FFAMediaFormat *format, const char *name, const char **out)
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:109
#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE
Definition: avcodec.h:3356
int32_t
void ff_AMediaFormat_setInt64(FFAMediaFormat *format, const char *name, int64_t value)
int ff_AMediaCodec_getBufferFlagEndOfStream(FFAMediaCodec *codec)
int ff_jni_init_jfields(JNIEnv *env, void *jfields, const struct FFJniField *jfields_mapping, int global, void *log_ctx)
Definition: ffjni.c:285
void ff_AMediaFormat_setFloat(FFAMediaFormat *format, const char *name, float value)
int ff_jni_exception_check(JNIEnv *env, int log, void *log_ctx)
Definition: ffjni.c:252
int ff_AMediaCodec_getBufferFlagKeyFrame(FFAMediaCodec *codec)
void ff_AMediaFormat_setString(FFAMediaFormat *format, const char *name, const char *value)
ssize_t ff_AMediaCodec_dequeueInputBuffer(FFAMediaCodec *codec, int64_t timeoutUs)
int ff_AMediaFormat_getInt32(FFAMediaFormat *format, const char *name, int32_t *out)
struct JNIAMediaCodecFields jfields
int ff_AMediaCodec_cleanOutputBuffers(FFAMediaCodec *codec)
int ff_AMediaCodec_start(FFAMediaCodec *codec)
Libavcodec external API header.
int ff_AMediaCodec_getBufferFlagCodecConfig(FFAMediaCodec *codec)
#define FF_PROFILE_H264_HIGH_422_INTRA
Definition: avcodec.h:3314
enum AVCodecID codec_id
Definition: avcodec.h:1778
main external API structure.
Definition: avcodec.h:1761
int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx)
The following API around MediaCodec and MediaFormat is based on the NDK one provided by Google since ...
GLint GLenum type
Definition: opengl_enc.c:105
#define FF_PROFILE_H264_HIGH_10_INTRA
Definition: avcodec.h:3311
static const char * format
Definition: movenc.c:47
Describe the class of an AVClass context structure.
Definition: log.h:67
#define FF_PROFILE_H264_HIGH_444
Definition: avcodec.h:3316
jfieldID info_output_buffers_changed_id
int ff_AMediaCodec_stop(FFAMediaCodec *codec)
int ff_AMediaCodec_infoTryAgainLater(FFAMediaCodec *codec, ssize_t idx)
int ff_AMediaFormat_delete(FFAMediaFormat *format)
mfxU16 profile
Definition: qsvenc.c:44
jmethodID release_output_buffer_at_time_id
uint8_t * ff_AMediaCodec_getOutputBuffer(FFAMediaCodec *codec, size_t idx, size_t *out_size)
int ff_AMediaCodec_configure(FFAMediaCodec *codec, const FFAMediaFormat *format, void *surface, void *crypto, uint32_t flags)
JNIEnv * ff_jni_get_env(void *log_ctx)
Definition: ffjni.c:51
static const AVClass amediaformat_class
const AVClass * class
#define JNI_GET_ENV_OR_RETURN(env, log_ctx, ret)
int ff_AMediaCodec_getConfigureFlagEncode(FFAMediaCodec *codec)
static int codec_init_static_fields(FFAMediaCodec *codec)
FFAMediaFormat * ff_AMediaCodec_getOutputFormat(FFAMediaCodec *codec)
#define FF_PROFILE_H264_HIGH_444_INTRA
Definition: avcodec.h:3318
FILE * out
Definition: movenc.c:54
int ff_AMediaFormat_getInt64(FFAMediaFormat *format, const char *name, int64_t *out)
#define av_freep(p)
FFAMediaCodec * ff_AMediaCodec_createDecoderByType(const char *mime)
#define FF_PROFILE_H264_CONSTRAINED_BASELINE
Definition: avcodec.h:3306
#define FF_PROFILE_H264_HIGH_10
Definition: avcodec.h:3310
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, int64_t timestampNs)
GLuint buffer
Definition: opengl_enc.c:102
const char * name
Definition: opengl_enc.c:103