mirror of https://github.com/FFmpeg/FFmpeg.git
parent
83a940e7fb
commit
0f2654c9a3
14 changed files with 616 additions and 59 deletions
@ -0,0 +1,133 @@ |
|||||||
|
/*
|
||||||
|
* Android MediaCodec public API functions |
||||||
|
* |
||||||
|
* Copyright (c) 2016 Matthieu Bouron <matthieu.bouron stupeflix.com> |
||||||
|
* |
||||||
|
* This file is part of FFmpeg. |
||||||
|
* |
||||||
|
* FFmpeg is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License as published by the Free Software Foundation; either |
||||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpeg is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public |
||||||
|
* License along with FFmpeg; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "config.h" |
||||||
|
|
||||||
|
#if CONFIG_H264_MEDIACODEC_HWACCEL |
||||||
|
|
||||||
|
#include <jni.h> |
||||||
|
|
||||||
|
#include "libavcodec/avcodec.h" |
||||||
|
#include "libavutil/atomic.h" |
||||||
|
#include "libavutil/mem.h" |
||||||
|
|
||||||
|
#include "ffjni.h" |
||||||
|
#include "mediacodec.h" |
||||||
|
#include "mediacodecdec.h" |
||||||
|
|
||||||
|
AVMediaCodecContext *av_mediacodec_alloc_context(void) |
||||||
|
{ |
||||||
|
return av_mallocz(sizeof(AVMediaCodecContext)); |
||||||
|
} |
||||||
|
|
||||||
|
int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface) |
||||||
|
{ |
||||||
|
int ret = 0; |
||||||
|
JNIEnv *env = NULL; |
||||||
|
int attached = 0; |
||||||
|
|
||||||
|
env = ff_jni_attach_env(&attached, avctx); |
||||||
|
if (!env) { |
||||||
|
return AVERROR_EXTERNAL; |
||||||
|
} |
||||||
|
|
||||||
|
ctx->surface = (*env)->NewGlobalRef(env, surface); |
||||||
|
if (ctx->surface) { |
||||||
|
avctx->hwaccel_context = ctx; |
||||||
|
} else { |
||||||
|
av_log(avctx, AV_LOG_ERROR, "Could not create new global reference\n"); |
||||||
|
ret = AVERROR_EXTERNAL; |
||||||
|
} |
||||||
|
|
||||||
|
if (attached) { |
||||||
|
ff_jni_detach_env(avctx); |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void av_mediacodec_default_free(AVCodecContext *avctx) |
||||||
|
{ |
||||||
|
JNIEnv *env = NULL; |
||||||
|
int attached = 0; |
||||||
|
|
||||||
|
AVMediaCodecContext *ctx = avctx->hwaccel_context; |
||||||
|
|
||||||
|
if (!ctx) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
env = ff_jni_attach_env(&attached, avctx); |
||||||
|
if (!env) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (ctx->surface) { |
||||||
|
(*env)->DeleteGlobalRef(env, ctx->surface); |
||||||
|
ctx->surface = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
if (attached) { |
||||||
|
ff_jni_detach_env(avctx); |
||||||
|
} |
||||||
|
|
||||||
|
av_freep(&avctx->hwaccel_context); |
||||||
|
} |
||||||
|
|
||||||
|
int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) |
||||||
|
{ |
||||||
|
MediaCodecDecContext *ctx = buffer->ctx; |
||||||
|
int released = avpriv_atomic_int_add_and_fetch(&buffer->released, 1); |
||||||
|
|
||||||
|
if (released == 1) { |
||||||
|
return ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, render); |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
|
||||||
|
#include "mediacodec.h" |
||||||
|
|
||||||
|
AVMediaCodecContext *av_mediacodec_alloc_context(void) |
||||||
|
{ |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface) |
||||||
|
{ |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void av_mediacodec_default_free(AVCodecContext *avctx) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) |
||||||
|
{ |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,88 @@ |
|||||||
|
/*
|
||||||
|
* Android MediaCodec public API |
||||||
|
* |
||||||
|
* Copyright (c) 2016 Matthieu Bouron <matthieu.bouron stupeflix.com> |
||||||
|
* |
||||||
|
* This file is part of FFmpeg. |
||||||
|
* |
||||||
|
* FFmpeg is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License as published by the Free Software Foundation; either |
||||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpeg is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public |
||||||
|
* License along with FFmpeg; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef AVCODEC_MEDIACODEC_H |
||||||
|
#define AVCODEC_MEDIACODEC_H |
||||||
|
|
||||||
|
#include "libavcodec/avcodec.h" |
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure holds a reference to a android/view/Surface object that will |
||||||
|
* be used as output by the decoder. |
||||||
|
* |
||||||
|
*/ |
||||||
|
typedef struct AVMediaCodecContext { |
||||||
|
|
||||||
|
/**
|
||||||
|
* android/view/Surface object reference. |
||||||
|
*/ |
||||||
|
void *surface; |
||||||
|
|
||||||
|
} AVMediaCodecContext; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate and initialize a MediaCodec context. |
||||||
|
* |
||||||
|
* When decoding with MediaCodec is finished, the caller must free the |
||||||
|
* MediaCodec context with av_mediacodec_default_free. |
||||||
|
* |
||||||
|
* @return a pointer to a newly allocated AVMediaCodecContext on success, NULL otherwise |
||||||
|
*/ |
||||||
|
AVMediaCodecContext *av_mediacodec_alloc_context(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience function that sets up the MediaCodec context. |
||||||
|
* |
||||||
|
* @param avctx codec context |
||||||
|
* @param ctx MediaCodec context to initialize |
||||||
|
* @param surface reference to an android/view/Surface |
||||||
|
* @return 0 on success, < 0 otherwise |
||||||
|
*/ |
||||||
|
int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface); |
||||||
|
|
||||||
|
/**
|
||||||
|
* This function must be called to free the MediaCodec context initialized with |
||||||
|
* av_mediacodec_default_init(). |
||||||
|
* |
||||||
|
* @param avctx codec context |
||||||
|
*/ |
||||||
|
void av_mediacodec_default_free(AVCodecContext *avctx); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Opaque structure representing a MediaCodec buffer to render. |
||||||
|
*/ |
||||||
|
typedef struct MediaCodecBuffer AVMediaCodecBuffer; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Release a MediaCodec buffer and render it to the surface that is associated |
||||||
|
* with the decoder. This function should only be called once on a given |
||||||
|
* buffer, once released the underlying buffer returns to the codec, thus |
||||||
|
* subsequent calls to this function will have no effect. |
||||||
|
* |
||||||
|
* @param buffer the buffer to render |
||||||
|
* @param render 1 to release and render the buffer to the surface or 0 to |
||||||
|
* discard the buffer |
||||||
|
* @return 0 on success, < 0 otherwise |
||||||
|
*/ |
||||||
|
int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render); |
||||||
|
|
||||||
|
#endif /* AVCODEC_MEDIACODEC_H */ |
@ -0,0 +1,66 @@ |
|||||||
|
/*
|
||||||
|
* Android MediaCodec Surface functions |
||||||
|
* |
||||||
|
* Copyright (c) 2016 Matthieu Bouron <matthieu.bouron stupeflix.com> |
||||||
|
* |
||||||
|
* This file is part of FFmpeg. |
||||||
|
* |
||||||
|
* FFmpeg is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License as published by the Free Software Foundation; either |
||||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpeg is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public |
||||||
|
* License along with FFmpeg; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <jni.h> |
||||||
|
|
||||||
|
#include "ffjni.h" |
||||||
|
#include "mediacodec_surface.h" |
||||||
|
|
||||||
|
void *ff_mediacodec_surface_ref(void *surface, void *log_ctx) |
||||||
|
{ |
||||||
|
int attached = 0; |
||||||
|
JNIEnv *env = NULL; |
||||||
|
|
||||||
|
void *reference = NULL; |
||||||
|
|
||||||
|
env = ff_jni_attach_env(&attached, log_ctx); |
||||||
|
if (!env) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
reference = (*env)->NewGlobalRef(env, surface); |
||||||
|
|
||||||
|
if (attached) { |
||||||
|
ff_jni_detach_env(log_ctx); |
||||||
|
} |
||||||
|
|
||||||
|
return reference; |
||||||
|
} |
||||||
|
|
||||||
|
int ff_mediacodec_surface_unref(void *surface, void *log_ctx) |
||||||
|
{ |
||||||
|
int attached = 0; |
||||||
|
JNIEnv *env = NULL; |
||||||
|
|
||||||
|
env = ff_jni_attach_env(&attached, log_ctx); |
||||||
|
if (!env) { |
||||||
|
return AVERROR_EXTERNAL; |
||||||
|
} |
||||||
|
|
||||||
|
(*env)->DeleteGlobalRef(env, surface); |
||||||
|
|
||||||
|
if (attached) { |
||||||
|
ff_jni_detach_env(log_ctx); |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
/*
|
||||||
|
* Android MediaCodec Surface functions |
||||||
|
* |
||||||
|
* Copyright (c) 2016 Matthieu Bouron <matthieu.bouron stupeflix.com> |
||||||
|
* |
||||||
|
* This file is part of FFmpeg. |
||||||
|
* |
||||||
|
* FFmpeg is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License as published by the Free Software Foundation; either |
||||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpeg is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public |
||||||
|
* License along with FFmpeg; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef AVCODEC_MEDIACODEC_SURFACE_H |
||||||
|
#define AVCODEC_MEDIACODEC_SURFACE_H |
||||||
|
|
||||||
|
#include "libavcodec/avcodec.h" |
||||||
|
|
||||||
|
void *ff_mediacodec_surface_ref(void *surface, void *log_ctx); |
||||||
|
int ff_mediacodec_surface_unref(void *surface, void *log_ctx); |
||||||
|
|
||||||
|
#endif /* AVCODEC_MEDIACODEC_SURFACE_H */ |
Loading…
Reference in new issue