Skip to content

Commit f971951

Browse files
committed
decoder: Default to valid profiles when demuxer reports unknown profile
When FFmpeg's demuxer reports an invalid or unknown profile (e.g., profile=0 for raw .265/.264 files without container metadata, or mis-tagged Baseline for interlaced H.264), default to a safe profile: H.264: Default to HIGH (100) -- superset of Baseline/Main, handles interlaced, CABAC, B-slices, weighted prediction. Matches NVCUVID. H.265: Default to MAIN (1) -- covers most 8-bit 4:2:0 content. AV1: Default to MAIN (0). The fix is in FFmpegDemuxer::GetProfileIdc() so it covers both VulkanVideoProcessor::Initialize() and VkVideoDecoder::StartVideoSequence() code paths. A warning is printed when a default is used. Additionally, VkVideoDecoder::StartVideoSequence() retries with upgraded profiles (Baseline→Main→High for H.264, Main→Main10 for H.265) if the initial capabilities query fails, as a second line of defense when the parser-reported profile differs from the demuxer. Fixes: Assert on 1080i-25-H264.mkv (interlaced Baseline) Fixes: Assert on 2024-05-03_14-55-55_1080p_p1_vbv2_5Mbps.265 (raw H.265) Signed-off-by: Tony Zlatinski <tzlatinski@nvidia.com>
1 parent 90ceee6 commit f971951

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

vk_video_decoder/libs/VkDecoderUtils/FFmpegDemuxer.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,12 @@ class FFmpegDemuxer : public VideoStreamDemuxer {
404404
case STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE:
405405
break;
406406
default:
407-
std::cerr << "\nInvalid h.264 profile: " << profile << std::endl;
407+
// Unknown/invalid H.264 profile from FFmpeg (e.g., profile=0 for
408+
// some streams). Default to High which is a superset of all lower
409+
// profiles and handles Baseline/Main/interlaced content correctly.
410+
std::cerr << "WARNING: Unknown H.264 profile_idc=" << profile
411+
<< " from demuxer, defaulting to HIGH (100)" << std::endl;
412+
return STD_VIDEO_H264_PROFILE_IDC_HIGH;
408413
}
409414
}
410415
break;
@@ -418,7 +423,11 @@ class FFmpegDemuxer : public VideoStreamDemuxer {
418423
case STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS:
419424
break;
420425
default:
421-
std::cerr << "\nInvalid h.265 profile: " << profile << std::endl;
426+
// Unknown/invalid H.265 profile from FFmpeg (e.g., profile=0 for
427+
// raw .265 files without container metadata). Default to Main.
428+
std::cerr << "WARNING: Unknown H.265 profile_idc=" << profile
429+
<< " from demuxer, defaulting to MAIN (1)" << std::endl;
430+
return STD_VIDEO_H265_PROFILE_IDC_MAIN;
422431
}
423432
}
424433
break;
@@ -430,7 +439,9 @@ class FFmpegDemuxer : public VideoStreamDemuxer {
430439
case STD_VIDEO_AV1_PROFILE_PROFESSIONAL:
431440
break;
432441
default:
433-
std::cerr << "\nInvalid AV1 profile: " << profile << std::endl;
442+
std::cerr << "WARNING: Unknown AV1 profile=" << profile
443+
<< " from demuxer, defaulting to MAIN (0)" << std::endl;
444+
return STD_VIDEO_AV1_PROFILE_MAIN;
434445
}
435446
}
436447
break;

vk_video_decoder/libs/VkVideoDecoder/VkVideoDecoder.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,35 @@ int32_t VkVideoDecoder::StartVideoSequence(VkParserDetectedVideoFormat* pVideoFo
210210
}
211211
}
212212
}
213+
if (result != VK_SUCCESS && videoCodec == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) {
214+
// The reported H.265 profile may be invalid (e.g., FFmpeg reports profile=0
215+
// for some streams, which maps to an invalid StdVideoH265ProfileIdc).
216+
// Try Main and Main10 which cover the vast majority of H.265 content.
217+
static constexpr uint32_t h265ProfileUpgradePath[] = {
218+
STD_VIDEO_H265_PROFILE_IDC_MAIN,
219+
STD_VIDEO_H265_PROFILE_IDC_MAIN_10,
220+
};
221+
for (uint32_t upgradedProfile : h265ProfileUpgradePath) {
222+
std::cerr << "WARNING: H.265 profile_idc=" << pVideoFormat->codecProfile
223+
<< " capabilities query failed (result=" << result
224+
<< "). Retrying with profile_idc=" << upgradedProfile << std::endl;
225+
226+
videoProfile = VkVideoCoreProfile(videoCodec,
227+
pVideoFormat->chromaSubsampling,
228+
pVideoFormat->lumaBitDepth,
229+
pVideoFormat->chromaBitDepth,
230+
upgradedProfile);
231+
232+
result = VulkanVideoCapabilities::GetVideoDecodeCapabilities(m_vkDevCtx, videoProfile,
233+
videoCapabilities,
234+
videoDecodeCapabilities);
235+
if (result == VK_SUCCESS) {
236+
std::cerr << "WARNING: H.265 profile upgraded to profile_idc="
237+
<< upgradedProfile << " successfully." << std::endl;
238+
break;
239+
}
240+
}
241+
}
213242
if (result != VK_SUCCESS) {
214243
std::cout << "*** Could not get Video Capabilities :" << result << " ***" << std::endl;
215244
assert(!"Could not get Video Capabilities!");

0 commit comments

Comments
 (0)