Commit cff84621 authored by Thomas Guillem's avatar Thomas Guillem
Browse files

mediacodec: check hevc profile

Fail if the profile is not supported. This fixes HEVC 10bits sw fallback when
HW can only do HEVC Main.
parent 7eb0ce08
......@@ -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);
......
......@@ -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 *);
......
......@@ -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,
......
......@@ -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,
......
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