[vlc-commits] mediacodec: check hevc profile
Thomas Guillem
git at videolan.org
Tue Jan 2 15:58:57 CET 2018
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Tue Jan 2 15:17:56 2018 +0100| [cff846218769cd0b52b81b212e056496bda618cb] | committer: Thomas Guillem
mediacodec: check hevc profile
Fail if the profile is not supported. This fixes HEVC 10bits sw fallback when
HW can only do HEVC Main.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=cff846218769cd0b52b81b212e056496bda618cb
---
modules/codec/omxil/mediacodec.c | 33 +++++++++++++++++++++------------
modules/codec/omxil/mediacodec.h | 2 +-
modules/codec/omxil/mediacodec_jni.c | 30 +++++++++++++++++++++++-------
modules/codec/omxil/mediacodec_ndk.c | 6 +++---
4 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c
index 61ff2d6b4f..21f5961e07 100644
--- a/modules/codec/omxil/mediacodec.c
+++ b/modules/codec/omxil/mediacodec.c
@@ -522,7 +522,7 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys;
int i_ret;
- size_t i_h264_profile = 0;
+ int i_profile = p_dec->fmt_in.i_profile;
const char *mime = NULL;
/* Video or Audio if "mediacodec-audio" bool is true */
@@ -543,8 +543,24 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
return VLC_EGENERIC;
switch (p_dec->fmt_in.i_codec) {
- case VLC_CODEC_HEVC: mime = "video/hevc"; break;
- case VLC_CODEC_H264: mime = "video/avc"; break;
+ case VLC_CODEC_HEVC:
+ if (i_profile == -1)
+ {
+ uint8_t i_hevc_profile;
+ if (hevc_get_profile_level(&p_dec->fmt_in, &i_hevc_profile, NULL, NULL))
+ i_profile = i_hevc_profile;
+ }
+ mime = "video/hevc";
+ break;
+ case VLC_CODEC_H264:
+ if (i_profile == -1)
+ {
+ uint8_t i_h264_profile;
+ if (h264_get_profile_level(&p_dec->fmt_in, &i_h264_profile, NULL, NULL))
+ i_profile = i_h264_profile;
+ }
+ mime = "video/avc";
+ break;
case VLC_CODEC_H263: mime = "video/3gpp"; break;
case VLC_CODEC_MP4V: mime = "video/mp4v-es"; break;
case VLC_CODEC_WMV3: mime = "video/x-ms-wmv"; break;
@@ -599,26 +615,19 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
p_sys->api.i_cat = p_dec->fmt_in.i_cat;
p_sys->api.psz_mime = mime;
- if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
- {
- uint8_t i_profile;
- if (h264_get_profile_level(&p_dec->fmt_in, &i_profile, NULL, NULL))
- i_h264_profile = i_profile;
- }
-
if (pf_init(&p_sys->api) != 0)
{
free(p_sys);
return VLC_EGENERIC;
}
- if (p_sys->api.configure(&p_sys->api, i_h264_profile) != 0)
+ if (p_sys->api.configure(&p_sys->api, i_profile) != 0)
{
/* If the device can't handle video/wvc1,
* it can probably handle video/x-ms-wmv */
if (!strcmp(mime, "video/wvc1") && p_dec->fmt_in.i_codec == VLC_CODEC_VC1)
{
p_sys->api.psz_mime = "video/x-ms-wmv";
- if (p_sys->api.configure(&p_sys->api, i_h264_profile) != 0)
+ if (p_sys->api.configure(&p_sys->api, i_profile) != 0)
{
p_sys->api.clean(&p_sys->api);
free(p_sys);
diff --git a/modules/codec/omxil/mediacodec.h b/modules/codec/omxil/mediacodec.h
index 3c2ff397e6..628a3a022d 100644
--- a/modules/codec/omxil/mediacodec.h
+++ b/modules/codec/omxil/mediacodec.h
@@ -125,7 +125,7 @@ struct mc_api
bool b_direct_rendering;
void (*clean)(mc_api *);
- int (*configure)(mc_api *, size_t i_h264_profile);
+ int (*configure)(mc_api *, int i_profile);
int (*start)(mc_api *, union mc_api_args *p_args);
int (*stop)(mc_api *);
int (*flush)(mc_api *);
diff --git a/modules/codec/omxil/mediacodec_jni.c b/modules/codec/omxil/mediacodec_jni.c
index 2fb341a9ea..9752193dcd 100644
--- a/modules/codec/omxil/mediacodec_jni.c
+++ b/modules/codec/omxil/mediacodec_jni.c
@@ -34,11 +34,12 @@
#include <OMX_Core.h>
#include <OMX_Component.h>
#include "omxil_utils.h"
+#include "../../packetizer/hevc_nal.h"
#include "mediacodec.h"
char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
- size_t h264_profile, bool *p_adaptive);
+ int profile, bool *p_adaptive);
#define THREAD_NAME "mediacodec_jni"
@@ -310,7 +311,7 @@ struct mc_api_sys
* MediaCodec_GetName
*****************************************************************************/
char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
- size_t h264_profile, bool *p_adaptive)
+ int profile, bool *p_adaptive)
{
JNIEnv *env;
int num_codecs;
@@ -395,7 +396,7 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
/* The mime type is matching for this component. We
now check if the capabilities of the codec is
matching the video format. */
- if (h264_profile)
+ if (profile > 0)
{
/* This decoder doesn't expose its profiles and is high
* profile capable */
@@ -407,9 +408,24 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
jobject profile_level = (*env)->GetObjectArrayElement(env, profile_levels, i);
int omx_profile = (*env)->GetIntField(env, profile_level, jfields.profile_field);
- size_t codec_profile = convert_omx_to_profile_idc(omx_profile);
(*env)->DeleteLocalRef(env, profile_level);
- if (codec_profile != h264_profile)
+
+ int codec_profile = 0;
+ if (strcmp(psz_mime, "video/avc") == 0)
+ codec_profile = convert_omx_to_profile_idc(omx_profile);
+ else if (strcmp(psz_mime, "video/hevc") == 0)
+ {
+ switch (omx_profile)
+ {
+ case 0x1: /* OMX_VIDEO_HEVCProfileMain */
+ codec_profile = HEVC_PROFILE_MAIN;
+ break;
+ case 0x2: /* OMX_VIDEO_HEVCProfileMain10 */
+ codec_profile = HEVC_PROFILE_MAIN_10;
+ break;
+ }
+ }
+ if (codec_profile != profile)
continue;
/* Some encoders set the level too high, thus we ignore it for the moment.
We could try to guess the actual profile based on the resolution. */
@@ -961,12 +977,12 @@ static void Clean(mc_api *api)
/*****************************************************************************
* Configure
*****************************************************************************/
-static int Configure(mc_api *api, size_t i_h264_profile)
+static int Configure(mc_api *api, int i_profile)
{
free(api->psz_name);
bool b_adaptive;
api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime,
- i_h264_profile, &b_adaptive);
+ i_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,
diff --git a/modules/codec/omxil/mediacodec_ndk.c b/modules/codec/omxil/mediacodec_ndk.c
index 254a9a41fe..3d782252e5 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, bool *p_adaptive);
+ int hxxx_profile, bool *p_adaptive);
#define THREAD_NAME "mediacodec_ndk"
@@ -603,12 +603,12 @@ static void Clean(mc_api *api)
/*****************************************************************************
* Configure
*****************************************************************************/
-static int Configure(mc_api * api, size_t i_h264_profile)
+static int Configure(mc_api * api, int i_profile)
{
free(api->psz_name);
bool b_adaptive;
api->psz_name = MediaCodec_GetName(api->p_obj, api->psz_mime,
- i_h264_profile, &b_adaptive);
+ i_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,
More information about the vlc-commits
mailing list