@@ -3191,6 +3191,7 @@ h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
h264_cuvid_decoder_deps="cuvid"
h264_cuvid_decoder_select="h264_mp4toannexb_bsf"
h264_mediacodec_decoder_deps="mediacodec"
+h264_mediacodec_decoder_extralibs="-landroid"
h264_mediacodec_decoder_select="h264_mp4toannexb_bsf h264_parser"
h264_mf_encoder_deps="mediafoundation"
h264_mmal_decoder_deps="mmal"
@@ -3209,6 +3210,7 @@ hevc_amf_encoder_deps="amf"
hevc_cuvid_decoder_deps="cuvid"
hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
hevc_mediacodec_decoder_deps="mediacodec"
+hevc_mediacodec_decoder_extralibs="-landroid"
hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser"
hevc_mf_encoder_deps="mediafoundation"
hevc_nvenc_encoder_deps="nvenc"
@@ -20,7 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <dlfcn.h>
#include <jni.h>
+#include <media/NdkMediaFormat.h>
+#include <media/NdkMediaCodec.h>
+#include <android/native_window_jni.h>
#include "libavutil/avassert.h"
#include "libavutil/mem.h"
@@ -1794,23 +1798,607 @@ static const FFAMediaCodec media_codec_jni = {
.cleanOutputBuffers = mediacodec_jni_cleanOutputBuffers,
};
-FFAMediaFormat *ff_AMediaFormat_new(void)
+typedef struct FFAMediaFormatNdk {
+ FFAMediaFormat api;
+
+ void *libmedia;
+ AMediaFormat *impl;
+
+ AMediaFormat *(*new)(void);
+ media_status_t (*delete)(AMediaFormat*);
+
+ const char* (*toString)(AMediaFormat*);
+
+ bool (*getInt32)(AMediaFormat*, const char *name, int32_t *out);
+ bool (*getInt64)(AMediaFormat*, const char *name, int64_t *out);
+ bool (*getFloat)(AMediaFormat*, const char *name, float *out);
+ bool (*getSize)(AMediaFormat*, const char *name, size_t *out);
+ bool (*getBuffer)(AMediaFormat*, const char *name, void** data, size_t *size);
+ bool (*getString)(AMediaFormat*, const char *name, const char **out);
+
+ void (*setInt32)(AMediaFormat*, const char* name, int32_t value);
+ void (*setInt64)(AMediaFormat*, const char* name, int64_t value);
+ void (*setFloat)(AMediaFormat*, const char* name, float value);
+ void (*setString)(AMediaFormat*, const char* name, const char* value);
+ void (*setBuffer)(AMediaFormat*, const char* name, const void* data, size_t size);
+} FFAMediaFormatNdk;
+
+typedef struct FFAMediaCodecNdk {
+ FFAMediaCodec api;
+
+ void *libmedia;
+ AMediaCodec *impl;
+ ANativeWindow *window;
+
+ AMediaCodec* (*createCodecByName)(const char *name);
+ AMediaCodec* (*createDecoderByType)(const char *mime_type);
+ AMediaCodec* (*createEncoderByType)(const char *mime_type);
+ media_status_t (*delete)(AMediaCodec*);
+
+ media_status_t (*configure)(AMediaCodec *,
+ const AMediaFormat *format,
+ ANativeWindow *surface,
+ AMediaCrypto *crypto,
+ uint32_t flags);
+ media_status_t (*start)(AMediaCodec*);
+ media_status_t (*stop)(AMediaCodec*);
+ media_status_t (*flush)(AMediaCodec*);
+
+ uint8_t* (*getInputBuffer)(AMediaCodec*, size_t idx, size_t *out_size);
+ uint8_t* (*getOutputBuffer)(AMediaCodec*, size_t idx, size_t *out_size);
+
+ ssize_t (*dequeueInputBuffer)(AMediaCodec*, int64_t timeoutUs);
+ media_status_t (*queueInputBuffer)(AMediaCodec*, size_t idx,
+ long offset, size_t size,
+ uint64_t time, uint32_t flags);
+
+ ssize_t (*dequeueOutputBuffer)(AMediaCodec*, AMediaCodecBufferInfo *info, int64_t timeoutUs);
+ AMediaFormat* (*getOutputFormat)(AMediaCodec*);
+
+ media_status_t (*releaseOutputBuffer)(AMediaCodec*, size_t idx, bool render);
+ media_status_t (*releaseOutputBufferAtTime)(AMediaCodec *mData, size_t idx, int64_t timestampNs);
+
+ // Available since API level 28.
+ media_status_t (*getName)(AMediaCodec*, char** out_name);
+ void (*releaseName)(AMediaCodec*, char* name);
+} FFAMediaCodecNdk;
+
+static const FFAMediaFormat media_format_ndk;
+static const FFAMediaCodec media_codec_ndk;
+
+static const AVClass amediaformat_ndk_class = {
+ .class_name = "amediaformat_ndk",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVClass amediacodec_ndk_class = {
+ .class_name = "amediacodec_ndk",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static FFAMediaFormat *mediaformat_ndk_create(AMediaFormat *impl)
+{
+ FFAMediaFormatNdk *format = av_mallocz(sizeof(*format));
+ if (!format)
+ return NULL;
+
+ format->api = media_format_ndk;
+
+ format->libmedia = dlopen("libmediandk.so", RTLD_NOW);
+ if (!format->libmedia)
+ goto error;
+
+#define GET_SYMBOL(sym) \
+ format->sym = dlsym(format->libmedia, "AMediaFormat_" #sym); \
+ if (!format->sym) \
+ goto error;
+
+ GET_SYMBOL(new)
+ GET_SYMBOL(delete)
+
+ GET_SYMBOL(toString)
+
+ GET_SYMBOL(getInt32)
+ GET_SYMBOL(getInt64)
+ GET_SYMBOL(getFloat)
+ GET_SYMBOL(getSize)
+ GET_SYMBOL(getBuffer)
+ GET_SYMBOL(getString)
+
+ GET_SYMBOL(setInt32)
+ GET_SYMBOL(setInt64)
+ GET_SYMBOL(setFloat)
+ GET_SYMBOL(setString)
+ GET_SYMBOL(setBuffer)
+
+#undef GET_SYMBOL
+
+ if (impl) {
+ format->impl = impl;
+ } else {
+ format->impl = format->new();
+ if (!format->impl)
+ goto error;
+ }
+
+ return (FFAMediaFormat *)format;
+
+error:
+ if (format->libmedia)
+ dlclose(format->libmedia);
+ av_freep(&format);
+ return NULL;
+}
+
+static FFAMediaFormat *mediaformat_ndk_new(void)
+{
+ return mediaformat_ndk_create(NULL);
+}
+
+static int mediaformat_ndk_delete(FFAMediaFormat* ctx)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ int ret = 0;
+ if (!format)
+ return 0;
+
+ av_assert0(format->api.class == &amediaformat_ndk_class);
+
+ if (format->impl && (format->delete(format->impl) != AMEDIA_OK))
+ ret = AVERROR_EXTERNAL;
+ if (format->libmedia)
+ dlclose(format->libmedia);
+ av_free(format);
+
+ return ret;
+}
+
+static char* mediaformat_ndk_toString(FFAMediaFormat* ctx)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ const char *str = format->toString(format->impl);
+ return av_strdup(str);
+}
+
+static int mediaformat_ndk_getInt32(FFAMediaFormat* ctx, const char *name, int32_t *out)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ return format->getInt32(format->impl, name, out);
+}
+
+static int mediaformat_ndk_getInt64(FFAMediaFormat* ctx, const char *name, int64_t *out)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ return format->getInt64(format->impl, name, out);
+}
+
+static int mediaformat_ndk_getFloat(FFAMediaFormat* ctx, const char *name, float *out)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ return format->getFloat(format->impl, name, out);
+}
+
+static int mediaformat_ndk_getBuffer(FFAMediaFormat* ctx, const char *name, void** data, size_t *size)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ return format->getBuffer(format->impl, name, data, size);
+}
+
+static int mediaformat_ndk_getString(FFAMediaFormat* ctx, const char *name, const char **out)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ const char *tmp = NULL;
+ int ret = format->getString(format->impl, name, &tmp);
+
+ if (tmp)
+ *out = av_strdup(tmp);
+ return ret;
+}
+
+static void mediaformat_ndk_setInt32(FFAMediaFormat* ctx, const char* name, int32_t value)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ format->setInt32(format->impl, name, value);
+}
+
+static void mediaformat_ndk_setInt64(FFAMediaFormat* ctx, const char* name, int64_t value)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ format->setInt64(format->impl, name, value);
+}
+
+static void mediaformat_ndk_setFloat(FFAMediaFormat* ctx, const char* name, float value)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ format->setFloat(format->impl, name, value);
+}
+
+static void mediaformat_ndk_setString(FFAMediaFormat* ctx, const char* name, const char* value)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ format->setString(format->impl, name, value);
+}
+
+static void mediaformat_ndk_setBuffer(FFAMediaFormat* ctx, const char* name, void* data, size_t size)
+{
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+ format->setBuffer(format->impl, name, data, size);
+}
+
+static char *mediacodec_ndk_getName(FFAMediaCodec *ctx)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ char *ret = NULL;
+ char *name = NULL;
+
+ if (!codec->getName || !codec->releaseName) {
+ av_log(ctx, AV_LOG_DEBUG, "getName() unavailable\n");
+ return ret;
+ }
+
+ codec->getName(codec->impl, &name);
+ if (name) {
+ ret = av_strdup(name);
+ codec->releaseName(codec->impl, name);
+ }
+
+ return ret;
+}
+
+static inline FFAMediaCodec *ndk_codec_create(int method, const char *arg) {
+ FFAMediaCodecNdk *codec = av_mallocz(sizeof(*codec));
+ const char *lib_name = "libmediandk.so";
+
+ if (!codec)
+ return NULL;
+
+ codec->api = media_codec_ndk;
+ codec->libmedia = dlopen(lib_name, RTLD_NOW);
+ if (!codec->libmedia)
+ goto error;
+
+#define GET_SYMBOL(sym, required) \
+ codec->sym = dlsym(codec->libmedia, "AMediaCodec_" #sym); \
+ if (!codec->sym) { \
+ av_log(codec, required ? AV_LOG_ERROR : AV_LOG_INFO, \
+ #sym "() unavailable from %s\n", lib_name); \
+ if (required) \
+ goto error; \
+ }
+
+ GET_SYMBOL(createCodecByName, 1)
+ GET_SYMBOL(createDecoderByType, 1)
+ GET_SYMBOL(createEncoderByType, 1)
+ GET_SYMBOL(delete, 1)
+
+ GET_SYMBOL(configure, 1)
+ GET_SYMBOL(start, 1)
+ GET_SYMBOL(stop, 1)
+ GET_SYMBOL(flush, 1)
+
+ GET_SYMBOL(getInputBuffer, 1)
+ GET_SYMBOL(getOutputBuffer, 1)
+
+ GET_SYMBOL(dequeueInputBuffer, 1)
+ GET_SYMBOL(queueInputBuffer, 1)
+
+ GET_SYMBOL(dequeueOutputBuffer, 1)
+ GET_SYMBOL(getOutputFormat, 1)
+
+ GET_SYMBOL(releaseOutputBuffer, 1)
+ GET_SYMBOL(releaseOutputBufferAtTime, 1)
+
+ GET_SYMBOL(getName, 0)
+ GET_SYMBOL(releaseName, 0)
+
+#undef GET_SYMBOL
+
+ switch (method) {
+ case CREATE_CODEC_BY_NAME:
+ codec->impl = codec->createCodecByName(arg);
+ break;
+ case CREATE_DECODER_BY_TYPE:
+ codec->impl = codec->createDecoderByType(arg);
+ break;
+ case CREATE_ENCODER_BY_TYPE:
+ codec->impl = codec->createEncoderByType(arg);
+ break;
+ default:
+ av_assert0(0);
+ }
+ if (!codec->impl)
+ goto error;
+
+ return (FFAMediaCodec *)codec;
+
+error:
+ if (codec->libmedia)
+ dlclose(codec->libmedia);
+ av_freep(&codec);
+ return NULL;
+}
+
+#define DECLARE_NDK_AMEDIACODEC_CREATE_FUNC(name, method) \
+static FFAMediaCodec *mediacodec_ndk_##name(const char *arg) \
+{ \
+ return ndk_codec_create(method, arg); \
+} \
+
+DECLARE_NDK_AMEDIACODEC_CREATE_FUNC(createCodecByName, CREATE_CODEC_BY_NAME)
+DECLARE_NDK_AMEDIACODEC_CREATE_FUNC(createDecoderByType, CREATE_DECODER_BY_TYPE)
+DECLARE_NDK_AMEDIACODEC_CREATE_FUNC(createEncoderByType, CREATE_ENCODER_BY_TYPE)
+
+static int mediacodec_ndk_delete(FFAMediaCodec* ctx)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ int ret = 0;
+
+ if (!codec)
+ return 0;
+
+ av_assert0(codec->api.class == &amediacodec_ndk_class);
+
+ if (codec->impl && (codec->delete(codec->impl) != AMEDIA_OK))
+ ret = AVERROR_EXTERNAL;
+ if (codec->window)
+ ANativeWindow_release(codec->window);
+ if (codec->libmedia)
+ dlclose(codec->libmedia);
+ av_free(codec);
+
+ return ret;
+}
+
+static int mediacodec_ndk_configure(FFAMediaCodec* ctx, const FFAMediaFormat* format_ctx, void* surface, void *crypto, uint32_t flags)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)format_ctx;
+ media_status_t status;
+
+ if (surface) {
+ JNIEnv *env = NULL;
+ JNI_GET_ENV_OR_RETURN(env, ctx, -1);
+ codec->window = ANativeWindow_fromSurface(env, surface);
+ }
+
+ if (format_ctx->class != &amediaformat_ndk_class) {
+ av_log(ctx, AV_LOG_ERROR, "invalid media format\n");
+ return AVERROR(EINVAL);
+ }
+
+ status = codec->configure(codec->impl, format->impl, codec->window, NULL, flags);
+ if (status != AMEDIA_OK) {
+ av_log(codec, AV_LOG_ERROR, "configure failed, %d\n", status);
+ return AVERROR_EXTERNAL;
+ }
+
+ return 0;
+}
+
+#define MEDIACODEC_NDK_WRAPPER(method) \
+static int mediacodec_ndk_ ## method(FFAMediaCodec* ctx) \
+{ \
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx; \
+ media_status_t status = codec->method(codec->impl); \
+ \
+ if (status != AMEDIA_OK) { \
+ av_log(codec, AV_LOG_ERROR, #method " failed, %d\n", status); \
+ return AVERROR_EXTERNAL; \
+ } \
+ \
+ return 0; \
+} \
+
+MEDIACODEC_NDK_WRAPPER(start)
+MEDIACODEC_NDK_WRAPPER(stop)
+MEDIACODEC_NDK_WRAPPER(flush)
+
+static uint8_t* mediacodec_ndk_getInputBuffer(FFAMediaCodec* ctx, size_t idx, size_t *out_size)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ return codec->getInputBuffer(codec->impl, idx, out_size);
+}
+
+static uint8_t* mediacodec_ndk_getOutputBuffer(FFAMediaCodec* ctx, size_t idx, size_t *out_size)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ return codec->getOutputBuffer(codec->impl, idx, out_size);
+}
+
+static ssize_t mediacodec_ndk_dequeueInputBuffer(FFAMediaCodec* ctx, int64_t timeoutUs)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ return codec->dequeueInputBuffer(codec->impl, timeoutUs);
+}
+
+static int mediacodec_ndk_queueInputBuffer(FFAMediaCodec *ctx, size_t idx,
+ off_t offset, size_t size,
+ uint64_t time, uint32_t flags)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ return codec->queueInputBuffer(codec->impl, idx, offset, size, time, flags);
+}
+
+static ssize_t mediacodec_ndk_dequeueOutputBuffer(FFAMediaCodec* ctx, FFAMediaCodecBufferInfo *info, int64_t timeoutUs)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ AMediaCodecBufferInfo buf_info = {0};
+ ssize_t ret;
+
+ ret = codec->dequeueOutputBuffer(codec->impl, &buf_info, timeoutUs);
+ info->offset = buf_info.offset;
+ info->size = buf_info.size;
+ info->presentationTimeUs = buf_info.presentationTimeUs;
+ info->flags = buf_info.flags;
+
+ return ret;
+}
+
+static FFAMediaFormat* mediacodec_ndk_getOutputFormat(FFAMediaCodec* ctx)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ AMediaFormat *format = codec->getOutputFormat(codec->impl);
+
+ if (!format)
+ return NULL;
+ return mediaformat_ndk_create(format);
+}
+
+static int mediacodec_ndk_releaseOutputBuffer(FFAMediaCodec* ctx, size_t idx, int render)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ media_status_t status;
+
+ status = codec->releaseOutputBuffer(codec->impl, idx, render);
+ if (status != AMEDIA_OK) {
+ av_log(codec, AV_LOG_ERROR, "release output buffer failed, %d\n", status);
+ return AVERROR_EXTERNAL;
+ }
+
+ return 0;
+}
+
+static int mediacodec_ndk_releaseOutputBufferAtTime(FFAMediaCodec *ctx, size_t idx, int64_t timestampNs)
+{
+ FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
+ media_status_t status;
+
+ status = codec->releaseOutputBufferAtTime(codec->impl, idx, timestampNs);
+ if (status != AMEDIA_OK) {
+ av_log(codec, AV_LOG_ERROR, "releaseOutputBufferAtTime failed, %d\n", status);
+ return AVERROR_EXTERNAL;
+ }
+
+ return 0;
+}
+
+static int mediacodec_ndk_infoTryAgainLater(FFAMediaCodec *ctx, ssize_t idx)
+{
+ return idx == AMEDIACODEC_INFO_TRY_AGAIN_LATER;
+}
+
+static int mediacodec_ndk_infoOutputBuffersChanged(FFAMediaCodec *ctx, ssize_t idx)
+{
+ return idx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED;
+}
+
+static int mediacodec_ndk_infoOutputFormatChanged(FFAMediaCodec *ctx, ssize_t idx)
+{
+ return idx == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED;
+}
+
+static int mediacodec_ndk_getBufferFlagCodecConfig(FFAMediaCodec *ctx)
+{
+ return AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG;
+}
+
+static int mediacodec_ndk_getBufferFlagEndOfStream(FFAMediaCodec *ctx)
+{
+ return AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
+}
+
+static int mediacodec_ndk_getBufferFlagKeyFrame(FFAMediaCodec *ctx)
+{
+ return 1;
+}
+
+static int mediacodec_ndk_getConfigureFlagEncode(FFAMediaCodec *ctx)
+{
+ return AMEDIACODEC_CONFIGURE_FLAG_ENCODE;
+}
+
+static int mediacodec_ndk_cleanOutputBuffers(FFAMediaCodec *ctx)
+{
+ return 0;
+}
+
+static const FFAMediaFormat media_format_ndk = {
+ .class = &amediaformat_ndk_class,
+
+ .create = mediaformat_ndk_new,
+ .delete = mediaformat_ndk_delete,
+
+ .toString = mediaformat_ndk_toString,
+
+ .getInt32 = mediaformat_ndk_getInt32,
+ .getInt64 = mediaformat_ndk_getInt64,
+ .getFloat = mediaformat_ndk_getFloat,
+ .getBuffer = mediaformat_ndk_getBuffer,
+ .getString = mediaformat_ndk_getString,
+
+ .setInt32 = mediaformat_ndk_setInt32,
+ .setInt64 = mediaformat_ndk_setInt64,
+ .setFloat = mediaformat_ndk_setFloat,
+ .setString = mediaformat_ndk_setString,
+ .setBuffer = mediaformat_ndk_setBuffer,
+};
+
+static const FFAMediaCodec media_codec_ndk = {
+ .class = &amediacodec_ndk_class,
+
+ .getName = mediacodec_ndk_getName,
+
+ .createCodecByName = mediacodec_ndk_createCodecByName,
+ .createDecoderByType = mediacodec_ndk_createDecoderByType,
+ .createEncoderByType = mediacodec_ndk_createEncoderByType,
+ .delete = mediacodec_ndk_delete,
+
+ .configure = mediacodec_ndk_configure,
+ .start = mediacodec_ndk_start,
+ .stop = mediacodec_ndk_stop,
+ .flush = mediacodec_ndk_flush,
+
+ .getInputBuffer = mediacodec_ndk_getInputBuffer,
+ .getOutputBuffer = mediacodec_ndk_getOutputBuffer,
+
+ .dequeueInputBuffer = mediacodec_ndk_dequeueInputBuffer,
+ .queueInputBuffer = mediacodec_ndk_queueInputBuffer,
+
+ .dequeueOutputBuffer = mediacodec_ndk_dequeueOutputBuffer,
+ .getOutputFormat = mediacodec_ndk_getOutputFormat,
+
+ .releaseOutputBuffer = mediacodec_ndk_releaseOutputBuffer,
+ .releaseOutputBufferAtTime = mediacodec_ndk_releaseOutputBufferAtTime,
+
+ .infoTryAgainLater = mediacodec_ndk_infoTryAgainLater,
+ .infoOutputBuffersChanged = mediacodec_ndk_infoOutputBuffersChanged,
+ .infoOutputFormatChanged = mediacodec_ndk_infoOutputFormatChanged,
+
+ .getBufferFlagCodecConfig = mediacodec_ndk_getBufferFlagCodecConfig,
+ .getBufferFlagEndOfStream = mediacodec_ndk_getBufferFlagEndOfStream,
+ .getBufferFlagKeyFrame = mediacodec_ndk_getBufferFlagKeyFrame,
+
+ .getConfigureFlagEncode = mediacodec_ndk_getConfigureFlagEncode,
+ .cleanOutputBuffers = mediacodec_ndk_cleanOutputBuffers,
+};
+
+FFAMediaFormat *ff_AMediaFormat_new(int ndk)
{
+ if (ndk)
+ return media_format_ndk.create();
return media_format_jni.create();
}
-FFAMediaCodec* ff_AMediaCodec_createCodecByName(const char *name)
+FFAMediaCodec* ff_AMediaCodec_createCodecByName(const char *name, int ndk)
{
+ if (ndk)
+ return media_codec_ndk.createCodecByName(name);
return media_codec_jni.createCodecByName(name);
}
-FFAMediaCodec* ff_AMediaCodec_createDecoderByType(const char *mime_type)
+FFAMediaCodec* ff_AMediaCodec_createDecoderByType(const char *mime_type, int ndk)
{
+ if (ndk)
+ return media_codec_ndk.createDecoderByType(mime_type);
return media_codec_jni.createDecoderByType(mime_type);
}
-FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type)
+FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type, int ndk)
{
+ if (ndk)
+ return media_codec_ndk.createEncoderByType(mime_type);
return media_codec_jni.createEncoderByType(mime_type);
}
@@ -80,7 +80,7 @@ struct FFAMediaFormat {
void (*setBuffer)(FFAMediaFormat* format, const char* name, void* data, size_t size);
};
-FFAMediaFormat *ff_AMediaFormat_new(void);
+FFAMediaFormat *ff_AMediaFormat_new(int ndk);
static inline int ff_AMediaFormat_delete(FFAMediaFormat* format)
{
@@ -198,9 +198,9 @@ static inline char *ff_AMediaCodec_getName(FFAMediaCodec *codec)
return codec->getName(codec);
}
-FFAMediaCodec* ff_AMediaCodec_createCodecByName(const char *name);
-FFAMediaCodec* ff_AMediaCodec_createDecoderByType(const char *mime_type);
-FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type);
+FFAMediaCodec* ff_AMediaCodec_createCodecByName(const char *name, int ndk);
+FFAMediaCodec* ff_AMediaCodec_createDecoderByType(const char *mime_type, int ndk);
+FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type, int ndk);
static inline int ff_AMediaCodec_configure(FFAMediaCodec* codec, const FFAMediaFormat* format, void* surface, void *crypto, uint32_t flags)
{
@@ -310,7 +310,7 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
FFAMediaFormat *format = NULL;
MediaCodecH264DecContext *s = avctx->priv_data;
- format = ff_AMediaFormat_new();
+ format = ff_AMediaFormat_new(0);
if (!format) {
av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n");
ret = AVERROR_EXTERNAL;
@@ -606,7 +606,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s,
}
av_log(avctx, AV_LOG_DEBUG, "Found decoder %s\n", s->codec_name);
- s->codec = ff_AMediaCodec_createCodecByName(s->codec_name);
+ s->codec = ff_AMediaCodec_createCodecByName(s->codec_name, 0);
if (!s->codec) {
av_log(avctx, AV_LOG_ERROR, "Failed to create media decoder for type %s and name %s\n", mime, s->codec_name);
ret = AVERROR_EXTERNAL;