[vlc-commits] codec: videotoolbox: always check device capabilities
Thomas Guillem
git at videolan.org
Thu Sep 28 11:10:43 CEST 2017
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Sep 28 11:06:19 2017 +0200| [41ce842d1cdfcbc3c76952f7e999598f5444e309] | committer: Thomas Guillem
codec: videotoolbox: always check device capabilities
The H264 profile/level check was only done for avcC content and not when a new
SPS/PPS was parsed.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=41ce842d1cdfcbc3c76952f7e999598f5444e309
---
modules/codec/videotoolbox.m | 129 +++++++++++++++++++++++--------------------
1 file changed, 70 insertions(+), 59 deletions(-)
diff --git a/modules/codec/videotoolbox.m b/modules/codec/videotoolbox.m
index 8fa4904d52..1267930716 100644
--- a/modules/codec/videotoolbox.m
+++ b/modules/codec/videotoolbox.m
@@ -468,69 +468,14 @@ static void OnDecodedFrame(decoder_t *p_dec, frame_info_t *p_info)
InsertIntoDPB(p_sys, p_info);
}
-static CMVideoCodecType CodecPrecheck(decoder_t *p_dec, int *p_cvpx_chroma)
+static CMVideoCodecType CodecPrecheck(decoder_t *p_dec)
{
decoder_sys_t *p_sys = p_dec->p_sys;
/* check for the codec we can and want to decode */
switch (p_dec->fmt_in.i_codec) {
case VLC_CODEC_H264:
- {
- uint8_t i_profile, i_level;
- if (!h264_get_profile_level(&p_dec->fmt_in, &i_profile, &i_level, NULL))
- {
- msg_Warn(p_dec, "H264 profile and level parsing failed because it didn't arrive yet");
- return kCMVideoCodecType_H264;
- }
-
- msg_Dbg(p_dec, "trying to decode MPEG-4 Part 10: profile %" PRIx8 ", level %" PRIx8, i_profile, i_level);
-
- switch (i_profile) {
- case PROFILE_H264_BASELINE:
- case PROFILE_H264_MAIN:
- case PROFILE_H264_HIGH:
- break;
-
- case PROFILE_H264_HIGH_10:
- {
- if (deviceSupportsAdvancedProfiles())
- {
- /* FIXME: There is no YUV420 10bits chroma. The
- * decoder seems to output RGBA when decoding 10bits
- * content, but there is an unknown crash when
- * displaying such output, so force NV12 for now. */
- *p_cvpx_chroma =
- kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
- break;
- }
- }
-
- default:
- {
- msg_Dbg(p_dec, "unsupported H264 profile %" PRIx8, i_profile);
- return -1;
- }
- }
-
-#if !TARGET_OS_IPHONE
- /* a level higher than 5.2 was not tested, so don't dare to
- * try to decode it*/
- if (i_level > 52) {
- msg_Dbg(p_dec, "unsupported H264 level %" PRIx8, i_level);
- return -1;
- }
-#else
- /* on SoC A8, 4.2 is the highest specified profile */
- if (i_level > 42) {
- /* on Twister, we can do up to 5.2 */
- if (!deviceSupportsAdvancedLevels() || i_level > 52) {
- msg_Dbg(p_dec, "unsupported H264 level %" PRIx8, i_level);
- return -1;
- }
- }
-#endif
return kCMVideoCodecType_H264;
- }
case VLC_CODEC_MP4V:
{
@@ -923,8 +868,8 @@ static int OpenDecoder(vlc_object_t *p_this)
/* check quickly if we can digest the offered data */
CMVideoCodecType codec;
- int codec_cvpx_chroma = 0;
- codec = CodecPrecheck(p_dec, &codec_cvpx_chroma);
+
+ codec = CodecPrecheck(p_dec);
if (codec == -1)
return VLC_EGENERIC;
@@ -966,7 +911,7 @@ static int OpenDecoder(vlc_object_t *p_this)
free(cvpx_chroma);
}
else
- p_sys->i_forced_cvpx_format = codec_cvpx_chroma;
+ p_dec->p_sys->i_forced_cvpx_format = 0;
h264_poc_context_init( &p_sys->pocctx );
vlc_mutex_init(&p_sys->lock);
@@ -1146,6 +1091,55 @@ static CFMutableDictionaryRef H264ExtradataInfoCreate(const struct hxxx_helper *
return extradataInfo;
}
+static bool IsH264ProfileLevelSupported(decoder_t *p_dec, uint8_t i_profile,
+ uint8_t i_level)
+{
+ switch (i_profile) {
+ case PROFILE_H264_BASELINE:
+ case PROFILE_H264_MAIN:
+ case PROFILE_H264_HIGH:
+ break;
+
+ case PROFILE_H264_HIGH_10:
+ {
+ if (deviceSupportsAdvancedProfiles())
+ {
+ /* FIXME: There is no YUV420 10bits chroma. The
+ * decoder seems to output RGBA when decoding 10bits
+ * content, but there is an unknown crash when
+ * displaying such output, so force NV12 for now. */
+ if (p_dec->p_sys->i_forced_cvpx_format == 0)
+ p_dec->p_sys->i_forced_cvpx_format =
+ kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
+ break;
+ }
+ else
+ {
+ msg_Err(p_dec, "current device doesn't support H264 10bits");
+ return false;
+ }
+ }
+
+ default:
+ {
+ msg_Warn(p_dec, "unknown H264 profile %" PRIx8, i_profile);
+ return false;
+ }
+ }
+
+ /* A level higher than 5.2 was not tested, so don't dare to try to decode
+ * it. On SoC A8, 4.2 is the highest specified profile. on Twister, we can
+ * do up to 5.2 */
+ if (i_level > 52 || (i_level > 42 && !deviceSupportsAdvancedLevels()))
+ {
+ msg_Err(p_dec, "current device doesn't support this H264 level: %"
+ PRIx8, i_level);
+ return false;
+ }
+
+ return true;
+}
+
static int SetH264DecoderInfo(decoder_t *p_dec, CFMutableDictionaryRef extradataInfo)
{
decoder_sys_t *p_sys = p_dec->p_sys;
@@ -1153,8 +1147,16 @@ static int SetH264DecoderInfo(decoder_t *p_dec, CFMutableDictionaryRef extradata
if (p_sys->hh.h264.i_sps_count == 0 || p_sys->hh.h264.i_pps_count == 0)
return VLC_EGENERIC;
+ uint8_t i_profile, i_level;
unsigned i_h264_width, i_h264_height, i_video_width, i_video_height;
int i_sar_num, i_sar_den, i_ret;
+
+ i_ret = h264_helper_get_current_profile_level(&p_sys->hh, &i_profile, &i_level);
+ if (i_ret != VLC_SUCCESS)
+ return i_ret;
+ if (!IsH264ProfileLevelSupported(p_dec, i_profile, i_level))
+ return VLC_ENOMOD; /* This error is critical */
+
i_ret = h264_helper_get_current_picture_size(&p_sys->hh,
&i_h264_width, &i_h264_height,
&i_video_width, &i_video_height);
@@ -1463,6 +1465,15 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_block)
msg_Dbg(p_dec, "Got SPS/PPS: late opening of H264 decoder");
StartVideoToolbox(p_dec);
}
+ else if (i_ret == VLC_ENOMOD)
+ {
+ /* The current device doesn't handle the h264 profile/level,
+ * abort */
+ vlc_mutex_lock(&p_sys->lock);
+ p_sys->vtsession_status = VTSESSION_STATUS_ABORT;
+ vlc_mutex_unlock(&p_sys->lock);
+ goto skip;
+ }
}
if (!p_sys->session)
More information about the vlc-commits
mailing list