[vlc-commits] mediacodec: add adaptive playback support
Thomas Guillem
git at videolan.org
Wed Mar 29 15:49:45 CEST 2017
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Mar 24 12:02:22 2017 +0100| [9d9e5d293f2ffa5341a787435ba74655d2a9b0cb] | committer: Thomas Guillem
mediacodec: add adaptive playback support
Starting Android 4.4, devices can have the "adaptive-playback" capability. If a
device have such capability, we don't have to use hxxx_helper to detect SPS/PPS
change since the device is capable of handling it. It can also handle a video
size change.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9d9e5d293f2ffa5341a787435ba74655d2a9b0cb
---
modules/codec/omxil/mediacodec.c | 30 ++++++++++++++++++++++++++---
modules/codec/omxil/mediacodec.h | 4 ++++
modules/codec/omxil/mediacodec_jni.c | 37 ++++++++++++++++++++++++++++--------
modules/codec/omxil/mediacodec_ndk.c | 13 +++++++++----
4 files changed, 69 insertions(+), 15 deletions(-)
diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c
index d107bd3..05a6dbb 100644
--- a/modules/codec/omxil/mediacodec.c
+++ b/modules/codec/omxil/mediacodec.c
@@ -103,6 +103,7 @@ struct decoder_sys_t
/* If true, the first input block was successfully dequeued */
bool b_input_dequeued;
bool b_aborted;
+ bool b_adaptive;
int i_decode_flags;
union
@@ -283,6 +284,12 @@ static int ParseVideoExtraH264(decoder_t *p_dec, uint8_t *p_extra, int i_extra)
if (i_ret != VLC_SUCCESS)
return i_ret;
+ if (!hh->b_is_xvcC && p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_ADAPTIVE)
+ {
+ p_sys->b_adaptive = true;
+ return VLC_SUCCESS;
+ }
+
assert(hh->pf_process_block != NULL);
p_sys->pf_on_new_block = VideoHXXX_OnNewBlock;
@@ -297,9 +304,20 @@ static int ParseVideoExtraHEVC(decoder_t *p_dec, uint8_t *p_extra, int i_extra)
struct hxxx_helper *hh = &p_sys->video.hh;
int i_ret = hxxx_helper_set_extra(hh, p_extra, i_extra);
- if (i_ret != VLC_SUCCESS || hh->pf_process_block == NULL)
+ if (i_ret != VLC_SUCCESS)
return i_ret;
+ if (!hh->b_is_xvcC)
+ {
+ if (p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_ADAPTIVE)
+ {
+ p_sys->b_adaptive = true;
+ return VLC_SUCCESS;
+ }
+ else /* TODO */
+ return VLC_EGENERIC;
+ }
+
assert(hh->pf_process_block != NULL);
p_sys->pf_on_new_block = VideoHXXX_OnNewBlock;
@@ -445,7 +463,8 @@ static int StartMediaCodec(decoder_t *p_dec)
decoder_sys_t *p_sys = p_dec->p_sys;
union mc_api_args args;
- if (((p_sys->api.i_quirks & MC_API_QUIRKS_NEED_CSD) && !p_sys->i_csd_count))
+ if ((p_sys->api.i_quirks & MC_API_QUIRKS_NEED_CSD) && !p_sys->i_csd_count
+ && !p_sys->b_adaptive)
{
msg_Warn(p_dec, "waiting for extra data for codec %4.4s",
(const char *)&p_dec->fmt_in.i_codec);
@@ -454,7 +473,8 @@ static int StartMediaCodec(decoder_t *p_dec)
if (p_dec->fmt_in.i_cat == VIDEO_ES)
{
- if (!p_dec->fmt_out.video.i_width || !p_dec->fmt_out.video.i_height)
+ if (!p_sys->b_adaptive
+ && (!p_dec->fmt_out.video.i_width || !p_dec->fmt_out.video.i_height))
{
msg_Warn(p_dec, "waiting for a valid video size for codec %4.4s",
(const char *)&p_dec->fmt_in.i_codec);
@@ -468,6 +488,9 @@ static int StartMediaCodec(decoder_t *p_dec)
args.video.p_jsurface = p_sys->video.p_jsurface;
args.video.b_tunneled_playback = args.video.p_surface ?
var_InheritBool(p_dec, CFG_PREFIX "tunneled-playback") : false;
+ if (p_sys->b_adaptive)
+ msg_Dbg(p_dec, "mediacodec configured for adaptative playback");
+ args.video.b_adaptive_playback = p_sys->b_adaptive;
}
else
{
@@ -1368,6 +1391,7 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
if (!i_ts && p_block->i_dts)
i_ts = p_block->i_dts;
}
+ else fprintf(stderr, "send CSD\n");
p_buf = p_block->p_buffer;
i_size = p_block->i_buffer;
}
diff --git a/modules/codec/omxil/mediacodec.h b/modules/codec/omxil/mediacodec.h
index 211bbf6..ed0eb73 100644
--- a/modules/codec/omxil/mediacodec.h
+++ b/modules/codec/omxil/mediacodec.h
@@ -45,6 +45,9 @@ int MediaCodecNdk_Init(mc_api*);
#define MC_API_VIDEO_QUIRKS_SUPPORT_INTERLACED 0x4
#define MC_API_AUDIO_QUIRKS_NEED_CHANNELS 0x8
+/* MediaCodec only QUIRKS */
+#define MC_API_VIDEO_QUIRKS_ADAPTIVE 0x1000
+
struct mc_api_out
{
enum {
@@ -94,6 +97,7 @@ union mc_api_args
int i_height;
int i_angle;
bool b_tunneled_playback;
+ bool b_adaptive_playback;
} video;
struct
{
diff --git a/modules/codec/omxil/mediacodec_jni.c b/modules/codec/omxil/mediacodec_jni.c
index 426f33c..b69cb1a 100644
--- a/modules/codec/omxil/mediacodec_jni.c
+++ b/modules/codec/omxil/mediacodec_jni.c
@@ -38,7 +38,7 @@
#include "mediacodec.h"
char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
- size_t h264_profile);
+ size_t h264_profile, bool *p_adaptive);
#define THREAD_NAME "mediacodec_jni"
@@ -58,6 +58,7 @@ struct jfields
jclass buffer_info_class, byte_buffer_class;
jmethodID tostring;
jmethodID get_codec_count, get_codec_info_at, is_encoder, get_capabilities_for_type;
+ jmethodID is_feature_supported;
jfieldID profile_levels_field, profile_field, level_field;
jmethodID get_supported_types, get_name;
jmethodID create_by_codec_name, configure, start, stop, flush, release;
@@ -113,7 +114,7 @@ static const struct member members[] = {
{ "getSupportedTypes", "()[Ljava/lang/String;", "android/media/MediaCodecInfo", OFF(get_supported_types), METHOD, true },
{ "getName", "()Ljava/lang/String;", "android/media/MediaCodecInfo", OFF(get_name), METHOD, true },
{ "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", "android/media/MediaCodecInfo", OFF(get_capabilities_for_type), METHOD, true },
-
+ { "isFeatureSupported", "(Ljava/lang/String;)Z", "android/media/MediaCodecInfo$CodecCapabilities", OFF(is_feature_supported), METHOD, false },
{ "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", "android/media/MediaCodecInfo$CodecCapabilities", OFF(profile_levels_field), FIELD, true },
{ "profile", "I", "android/media/MediaCodecInfo$CodecProfileLevel", OFF(profile_field), FIELD, true },
{ "level", "I", "android/media/MediaCodecInfo$CodecProfileLevel", OFF(level_field), FIELD, true },
@@ -309,7 +310,7 @@ struct mc_api_sys
* MediaCodec_GetName
*****************************************************************************/
char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
- size_t h264_profile)
+ size_t h264_profile, bool *p_adaptive)
{
JNIEnv *env;
int num_codecs;
@@ -341,6 +342,7 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
int profile_levels_len = 0, num_types = 0;
const char *name_ptr = NULL;
bool found = false;
+ bool b_adaptive = false;
info = (*env)->CallStaticObjectMethod(env, jfields.media_codec_list_class,
jfields.get_codec_info_at, i);
@@ -368,6 +370,16 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
profile_levels = (*env)->GetObjectField(env, codec_capabilities, jfields.profile_levels_field);
if (profile_levels)
profile_levels_len = (*env)->GetArrayLength(env, profile_levels);
+ if (jfields.is_feature_supported)
+ {
+ jstring jfeature = JNI_NEW_STRING("adaptive-playback");
+ b_adaptive =
+ (*env)->CallBooleanMethod(env, codec_capabilities,
+ jfields.is_feature_supported,
+ jfeature);
+ CHECK_EXCEPTION();
+ (*env)->DeleteLocalRef(env, jfeature);
+ }
}
msg_Dbg(p_obj, "Number of profile levels: %d", profile_levels_len);
@@ -418,6 +430,7 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
memcpy(psz_name, name_ptr, name_len);
psz_name[name_len] = '\0';
}
+ *p_adaptive = b_adaptive;
}
loopclean:
if (name)
@@ -543,10 +556,15 @@ static int Start(mc_api *api, union mc_api_args *p_args)
if (p_args->video.i_angle != 0)
SET_INTEGER(jformat, "rotation-degrees", p_args->video.i_angle);
- /* feature-tunneled-playback available since API 21 */
- if (b_direct_rendering && jfields.get_input_buffer)
- SET_INTEGER(jformat, "feature-tunneled-playback",
- p_args->video.b_tunneled_playback);
+ if (b_direct_rendering)
+ {
+ /* feature-tunneled-playback available since API 21 */
+ if (jfields.get_input_buffer && p_args->video.b_tunneled_playback)
+ SET_INTEGER(jformat, "feature-tunneled-playback", 1);
+
+ if (p_args->video.b_adaptive_playback)
+ SET_INTEGER(jformat, "feature-adaptive-playback", 1);
+ }
}
else
{
@@ -946,8 +964,9 @@ static void Clean(mc_api *api)
static int Configure(mc_api *api, size_t i_h264_profile)
{
free(api->psz_name);
+ bool b_adaptive;
api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime,
- i_h264_profile);
+ i_h264_profile, &b_adaptive);
if (!api->psz_name)
return MC_API_ERROR;
api->i_quirks = OMXCodec_GetQuirks(api->i_cat, api->i_codec, api->psz_name,
@@ -956,6 +975,8 @@ static int Configure(mc_api *api, size_t i_h264_profile)
/* Allow interlaced picture after API 21 */
if (jfields.get_input_buffer && jfields.get_output_buffer)
api->i_quirks |= MC_API_VIDEO_QUIRKS_SUPPORT_INTERLACED;
+ if (b_adaptive)
+ api->i_quirks |= MC_API_VIDEO_QUIRKS_ADAPTIVE;
return 0;
}
diff --git a/modules/codec/omxil/mediacodec_ndk.c b/modules/codec/omxil/mediacodec_ndk.c
index 8677c74..a07ec20 100644
--- a/modules/codec/omxil/mediacodec_ndk.c
+++ b/modules/codec/omxil/mediacodec_ndk.c
@@ -39,7 +39,7 @@
#include "mediacodec.h"
char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
- size_t h264_profile);
+ size_t h264_profile, bool *p_adaptive);
#define THREAD_NAME "mediacodec_ndk"
@@ -342,8 +342,10 @@ static int Start(mc_api *api, union mc_api_args *p_args)
p_anw = p_args->video.p_surface;
if (p_args->video.b_tunneled_playback)
syms.AMediaFormat.setInt32(p_sys->p_format,
- "feature-tunneled-playback",
- p_args->video.b_tunneled_playback);
+ "feature-tunneled-playback", 1);
+ if (p_args->video.b_adaptive_playback)
+ syms.AMediaFormat.setInt32(p_sys->p_format,
+ "feature-adaptive-playback", 1);
}
}
else
@@ -584,14 +586,17 @@ static void Clean(mc_api *api)
static int Configure(mc_api * api, size_t i_h264_profile)
{
free(api->psz_name);
+ bool b_adaptive;
api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime,
- i_h264_profile);
+ i_h264_profile, &b_adaptive);
if (!api->psz_name)
return MC_API_ERROR;
api->i_quirks = OMXCodec_GetQuirks(api->i_cat, api->i_codec, api->psz_name,
strlen(api->psz_name));
/* Allow interlaced picture after API 21 */
api->i_quirks |= MC_API_VIDEO_QUIRKS_SUPPORT_INTERLACED;
+ if (b_adaptive)
+ api->i_quirks |= MC_API_VIDEO_QUIRKS_ADAPTIVE;
return 0;
}
More information about the vlc-commits
mailing list