vlc | branch: master | Thomas Guillem <[email protected]> | 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; } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
