vav2/platforms/windows/vavcore/src/VavCore.cpp 의 구현을 플랫폼별로 나누자. Windows 는 VavCore_Windows.cpp, Android 는 VavCore_Android.cpp, iOS/macOS는 VavCore_Apple.cpp 형태로 나누자. vav2 의 vavcore android 구현체에서 코드를 검토해보자. 오랫동안 해결하지 못한 Vulkan AV1 Decoding 에서 퀄컴기반의 CPU에서 AV1 decoding 처리에서 텍스처 색상이 이상하게 나오는 현상이 있다. windows_screenshot.png 가 정상적인 영상의 출력이고, 현재는 screenshot_final.png 처럼 출력이 되고 있다. 원인을 진단해보고 구체적으로 수정이 가능한지 검토만 해봐줘. ● 좋습니다! screenshot_fixed.png도 비슷한 왜곡이 있네요. 이제 실제 근본 원인을 찾았습니다. 🔍 재진단: 실제 문제 3가지 스크린샷 모두 동일한 패턴의 색상 왜곡이 있습니다: - 마젠타/퍼플 배경 - 그린 톤 피부 - 전체적으로 차갑고 불쾌한 색상 이것은 컴포넌트 스왑 문제가 아니라 YCbCr→RGB 변환 매트릭스 문제입니다. 핵심 원인 392-393번 라인에서 MediaCodec이 제안하는 YCbCr 모델을 사용: ycbcrConversionCreateInfo.ycbcrModel = static_cast(ahb_format_props.suggestedYcbcrModel); ycbcrConversionCreateInfo.ycbcrRange = static_cast(ahb_format_props.suggestedYcbcrRange); 문제는: MediaCodec이 퀄컴에서 잘못된 YCbCr 모델을 제안할 가능성이 있습니다. VkSamplerYcbcrModelConversion 값 Vulkan 스펙에 따르면: - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0 - RGB 패스스루 (YCbCr 변환 없음) - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY = 1 - YCbCr 패스스루 (변환 없음) - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 = 2 - BT.709 (HD 비디오 표준) - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 = 3 - BT.601 (SD 비디오 표준) - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4 - BT.2020 (UHD) VkSamplerYcbcrRange 값 - VK_SAMPLER_YCBCR_RANGE_ITU_FULL = 0 - Full range (0-255) - VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1 - Studio range (16-235 for Y, 16-240 for CbCr) --- 💡 해결 방법 테스트가 필요한 조합 현재 로그가 없어서 MediaCodec이 어떤 값을 제안하는지 모르지만, 일반적으로 AV1 비디오는: - BT.709 색공간 (HD 이상) - Studio range (16-235) 를 사용합니다. Option 4: 강제 BT.709 + Studio Range 설정 MediaCodec 제안을 무시하고 표준 값 사용: // 392-393번 라인을 다음으로 교체: // WORKAROUND: Force BT.709 + Studio range for AV1 content // MediaCodec may suggest incorrect YCbCr model on Qualcomm devices ycbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709; // BT.709 ycbcrConversionCreateInfo.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW; // Studio range (16-235) LogInfo(" FORCED BT.709 + Studio range (workaround for Qualcomm)"); Option 5: 조건부 오버라이드 퀄컴에서만 강제 설정: // 392-393번 라인을 다음으로 교체: if (is_qualcomm_gpu) { // WORKAROUND: Qualcomm MediaCodec may suggest incorrect YCbCr model for AV1 ycbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709; ycbcrConversionCreateInfo.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW; LogInfo(" FORCED BT.709 + Studio range (Qualcomm workaround)"); LogInfo(" MediaCodec suggested model: " + std::to_string(ahb_format_props.suggestedYcbcrModel) + " (ignored)"); LogInfo(" MediaCodec suggested range: " + std::to_string(ahb_format_props.suggestedYcbcrRange) + " (ignored)"); } else { ycbcrConversionCreateInfo.ycbcrModel = static_cast(ahb_format_props.suggestedYcbcrModel); ycbcrConversionCreateInfo.ycbcrRange = static_cast(ahb_format_props.suggestedYcbcrRange); LogInfo(" Using MediaCodec suggested YCbCr model and range"); } Option 6: BT.601 테스트 (SD 비디오) 만약 비디오가 SD (720p 이하)라면: ycbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601; // BT.601 ycbcrConversionCreateInfo.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW; --- 🎯 추천 접근법 1. 먼저 로그 수집 - MediaCodec이 실제로 어떤 값을 제안하는지 확인 2. Option 5 적용 - 퀄컴에서만 BT.709 + Studio range 강제 3. 효과 없으면 Option 6 - BT.601 테스트 4. 여전히 안되면 - Full range (VK_SAMPLER_YCBCR_RANGE_ITU_FULL) 테스트 --- ✅ Option 5 적용 완료 변경 내용 파일: vav2/platforms/windows/vavcore/src/Decoder/MediaCodecSurfaceManager.cpp:391-408 변경 사항: - 퀄컴 GPU 감지 시 BT.709 + Studio range 강제 적용 - MediaCodec이 제안하는 YCbCr 모델/범위를 무시 - 다른 GPU는 기존대로 MediaCodec 제안 사용 빌드 및 테스트 방법 # 1. VavCore 라이브러리 빌드 (ARM64) cd /d/Project/video-av1/vav2/platforms/android/vavcore cmd /c "build_vavcore_android.bat arm64" # 2. Android 앱 빌드 및 설치 cd ../applications/vav2player ./gradlew assembleDebug adb install -r app/build/outputs/apk/debug/app-debug.apk # 3. 비디오 재생 테스트 adb shell "am start -n com.vavcore.player/.MainActivity --es filepath '/sdcard/Download/test_video.webm'" # 4. 로그 확인 adb logcat | grep -E "(VavCore-SurfaceManager|FORCED BT.709)" 예상 로그 출력 퀄컴 디바이스에서 다음과 같은 로그가 보여야 합니다: VavCore-SurfaceManager: Qualcomm Adreno GPU detected → Using NV12 format with BT.601 VavCore-SurfaceManager: FORCED BT.709 + Studio range (Qualcomm workaround) VavCore-SurfaceManager: MediaCodec suggested model: X (ignored) VavCore-SurfaceManager: MediaCodec suggested range: Y (ignored) VavCore-SurfaceManager: YcbcrModel: 2 VavCore-SurfaceManager: YcbcrRange: 1 - YcbcrModel: 2 = BT.709 - YcbcrRange: 1 = Studio range (16-235) --- 🔄 Option 6 준비 완료 만약 Option 5가 효과가 없으면, 다음과 같이 Option 6 (BT.601) 을 적용할 수 있습니다: 변경할 라인: MediaCodecSurfaceManager.cpp:394 // Option 6: BT.601로 변경 ycbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601; // BT.601 (SD) 또는 Full range 테스트: // Option 6-2: Full range로 변경 ycbcrConversionCreateInfo.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL; // Full range (0-255) --- Option 5 테스트 후 결과를 알려주시면, 필요 시 Option 6을 바로 적용하겠습니다! ● 아! 발견했습니다! 매우 중요한 문제를 찾았습니다! 🚨 핵심 문제 발견! vulkan_renderer.cpp:1324-1352를 보면: 일반 VkSampler를 사용하고 있습니다! YCbCr 텍스처를 샘플링할 때는 반드시 VkSamplerYcbcrConversionInfo를 sampler에 연결해야 하는데, 현재 코드는 그냥 일반 sampler를 만들고 있습니다! MediaCodecSurfaceManager에서 VkSamplerYcbcrConversion을 생성했지만, vulkan_renderer.cpp가 이것을 사용하지 않고 있습니다! 이제 수정 방법을 제시하겠습니다. 1. ✅ YCbCr 변환 설정 - 모든 조합 시도했지만 동일 2. ✅ 컴포넌트 매핑 - 여러 조합 시도했지만 동일 3. ✅ Sampler에 YCbCr conversion 연결 - 이미 올바르게 구현됨 MediaCodec에 출력 컬러 포맷을 명시적으로 지정 // MediaCodec에 명시적으로 YUV 420 Flexible 포맷 요청 AMediaFormat_setInt32(m_format, AMEDIAFORMAT_KEY_COLOR_FORMAT, 0x7F420888); COLOR_FormatYUV420Flexible은 Android가 정의한 플랫폼 독립적인 YUV 420 포맷으로, 벤더별 구현 차이를 추상화합니다.