Commit 3e21d7ce authored by Duncan McNAMARA's avatar Duncan McNAMARA Committed by Thomas Guillem

mediacodec: fail in case of unsupported resolution

Signed-off-by: Thomas Guillem's avatarThomas Guillem <thomas@gllm.fr>
parent 9e857807
...@@ -510,7 +510,7 @@ static int StartMediaCodec(decoder_t *p_dec) ...@@ -510,7 +510,7 @@ static int StartMediaCodec(decoder_t *p_dec)
if (p_sys->u.video.i_h264_profile) if (p_sys->u.video.i_h264_profile)
{ {
if (p_sys->api->configure(p_sys->api, if (p_sys->api->configure(p_sys->api,
p_sys->u.video.i_h264_profile) != 0 ) p_sys->u.video.i_h264_profile, 0, 0) != 0 )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} }
...@@ -662,18 +662,23 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init) ...@@ -662,18 +662,23 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
free(api); free(api);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if (api->configure(api, i_h264_profile) != 0)
if (api->configure(api, i_h264_profile,
p_dec->fmt_in.video.i_width,
p_dec->fmt_in.video.i_height) != 0)
{ {
/* If the device can't handle video/wvc1, /* If the device can't handle video/wvc1,
* it can probably handle video/x-ms-wmv */ * it can probably handle video/x-ms-wmv */
if (!strcmp(mime, "video/wvc1") && p_dec->fmt_in.i_codec == VLC_CODEC_VC1) if (!strcmp(mime, "video/wvc1") && p_dec->fmt_in.i_codec == VLC_CODEC_VC1)
{ {
api->psz_mime = "video/x-ms-wmv"; api->psz_mime = "video/x-ms-wmv";
if (api->configure(api, i_h264_profile) != 0) if (api->configure(api, i_h264_profile,
p_dec->fmt_in.video.i_width,
p_dec->fmt_in.video.i_height) != 0)
{ {
api->clean(api); api->clean(api);
free(api); free(api);
return (VLC_EGENERIC); return VLC_EGENERIC;
} }
} }
else else
......
...@@ -119,7 +119,8 @@ struct mc_api ...@@ -119,7 +119,8 @@ struct mc_api
bool b_direct_rendering; bool b_direct_rendering;
void (*clean)(mc_api *); void (*clean)(mc_api *);
int (*configure)(mc_api *, size_t i_h264_profile); int (*configure)(mc_api *, size_t i_h264_profile,
unsigned int i_width, unsigned int i_height);
int (*start)(mc_api *, union mc_api_args *p_args); int (*start)(mc_api *, union mc_api_args *p_args);
int (*stop)(mc_api *); int (*stop)(mc_api *);
int (*flush)(mc_api *); int (*flush)(mc_api *);
......
...@@ -37,8 +37,8 @@ ...@@ -37,8 +37,8 @@
#include "mediacodec.h" #include "mediacodec.h"
char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime, char* MediaCodec_GetName(vlc_object_t *, const char *, size_t,
size_t h264_profile); unsigned int, unsigned int);
#define THREAD_NAME "mediacodec_jni" #define THREAD_NAME "mediacodec_jni"
...@@ -59,6 +59,7 @@ struct jfields ...@@ -59,6 +59,7 @@ struct jfields
jmethodID tostring; jmethodID tostring;
jmethodID get_codec_count, get_codec_info_at, is_encoder, get_capabilities_for_type; jmethodID get_codec_count, get_codec_info_at, is_encoder, get_capabilities_for_type;
jfieldID profile_levels_field, profile_field, level_field; jfieldID profile_levels_field, profile_field, level_field;
jmethodID get_video_capabilities, is_size_supported;
jmethodID get_supported_types, get_name; jmethodID get_supported_types, get_name;
jmethodID create_by_codec_name, configure, start, stop, flush, release; jmethodID create_by_codec_name, configure, start, stop, flush, release;
jmethodID get_output_format; jmethodID get_output_format;
...@@ -117,7 +118,10 @@ static const struct member members[] = { ...@@ -117,7 +118,10 @@ static const struct member members[] = {
{ "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", "android/media/MediaCodecInfo$CodecCapabilities", OFF(profile_levels_field), FIELD, true }, { "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 }, { "profile", "I", "android/media/MediaCodecInfo$CodecProfileLevel", OFF(profile_field), FIELD, true },
{ "level", "I", "android/media/MediaCodecInfo$CodecProfileLevel", OFF(level_field), FIELD, true }, { "level", "I", "android/media/MediaCodecInfo$CodecProfileLevel", OFF(level_field), FIELD, true },
{ "getVideoCapabilities", "()Landroid/media/MediaCodecInfo$VideoCapabilities;",
"android/media/MediaCodecInfo$CodecCapabilities", OFF(get_video_capabilities), METHOD, false },
{ "isSizeSupported", "(II)Z",
"android/media/MediaCodecInfo$VideoCapabilities", OFF(is_size_supported), METHOD, false },
{ "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", "android/media/MediaCodec", OFF(create_by_codec_name), STATIC_METHOD, true }, { "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", "android/media/MediaCodec", OFF(create_by_codec_name), STATIC_METHOD, true },
{ "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", "android/media/MediaCodec", OFF(configure), METHOD, true }, { "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", "android/media/MediaCodec", OFF(configure), METHOD, true },
{ "start", "()V", "android/media/MediaCodec", OFF(start), METHOD, true }, { "start", "()V", "android/media/MediaCodec", OFF(start), METHOD, true },
...@@ -309,7 +313,8 @@ struct mc_api_sys ...@@ -309,7 +313,8 @@ struct mc_api_sys
* MediaCodec_GetName * MediaCodec_GetName
*****************************************************************************/ *****************************************************************************/
char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime, char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
size_t h264_profile) size_t h264_profile, unsigned int i_width,
unsigned int i_height)
{ {
JNIEnv *env; JNIEnv *env;
int num_codecs; int num_codecs;
...@@ -333,6 +338,7 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime, ...@@ -333,6 +338,7 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
for (int i = 0; i < num_codecs; i++) for (int i = 0; i < num_codecs; i++)
{ {
jobject codec_capabilities = NULL; jobject codec_capabilities = NULL;
jobject video_capabilities = NULL;
jobject profile_levels = NULL; jobject profile_levels = NULL;
jobject info = NULL; jobject info = NULL;
jobject name = NULL; jobject name = NULL;
...@@ -368,6 +374,23 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime, ...@@ -368,6 +374,23 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
profile_levels = (*env)->GetObjectField(env, codec_capabilities, jfields.profile_levels_field); profile_levels = (*env)->GetObjectField(env, codec_capabilities, jfields.profile_levels_field);
if (profile_levels) if (profile_levels)
profile_levels_len = (*env)->GetArrayLength(env, profile_levels); profile_levels_len = (*env)->GetArrayLength(env, profile_levels);
if (i_width != 0 && i_height != 0 && jfields.get_video_capabilities && jfields.is_size_supported)
{
video_capabilities = (*env)->CallObjectMethod(env, codec_capabilities,
jfields.get_video_capabilities);
if (video_capabilities)
{
if ( !(*env)->CallBooleanMethod(env, video_capabilities,
jfields.is_size_supported,
i_width, i_height))
{
msg_Err(p_obj, "Video size %d * %d not supported",
i_width, i_height);
goto loopclean;
}
}
}
} }
msg_Dbg(p_obj, "Number of profile levels: %d", profile_levels_len); msg_Dbg(p_obj, "Number of profile levels: %d", profile_levels_len);
...@@ -433,6 +456,8 @@ loopclean: ...@@ -433,6 +456,8 @@ loopclean:
(*env)->DeleteLocalRef(env, codec_capabilities); (*env)->DeleteLocalRef(env, codec_capabilities);
if (info) if (info)
(*env)->DeleteLocalRef(env, info); (*env)->DeleteLocalRef(env, info);
if (video_capabilities)
(*env)->DeleteLocalRef(env, video_capabilities);
if (found) if (found)
break; break;
} }
...@@ -943,11 +968,12 @@ static void Clean(mc_api *api) ...@@ -943,11 +968,12 @@ static void Clean(mc_api *api)
/***************************************************************************** /*****************************************************************************
* Configure * Configure
*****************************************************************************/ *****************************************************************************/
static int Configure(mc_api *api, size_t i_h264_profile) static int Configure(mc_api *api, size_t i_h264_profile, unsigned int i_width,
unsigned int i_height)
{ {
free(api->psz_name); free(api->psz_name);
api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime, api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime,
i_h264_profile); i_h264_profile, i_width, i_height);
if (!api->psz_name) if (!api->psz_name)
return MC_API_ERROR; return MC_API_ERROR;
api->i_quirks = OMXCodec_GetQuirks(api->i_cat, api->i_codec, api->psz_name, api->i_quirks = OMXCodec_GetQuirks(api->i_cat, api->i_codec, api->psz_name,
......
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
#include "mediacodec.h" #include "mediacodec.h"
char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime, char* MediaCodec_GetName(vlc_object_t *, const char *, size_t,
size_t h264_profile); unsigned int, unsigned int);
#define THREAD_NAME "mediacodec_ndk" #define THREAD_NAME "mediacodec_ndk"
...@@ -564,11 +564,12 @@ static void Clean(mc_api *api) ...@@ -564,11 +564,12 @@ static void Clean(mc_api *api)
/***************************************************************************** /*****************************************************************************
* Configure * Configure
*****************************************************************************/ *****************************************************************************/
static int Configure(mc_api * api, size_t i_h264_profile) static int Configure(mc_api * api, size_t i_h264_profile, unsigned int i_width,
unsigned int i_height)
{ {
free(api->psz_name); free(api->psz_name);
api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime, api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime,
i_h264_profile); i_h264_profile, i_width, i_height);
if (!api->psz_name) if (!api->psz_name)
return MC_API_ERROR; return MC_API_ERROR;
api->i_quirks = OMXCodec_GetQuirks(api->i_cat, api->i_codec, api->psz_name, api->i_quirks = OMXCodec_GetQuirks(api->i_cat, api->i_codec, api->psz_name,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment