[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