diff options
author | Zhao Zhili <zhilizhao@tencent.com> | 2022-10-17 00:50:02 +0800 |
---|---|---|
committer | Zhao Zhili <zhilizhao@tencent.com> | 2022-11-21 23:52:34 +0800 |
commit | 4df9cb918eb645d3690a5209212be7f0471e35eb (patch) | |
tree | f28e9e1e1cd51f103191cfa2f429e967e4f0d89d | |
parent | 4f2ea862b3de1647de0d9e00702801671764a762 (diff) | |
download | ffmpeg-4df9cb918eb645d3690a5209212be7f0471e35eb.tar.gz |
avcodec/mediacodec: add NDK media codec wrapper
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | libavcodec/mediacodec_wrapper.c | 596 | ||||
-rw-r--r-- | libavcodec/mediacodec_wrapper.h | 8 | ||||
-rw-r--r-- | libavcodec/mediacodecdec.c | 2 | ||||
-rw-r--r-- | libavcodec/mediacodecdec_common.c | 2 |
5 files changed, 600 insertions, 10 deletions
@@ -3181,6 +3181,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" @@ -3199,6 +3200,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" diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c index e0c614680e..b12aced711 100644 --- a/libavcodec/mediacodec_wrapper.c +++ b/libavcodec/mediacodec_wrapper.c @@ -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); } diff --git a/libavcodec/mediacodec_wrapper.h b/libavcodec/mediacodec_wrapper.h index 606fdbede5..b9b882f243 100644 --- a/libavcodec/mediacodec_wrapper.h +++ b/libavcodec/mediacodec_wrapper.h @@ -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) { diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c index 2c66f38541..2e07548b77 100644 --- a/libavcodec/mediacodecdec.c +++ b/libavcodec/mediacodecdec.c @@ -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; diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c index 69a462ec48..4a9e50b0df 100644 --- a/libavcodec/mediacodecdec_common.c +++ b/libavcodec/mediacodecdec_common.c @@ -613,7 +613,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; |