# VavCore Android MediaCodec 크로스 플랫폼 Graphics 통합 설계 ## 📋 **문서 정보** - **작성일**: 2025-09-27 - **버전**: 3.0.0 (완전한 크로스 플랫폼 Graphics API 통합) - **최신 업데이트**: Enhanced IVideoDecoder 인터페이스 및 VavCoreSurfaceType 시스템 - **대상**: VavCore Android MediaCodec AV1 Decoder + 크로스 플랫폼 Graphics - **목적**: Android의 다양한 Graphics API와 MediaCodec의 완전한 크로스 플랫폼 통합 ## 1. 개요 및 최신 변경사항 본 문서는 VavCore의 완전한 크로스 플랫폼 Graphics API 지원을 포함하여 Android MediaCodec API와의 통합 설계를 제시합니다. **주요 업데이트:** ### **🆕 v3.0 최신 기능 (2025-09-27) - 현실적인 AV1 하드웨어 지원 반영** - ✅ **완전한 크로스 플랫폼 Surface 시스템**: VavCoreSurfaceType 열거형으로 모든 플랫폼 지원 - ✅ **Enhanced IVideoDecoder 인터페이스**: 플랫폼별 Graphics API 설정 메서드 확장 - ⚠️ **현실적인 Android AV1 하드웨어 지원**: 2022년 이후 고급 SoC만 실제 지원 - ✅ **ANativeWindow 우선 지원**: MediaCodec Surface 디코딩의 가장 안정적인 방식 - ⚠️ **제한적인 고급 Graphics API**: OpenGL ES/Vulkan은 고급 SoC + API 29+에서만 - ✅ **정확한 하드웨어 감지**: 실제 AV1 지원 SoC 검증 로직 (Snapdragon 8 Gen 1+, Tensor G2+) - ✅ **Graceful Fallback**: 하드웨어 미지원 시 dav1d 소프트웨어 디코더로 안전한 전환 ### **⚠️ 중요: Android AV1 하드웨어 지원 현실** **실제 AV1 하드웨어 디코딩이 가능한 기기:** - **Qualcomm**: Snapdragon 8 Gen 1+ (2022년 이후) - Galaxy S22+, OnePlus 10+ - **Google**: Tensor G2+ (Pixel 7+, 2022년 이후) - **MediaTek**: Dimensity 9200+ (2023년 이후) - 일부 고급 기기만 - **Samsung**: Exynos 2200 (Galaxy S22 일부) - 제한적이고 불안정 **🎮 Godot 게임엔진 관점에서의 Surface 우선순위:** 1. **Vulkan VkImage** - Godot 4 Forward+/Mobile 렌더러와 직접 통합 2. **OpenGL ES 텍스처** - Godot 4 Compatibility 렌더러와 직접 통합 3. **ANativeWindow** - 추가 변환 필요, 게임엔진에 덜 적합 4. **CPU 메모리** - 호환성은 좋지만 성능 저하 **대부분의 Android 기기는 여전히 소프트웨어 디코딩 필요** ## 2. VavCore 크로스 플랫폼 아키텍처 분석 ### 2.1 하드웨어 디코더 팩토리 패턴 VavCore는 등록 기반 디코더 팩토리 시스템으로 모든 플랫폼의 하드웨어 가속을 지원합니다: **VideoDecoderFactory 디코더 우선순위:** ```cpp // AUTO 모드 우선순위: Platform-specific HW → dav1d SW enum class VideoCodecType { AV1, VP9, H264, H265 }; enum class DecoderType { AUTO, // 플랫폼별 최적 디코더 자동 선택 // Windows Hardware Decoders NVDEC, // NVIDIA NVDEC (Windows) VPL, // Intel VPL (Windows) AMF, // AMD AMF (Windows) MEDIA_FOUNDATION, // Windows Media Foundation // Android Hardware Decoders MEDIACODEC, // Android MediaCodec // Cross-platform Software DAV1D // dav1d 소프트웨어 (모든 플랫폼) }; ``` ### 2.2 Enhanced IVideoDecoder 크로스 플랫폼 인터페이스 현재 인터페이스는 모든 플랫폼의 Graphics API를 완전히 지원합니다: ```cpp class IVideoDecoder { public: // Core 디코딩 인터페이스 virtual bool Initialize(const VideoMetadata& metadata) = 0; virtual bool DecodeFrame(const VideoPacket& input_packet, VideoFrame& output_frame) = 0; virtual bool DecodeFrame(const uint8_t* packet_data, size_t packet_size, VideoFrame& output_frame) = 0; // 크로스 플랫폼 Surface 디코딩 virtual bool SupportsSurfaceType(VavCoreSurfaceType type) const = 0; virtual VavCoreSurfaceType GetOptimalSurfaceType() const = 0; virtual bool DecodeToSurface(const uint8_t* packet_data, size_t packet_size, VavCoreSurfaceType target_type, void* target_surface, VideoFrame& output_frame) = 0; // 플랫폼별 Graphics API 설정 // Windows virtual bool SetD3DDevice(void* d3d_device, VavCoreSurfaceType type) = 0; // Android virtual bool SetAndroidSurface(void* native_window) = 0; virtual bool SetOpenGLESContext(void* egl_context) = 0; virtual bool SetVulkanDevice(void* vk_device, void* vk_instance) = 0; // Cross-platform virtual bool SetOpenGLContext(void* gl_context) = 0; virtual bool SetMetalDevice(void* metal_device) = 0; // Graphics API 지원 감지 virtual bool SupportsHardwareAcceleration() const = 0; virtual bool SupportsZeroCopyDecoding() const = 0; virtual bool RequiresExternalContext() const = 0; }; ``` ### 2.3 VavCoreSurfaceType 크로스 플랫폼 시스템 현재 VavCore는 모든 주요 플랫폼의 Graphics API를 완전히 지원합니다: ```cpp typedef enum { VAVCORE_SURFACE_CPU = 0, // 전통적인 CPU 메모리 // Windows Graphics APIs VAVCORE_SURFACE_D3D11_TEXTURE = 1, // D3D11 texture (Windows) VAVCORE_SURFACE_D3D12_RESOURCE = 2, // D3D12 resource (Windows) VAVCORE_SURFACE_CUDA_DEVICE = 3, // CUDA device pointer (Windows) VAVCORE_SURFACE_AMF_SURFACE = 4, // AMF surface wrapper (Windows) // Android Graphics APIs VAVCORE_SURFACE_ANDROID_NATIVE_WINDOW = 5, // Android ANativeWindow VAVCORE_SURFACE_OPENGL_ES_TEXTURE = 6, // OpenGL ES texture (Android/iOS) VAVCORE_SURFACE_VULKAN_IMAGE = 7, // Vulkan VkImage (Android/Windows) VAVCORE_SURFACE_ANDROID_HARDWARE_BUFFER = 8, // AHardwareBuffer (Android) // Cross-platform APIs VAVCORE_SURFACE_OPENGL_TEXTURE = 9, // Desktop OpenGL texture VAVCORE_SURFACE_METAL_TEXTURE = 10, // Metal MTLTexture (iOS/macOS) VAVCORE_SURFACE_COREVIDEO_PIXELBUFFER = 11 // CVPixelBuffer (iOS/macOS) } VavCoreSurfaceType; ``` ### 2.4 하드웨어 디코더 공통 구현 패턴 **모든 플랫폼의 하드웨어 디코더 (NVDEC/AMF/VPL/MediaCodec) 공통 패턴:** 1. **하드웨어 감지**: GPU/SoC 하드웨어 가용성 자동 확인 2. **Graphics API 설정**: 플랫폼별 최적 Graphics API 초기화 3. **Surface 기반 디코딩**: Zero-copy를 위한 하드웨어 Surface 직접 렌더링 4. **Graceful Fallback**: 하드웨어 실패 시 소프트웨어 디코더로 자동 전환 5. **성능 최적화**: GPU-to-GPU 직접 전송으로 메모리 복사 제거 6. **리소스 관리**: 플랫폼별 하드웨어 리소스 적절한 해제 ## 3. Android MediaCodec 크로스 플랫폼 통합 설계 ### 3.1 플랫폼별 조건부 컴파일 전략 ```cpp // 플랫폼별 헤더 및 Graphics API 정의 #ifdef ANDROID #include #include #include #include #include #include #include #include #include #define VAVCORE_PLATFORM_ANDROID #elif defined(_WIN32) #include #include #include #include #include #define VAVCORE_PLATFORM_WINDOWS #elif defined(__APPLE__) #include #include #define VAVCORE_PLATFORM_APPLE #endif // VavCoreSurfaceType은 이제 enum으로 통합 관리 // 플랫폼별 void* 포인터로 실제 리소스 전달 ``` ### 3.2 AndroidMediaCodecAV1Decoder Enhanced 구현 #### 3.2.1 Enhanced 클래스 구조 (크로스 플랫폼 호환성) ```cpp namespace VavCore { class AndroidMediaCodecAV1Decoder : public IVideoDecoder { public: AndroidMediaCodecAV1Decoder(); virtual ~AndroidMediaCodecAV1Decoder(); // IVideoDecoder 기본 인터페이스 bool Initialize(const VideoMetadata& metadata) override; void Cleanup() override; bool IsInitialized() const override { return m_initialized; } // Core 디코딩 기능 bool DecodeFrame(const VideoPacket& input_packet, VideoFrame& output_frame) override; bool DecodeFrame(const uint8_t* packet_data, size_t packet_size, VideoFrame& output_frame) override; // 크로스 플랫폼 Surface 디코딩 (Enhanced) bool SupportsSurfaceType(VavCoreSurfaceType type) const override; VavCoreSurfaceType GetOptimalSurfaceType() const override; bool DecodeToSurface(const uint8_t* packet_data, size_t packet_size, VavCoreSurfaceType target_type, void* target_surface, VideoFrame& output_frame) override; // 플랫폼별 Graphics API 설정 (Android 특화) bool SetAndroidSurface(void* native_window) override; bool SetOpenGLESContext(void* egl_context) override; bool SetVulkanDevice(void* vk_device, void* vk_instance) override; // 다른 플랫폼 API는 지원하지 않음 (기본 구현) bool SetD3DDevice(void* d3d_device, VavCoreSurfaceType type) override { return false; } bool SetOpenGLContext(void* gl_context) override { return false; } bool SetMetalDevice(void* metal_device) override { return false; } // Graphics API 지원 감지 (Android 특화) bool SupportsHardwareAcceleration() const override; bool SupportsZeroCopyDecoding() const override; bool RequiresExternalContext() const override; // 디코더 상태 관리 bool Reset() override; bool Flush() override; // 디코더 정보 std::string GetCodecName() const override; VideoCodecType GetCodecType() const override { return VideoCodecType::AV1; } std::string GetVersion() const override; // 성능 및 통계 DecoderStats GetStats() const override; void ResetStats() override; // Android 레거시 호환성 (legacy) bool SetSurface(ANativeWindow* surface); // Legacy method bool IsHardwareAccelerated() const; // Legacy method std::string GetSelectedCodecName() const; private: // 초기화 및 설정 bool InitializeMediaCodec(); bool FindAV1Decoder(); AMediaCodec* CreateAV1Decoder(); bool ConfigureDecoder(const VideoMetadata& metadata); // 처리 로직 bool ProcessInputBuffer(const uint8_t* data, size_t size); bool ProcessOutputBuffer(VideoFrame& frame); // 하드웨어 가속 감지 (Enhanced) bool DetectHardwareCapabilities(); std::vector GetAvailableCodecs(); // 로깅 (크로스 플랫폼 호환성) void LogError(const std::string& message); void LogInfo(const std::string& message); void LogWarning(const std::string& message); private: // Core MediaCodec 객체 bool m_initialized; AMediaCodec* m_codec; AMediaFormat* m_format; ANativeWindow* m_surface; // 디코더 성능 정보 bool m_hardware_accelerated; std::string m_selected_codec_name; // 비디오 속성 int32_t m_width; int32_t m_height; // 버퍼 관리 std::vector m_input_buffer; int64_t m_timestamp_counter; // 성능 추적 (Enhanced) std::chrono::high_resolution_clock::time_point m_decode_start_time; }; } // namespace VavCore ``` #### 3.2.2 Android SoC별 하드웨어 감지 로직 (Enhanced) ```cpp bool AndroidMediaCodecAV1Decoder::DetectHardwareCapabilities() { // ⚠️ 현실적인 Android AV1 하드웨어 디코더 식별 (2025년 기준) // 대부분의 SoC는 AV1 하드웨어를 광고하지만 실제로는 2022년 이후에만 안정적 const char* hw_codec_prefixes[] = { // Qualcomm Snapdragon (8 Gen 1+ 시리즈만 실제 AV1 지원) "c2.qti.av1.decoder", // Qualcomm Codec 2.0 AV1 전용 "c2.qcom.av1.decoder", // Qualcomm 최신 AV1 전용 "OMX.qcom.video.decoder.av1", // Qualcomm OMX AV1 (레거시) // Google Tensor (G2+ 시리즈만 - Pixel 7+) "c2.android.av1.decoder", // Android Codec 2.0 AV1 (Google 하드웨어) "c2.google.av1.decoder", // Google Tensor 특화 AV1 // MediaTek Dimensity (9200+ 시리즈만 - 늦은 지원) "c2.mtk.av1.decoder", // MediaTek Codec 2.0 AV1 "OMX.MTK.VIDEO.DECODER.AV1", // MediaTek OMX AV1 // Samsung Exynos (매우 제한적 - 2200 일부만) "c2.exynos.av1.decoder", // Samsung Exynos AV1 (제한적) // ⚠️ 주의: 범용 프리픽스는 제외 // "OMX.qcom.", "c2.qti.", "c2.android." 등은 H.264/H.265도 포함하므로 // AV1 전용 디코더명만 검색하여 정확성 확보 nullptr }; auto available_codecs = GetAvailableCodecs(); // 하드웨어 디코더 우선순위 검색 for (const auto& codec : available_codecs) { for (int i = 0; hw_codec_prefixes[i] != nullptr; i++) { if (codec.find(hw_codec_prefixes[i]) == 0) { m_selected_codec_name = codec; m_hardware_accelerated = true; LogInfo("Hardware AV1 decoder detected: " + codec); return true; } } } // 소프트웨어 디코더로 graceful fallback LogWarning("No hardware AV1 decoder found, will fallback to software decoder"); m_hardware_accelerated = false; return false; } // Godot 게임엔진 최적화를 위한 Surface 타입 결정 VavCoreSurfaceType AndroidMediaCodecAV1Decoder::GetOptimalSurfaceType() const { if (!m_hardware_accelerated) { return VAVCORE_SURFACE_CPU; // 소프트웨어 디코더는 CPU만 지원 } // Android API Level 및 SoC별 AV1 하드웨어 지원 확인 int api_level = GetAndroidAPILevel(); std::string soc_name = GetSoCName(); // ⚠️ 중요: AV1 하드웨어 디코딩이 실제로 가능한 SoC인지 확인 if (!IsAV1HardwareCapableSoC(soc_name, api_level)) { LogWarning("SoC does not support AV1 hardware decoding, falling back to CPU"); return VAVCORE_SURFACE_CPU; } // 🎮 Godot 게임엔진 관점: 직접적인 Graphics API 통합이 최우선 // Godot 4는 Vulkan/OpenGL ES 기반 렌더링 시스템 사용 // 1. Vulkan 최우선 (Godot 4의 기본 렌더링 백엔드) // - Godot 4 Forward+ 및 Mobile 렌더링 메서드 // - Google과 협력하여 Android Vulkan 최적화 완료 if (api_level >= 29 && IsHighEndSoC(soc_name)) { // Android 10+ 고급 SoC if (SupportsVulkan11()) { LogInfo("Using Vulkan image for Godot 4 optimal integration"); return VAVCORE_SURFACE_VULKAN_IMAGE; } } // 2. OpenGL ES 텍스처 (Godot 4 Compatibility 렌더러) // - Godot 4 Compatibility 렌더링 메서드 (OpenGL ES 3.0) // - SurfaceTexture → GL_TEXTURE_EXTERNAL_OES → Godot 텍스처 // - 더 넓은 기기 호환성 if (api_level >= 21) { // Android 5.0+ (OpenGL ES 3.0) if (SupportsOpenGLES()) { LogInfo("Using OpenGL ES texture for Godot 4 Compatibility renderer"); return VAVCORE_SURFACE_OPENGL_ES_TEXTURE; } } // 3. ANativeWindow (제한적 사용 - 게임엔진에 덜 적합) // - MediaCodec Surface → ANativeWindow → Godot는 복잡한 통합 필요 // - Godot의 텍스처 시스템과 직접 연결되지 않음 // - 주로 비디오 플레이어 앱에서 사용하는 방식 if (api_level >= 18) { // MediaCodec Surface 지원 시작점 LogWarning("Using ANativeWindow - suboptimal for Godot integration"); return VAVCORE_SURFACE_ANDROID_NATIVE_WINDOW; } // 4. 기본값: CPU (안전한 fallback) LogWarning("No suitable Surface type found, falling back to CPU decoding"); return VAVCORE_SURFACE_CPU; } // Godot 통합을 위한 추가 메서드들 bool AndroidMediaCodecAV1Decoder::IsOptimalForGodot() const { VavCoreSurfaceType optimal = GetOptimalSurfaceType(); // Godot에 최적인 Surface 타입들 return (optimal == VAVCORE_SURFACE_VULKAN_IMAGE || optimal == VAVCORE_SURFACE_OPENGL_ES_TEXTURE); } std::string AndroidMediaCodecAV1Decoder::GetGodotIntegrationInfo() const { VavCoreSurfaceType surface_type = GetOptimalSurfaceType(); switch (surface_type) { case VAVCORE_SURFACE_VULKAN_IMAGE: return "Vulkan VkImage - Direct integration with Godot 4 Forward+/Mobile renderer"; case VAVCORE_SURFACE_OPENGL_ES_TEXTURE: return "OpenGL ES GL_TEXTURE_EXTERNAL_OES - Direct integration with Godot 4 Compatibility renderer"; case VAVCORE_SURFACE_ANDROID_NATIVE_WINDOW: return "ANativeWindow - Requires additional conversion for Godot texture system"; case VAVCORE_SURFACE_CPU: return "CPU memory - Software decoding, universally compatible but slower"; default: return "Unknown surface type"; } } // 실제 AV1 하드웨어 지원 SoC 검증 (현실적인 출시 시점 고려) bool AndroidMediaCodecAV1Decoder::IsAV1HardwareCapableSoC(const std::string& soc_name, int api_level) const { // ⚠️ 현실: 대부분의 Android SoC는 2022년 이후에야 실제 AV1 하드웨어 지원 // Qualcomm Snapdragon (8 Gen 1+ 시리즈만 확실한 지원) if (soc_name.find("sm8450") != std::string::npos || // 8 Gen 1 (2022) soc_name.find("sm8475") != std::string::npos || // 8+ Gen 1 (2022) soc_name.find("sm8550") != std::string::npos || // 8 Gen 2 (2023) soc_name.find("sm8650") != std::string::npos) { // 8 Gen 3 (2024) return api_level >= 31; // Android 12+ 필요 } // Google Tensor (G2+ 시리즈만 - Pixel 7+) if (soc_name.find("gs201") != std::string::npos || // Tensor G2 (Pixel 7, 2022) soc_name.find("gs301") != std::string::npos) { // Tensor G3 (Pixel 8, 2023) return api_level >= 31; // Android 12+ 필요 } // MediaTek Dimensity (9200+ 시리즈만 - 늦은 지원) if (soc_name.find("mt6985") != std::string::npos || // Dimensity 9200 (2023) soc_name.find("mt6989") != std::string::npos) { // Dimensity 9300 (2024) return api_level >= 33; // Android 13+ 필요 (MediaTek 늦은 지원) } // Samsung Exynos (매우 제한적 지원 - 2200 일부만) if (soc_name.find("s5e9925") != std::string::npos) { // Exynos 2200 (Galaxy S22) // Exynos 2200은 AV1 하드웨어가 있지만 성능 이슈로 제한적 활용 LogWarning("Exynos 2200 AV1 hardware support is limited and unstable"); return api_level >= 32; // Android 12L+ 필요 } // 기타 모든 SoC는 AV1 하드웨어 디코딩 미지원으로 간주 LogWarning("SoC " + soc_name + " not in confirmed AV1 hardware support list"); return false; } bool AndroidMediaCodecAV1Decoder::IsHighEndSoC(const std::string& soc_name) const { // Snapdragon 8 series if (soc_name.find("sm84") != std::string::npos || soc_name.find("sm86") != std::string::npos) { return true; } // Google Tensor if (soc_name.find("gs") != std::string::npos) { return true; } // MediaTek Dimensity 9xxx series if (soc_name.find("mt698") != std::string::npos) { return true; } return false; } ``` #### 3.2.3 크로스 플랫폼 Surface 기반 디코딩 (Enhanced) ```cpp bool AndroidMediaCodecAV1Decoder::DecodeToSurface(const uint8_t* packet_data, size_t packet_size, VavCoreSurfaceType target_type, void* target_surface, VideoFrame& output_frame) { if (!m_initialized || !m_hardware_accelerated) { LogError("AndroidMediaCodec decoder not initialized or hardware not available"); return false; } // Android에서 지원하는 Surface 타입 검증 if (!SupportsSurfaceType(target_type)) { LogError("Unsupported surface type for Android MediaCodec: " + std::to_string(target_type)); return false; } // Surface 타입별 처리 switch (target_type) { case VAVCORE_SURFACE_ANDROID_NATIVE_WINDOW: { auto* native_window = static_cast(target_surface); if (!SetAndroidSurface(native_window)) { LogError("Failed to set Android native window"); return false; } break; } case VAVCORE_SURFACE_OPENGL_ES_TEXTURE: { // OpenGL ES 텍스처로 직접 렌더링 // EGL 컨텍스트와 텍스처 ID가 필요 if (!m_opengl_es_context) { LogError("OpenGL ES context not set for texture rendering"); return false; } break; } case VAVCORE_SURFACE_VULKAN_IMAGE: { // Vulkan 이미지로 직접 렌더링 // VkDevice와 VkImage가 필요 if (!m_vulkan_device) { LogError("Vulkan device not set for image rendering"); return false; } break; } case VAVCORE_SURFACE_ANDROID_HARDWARE_BUFFER: { // AHardwareBuffer로 직접 렌더링 auto* hardware_buffer = static_cast(target_surface); if (!SetHardwareBuffer(hardware_buffer)) { LogError("Failed to set Android hardware buffer"); return false; } break; } default: LogError("Surface type not supported by Android MediaCodec"); return false; } // 입력 버퍼 처리 if (!ProcessInputBuffer(packet_data, packet_size)) { LogError("Failed to process input buffer"); return false; } // Zero-copy: 출력이 하드웨어 Surface로 직접 렌더링됨 // CPU 메모리 복사 없이 GPU-to-GPU 직접 전송 output_frame.surface_type = target_type; output_frame.surface_data.android_native.native_window = target_surface; output_frame.timestamp_us = m_timestamp_counter++; // 성능 통계 업데이트 IncrementFramesDecoded(); UpdateDecodeTime(CalculateDecodeTime()); LogInfo("Frame decoded directly to Android surface (zero-copy)"); return true; } // Android AV1 하드웨어 현실을 반영한 Surface 타입 지원 감지 bool AndroidMediaCodecAV1Decoder::SupportsSurfaceType(VavCoreSurfaceType type) const { int api_level = GetAndroidAPILevel(); std::string soc_name = GetSoCName(); switch (type) { case VAVCORE_SURFACE_CPU: return true; // 모든 Android 기기에서 지원 (소프트웨어 dav1d) case VAVCORE_SURFACE_ANDROID_NATIVE_WINDOW: // MediaCodec Surface 디코딩: API 18+에서 지원, AV1은 API 29+ 실용적 if (api_level >= 18 && m_hardware_accelerated) { return IsAV1HardwareCapableSoC(soc_name, api_level); } return false; case VAVCORE_SURFACE_OPENGL_ES_TEXTURE: // OpenGL ES 텍스처: 복잡한 MediaCodec 통합, 고급 SoC에서만 권장 if (api_level >= 29 && m_hardware_accelerated && IsHighEndSoC(soc_name)) { return SupportsOpenGLES() && IsAV1HardwareCapableSoC(soc_name, api_level); } return false; case VAVCORE_SURFACE_VULKAN_IMAGE: // Vulkan: API 24+에서 지원, AV1과 함께는 API 29+ 고급 SoC만 if (api_level >= 29 && m_hardware_accelerated && IsHighEndSoC(soc_name)) { return SupportsVulkan11() && IsAV1HardwareCapableSoC(soc_name, api_level); } return false; case VAVCORE_SURFACE_ANDROID_HARDWARE_BUFFER: // AHardwareBuffer: API 26+에서 지원, AV1과 함께는 API 31+ 권장 if (api_level >= 31 && m_hardware_accelerated && IsHighEndSoC(soc_name)) { return SupportsHardwareBuffer() && IsAV1HardwareCapableSoC(soc_name, api_level); } return false; // Android에서 지원하지 않는 플랫폼별 Surface 타입들 case VAVCORE_SURFACE_D3D11_TEXTURE: case VAVCORE_SURFACE_D3D12_RESOURCE: case VAVCORE_SURFACE_CUDA_DEVICE: case VAVCORE_SURFACE_AMF_SURFACE: case VAVCORE_SURFACE_OPENGL_TEXTURE: // Desktop OpenGL (Android는 ES만) case VAVCORE_SURFACE_METAL_TEXTURE: case VAVCORE_SURFACE_COREVIDEO_PIXELBUFFER: return false; default: return false; } } // Android API 및 Graphics API 지원 검증 메서드들 bool AndroidMediaCodecAV1Decoder::SupportsOpenGLES() const { // OpenGL ES는 모든 Android 기기에서 지원하지만, // MediaCodec과의 복잡한 통합은 고급 기기에서만 안정적 return GetAndroidAPILevel() >= 21; // Android 5.0+ (OpenGL ES 3.0) } bool AndroidMediaCodecAV1Decoder::SupportsVulkan11() const { // Vulkan 1.1은 API 29+에서 모든 64비트 기기에서 보장 return GetAndroidAPILevel() >= 29; } bool AndroidMediaCodecAV1Decoder::SupportsHardwareBuffer() const { // AHardwareBuffer는 API 26+에서 지원, 완전한 기능은 API 31+ return GetAndroidAPILevel() >= 31; } ``` ### 3.3 Enhanced VideoDecoderFactory 크로스 플랫폼 통합 #### 3.3.1 크로스 플랫폼 디코더 등록 및 우선순위 ```cpp // VideoDecoderFactory에서 플랫폼별 디코더 자동 등록 void VideoDecoderFactory::RegisterAV1Decoders() { // Windows 하드웨어 디코더들 #ifdef VAVCORE_PLATFORM_WINDOWS RegisterDecoder(VideoCodecType::AV1, DecoderType::NVDEC, []() -> std::unique_ptr { return std::make_unique(); }, 400); // 최고 우선순위 RegisterDecoder(VideoCodecType::AV1, DecoderType::VPL, []() -> std::unique_ptr { return std::make_unique(); }, 300); RegisterDecoder(VideoCodecType::AV1, DecoderType::AMF, []() -> std::unique_ptr { return std::make_unique(); }, 200); RegisterDecoder(VideoCodecType::AV1, DecoderType::MEDIA_FOUNDATION, []() -> std::unique_ptr { return std::make_unique(); }, 50); #endif // Android 하드웨어 디코더 #ifdef VAVCORE_PLATFORM_ANDROID RegisterDecoder(VideoCodecType::AV1, DecoderType::MEDIACODEC, []() -> std::unique_ptr { return std::make_unique(); }, 400); // Android에서 최고 우선순위 #endif // 크로스 플랫폼 소프트웨어 디코더 (모든 플랫폼에서 fallback) RegisterDecoder(VideoCodecType::AV1, DecoderType::DAV1D, []() -> std::unique_ptr { return std::make_unique(); }, 10); // 최하위 우선순위 (안전한 fallback) } // Enhanced AUTO 디코더 선택 로직 std::unique_ptr VideoDecoderFactory::CreateDecoder(VideoCodecType codec_type, DecoderType type) { switch (type) { case DecoderType::AUTO: { // 플랫폼별 최적 디코더 자동 선택 auto decoders = GetSortedDecoders(codec_type); // 우선순위 순서로 정렬 for (const auto& decoder_factory : decoders) { auto decoder = decoder_factory.create(); // 하드웨어 가용성 미리 확인 if (decoder->SupportsHardwareAcceleration()) { if (decoder->Initialize(GetDummyMetadata())) { decoder->Cleanup(); // 테스트 후 정리 LogInfo("Selected hardware decoder: " + decoder->GetCodecName()); return decoder_factory.create(); // 새 인스턴스 생성 } } } // 모든 하드웨어 디코더 실패 시 소프트웨어 fallback LogWarning("All hardware decoders failed, using software decoder"); return CreateDecoder(codec_type, DecoderType::DAV1D); } case DecoderType::MEDIACODEC: #ifdef VAVCORE_PLATFORM_ANDROID return std::make_unique(); #else LogError("MediaCodec decoder not available on this platform"); return nullptr; #endif case DecoderType::NVDEC: #ifdef VAVCORE_PLATFORM_WINDOWS return std::make_unique(); #else LogError("NVDEC decoder not available on this platform"); return nullptr; #endif case DecoderType::DAV1D: return std::make_unique(); // 모든 플랫폼에서 사용 가능 default: LogError("Unknown decoder type requested"); return nullptr; } } ``` ### 3.4 Enhanced 크로스 플랫폼 빌드 시스템 #### 3.4.1 완전한 CMakeLists.txt 구조 (모든 플랫폼 지원) ```cmake cmake_minimum_required(VERSION 3.22) project(VavCore) # 플랫폼별 소스 파일 및 라이브러리 설정 if(ANDROID) # Android 플랫폼 set(PLATFORM_SOURCES src/Decoder/AndroidMediaCodecAV1Decoder.cpp src/Platform/AndroidSurface.cpp src/Platform/AndroidGraphicsAPI.cpp ) set(PLATFORM_LIBRARIES mediandk # Android MediaCodec NDK android # Android 네이티브 라이브러리 log # Android 로깅 EGL # OpenGL ES 컨텍스트 GLESv2 # OpenGL ES 2.0 vulkan # Vulkan API (Android 7.0+) ) set(PLATFORM_INCLUDES ${ANDROID_NDK}/sources/android/native_app_glue ) add_definitions(-DVAVCORE_PLATFORM_ANDROID) elseif(WIN32) # Windows 플랫폼 set(PLATFORM_SOURCES src/Decoder/NVDECAV1Decoder.cpp src/Decoder/AMFAV1Decoder.cpp src/Decoder/VPLAV1Decoder.cpp src/Decoder/MediaFoundationAV1Decoder.cpp src/Platform/WindowsD3D.cpp src/Platform/WindowsCUDA.cpp ) set(PLATFORM_LIBRARIES d3d11 d3d12 dxgi mfplat mfreadwrite mftransform # CUDA 라이브러리들 (옵션) cuda cudart # AMD AMF 라이브러리들 (옵션) amf # Intel VPL 라이브러리들 (옵션) vpl ) add_definitions(-DVAVCORE_PLATFORM_WINDOWS) elseif(APPLE) # macOS/iOS 플랫폼 set(PLATFORM_SOURCES src/Decoder/VideoToolboxAV1Decoder.cpp # 미래 확장 src/Platform/AppleMetal.cpp src/Platform/AppleCoreVideo.cpp ) set(PLATFORM_LIBRARIES "-framework Metal" "-framework CoreVideo" "-framework VideoToolbox" "-framework Foundation" ) add_definitions(-DVAVCORE_PLATFORM_APPLE) else() # Linux 플랫폼 (기본값) set(PLATFORM_SOURCES src/Platform/LinuxOpenGL.cpp src/Platform/LinuxVulkan.cpp ) set(PLATFORM_LIBRARIES GL # OpenGL vulkan # Vulkan X11 # X11 윈도우 시스템 ) add_definitions(-DVAVCORE_PLATFORM_LINUX) endif() # 크로스 플랫폼 공통 소스 set(COMMON_SOURCES # Core 디코더 인터페이스 src/Decoder/IVideoDecoder.cpp src/Decoder/VideoDecoderFactory.cpp src/Decoder/AV1Decoder.cpp # dav1d 소프트웨어 디코더 # 공통 타입 및 유틸리티 src/Common/VideoTypes.cpp src/Common/SurfaceTypes.cpp src/Common/PlatformUtils.cpp # 파일 I/O (크로스 플랫폼) src/FileIO/IWebMFileReader.cpp src/FileIO/WebMFileReader.cpp # C API 래퍼 src/VavCore.cpp ) # VavCore 정적 라이브러리 생성 add_library(VavCore STATIC ${COMMON_SOURCES} ${PLATFORM_SOURCES} ) # 헤더 파일 경로 설정 target_include_directories(VavCore PUBLIC include/ # Public API 헤더 PRIVATE src/ # 내부 구현 헤더 ${PLATFORM_INCLUDES} ) # 라이브러리 링크 target_link_libraries(VavCore ${PLATFORM_LIBRARIES} dav1d # 크로스 플랫폼 소프트웨어 디코더 webm # libwebm 파서 라이브러리 ) # 컴파일러 플래그 설정 target_compile_features(VavCore PRIVATE cxx_std_17) target_compile_definitions(VavCore PRIVATE VAVCORE_VERSION_MAJOR=3 VAVCORE_VERSION_MINOR=0 VAVCORE_VERSION_PATCH=0 ) # 플랫폼별 추가 설정 if(ANDROID) # Android NDK 설정 target_compile_options(VavCore PRIVATE -fPIC -Wall -Wextra -O2 ) elseif(WIN32) # Windows MSVC 설정 target_compile_options(VavCore PRIVATE /W4 /O2 /DWIN32_LEAN_AND_MEAN ) endif() ``` #### 3.4.2 Enhanced Android Gradle 통합 (모든 Graphics API 지원) ```gradle android { namespace 'com.vavcore' compileSdk 34 externalNativeBuild { cmake { path "CMakeLists.txt" version "3.22.1" } } defaultConfig { minSdk 21 // Android 5.0+ (OpenGL ES 3.0 지원) targetSdk 34 ndk { // 현대적인 ARM 아키텍처 지원 abiFilters 'arm64-v8a', 'armeabi-v7a' } externalNativeBuild { cmake { cppFlags "-std=c++17 -DVAVCORE_PLATFORM_ANDROID -DANDROID_STL=c++_shared" arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang", "-DCMAKE_BUILD_TYPE=Release" } } } buildTypes { debug { debuggable true externalNativeBuild { cmake { cppFlags "-DVAVCORE_DEBUG -g" } } } release { minifyEnabled false externalNativeBuild { cmake { cppFlags "-DNDEBUG -O3" } } } } // Vulkan API 지원 설정 (Android 7.0+) defaultConfig { externalNativeBuild { cmake { cppFlags "-DVAVCORE_VULKAN_SUPPORT" arguments "-DVULKAN_ANDROID=1" } } } } dependencies { // Android Graphics API들은 프레임워크 일부이므로 추가 의존성 불필요 // - MediaCodec: Android 프레임워크 // - OpenGL ES: Android 프레임워크 // - Vulkan: Android 7.0+ 프레임워크 // - EGL: Android 프레임워크 // 필요시 추가할 수 있는 외부 라이브러리들 // implementation 'androidx.core:core:1.10.1' // AHardwareBuffer 지원 // implementation 'androidx.opengl:opengl:1.0.0' // OpenGL 유틸리티 } // NDK 빌드 최적화 설정 android.packagingOptions { pickFirst '**/libvavcore.so' pickFirst '**/libdav1d.so' } ``` ## 4. Enhanced 크로스 플랫폼 코드베이스 통합 ### 4.1 완전한 역호환성과 플랫폼 투명성 Enhanced 설계는 기존 코드와 100% 역호환성을 유지하면서 모든 플랫폼을 투명하게 지원합니다: ```cpp // 기존 코드는 전혀 변경 없이 모든 플랫폼에서 동작 auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, DecoderType::AUTO); decoder->Initialize(metadata); decoder->DecodeFrame(packet_data, packet_size, frame); // 플랫폼별 자동 최적화: // - Windows: NVDEC → VPL → AMF → dav1d → Media Foundation // - Android: MediaCodec (하드웨어) → dav1d (소프트웨어) // - macOS/iOS: VideoToolbox → dav1d (미래 확장) // - Linux: dav1d // Enhanced Surface 기반 디코딩 (플랫폼 투명) if (decoder->SupportsSurfaceType(target_surface_type)) { decoder->DecodeToSurface(packet_data, packet_size, target_surface_type, surface, frame); } ``` ### 4.2 크로스 플랫폼 로깅 시스템 (Enhanced) ```cpp namespace VavCore { class PlatformLogger { public: static void LogError(const std::string& message) { #ifdef VAVCORE_PLATFORM_ANDROID __android_log_print(ANDROID_LOG_ERROR, "VavCore", "%s", message.c_str()); #elif defined(VAVCORE_PLATFORM_WINDOWS) OutputDebugStringA(("VavCore Error: " + message + "\n").c_str()); #elif defined(VAVCORE_PLATFORM_APPLE) NSLog(@"VavCore Error: %s", message.c_str()); #else std::cerr << "VavCore Error: " << message << std::endl; #endif } static void LogInfo(const std::string& message) { #ifdef VAVCORE_PLATFORM_ANDROID __android_log_print(ANDROID_LOG_INFO, "VavCore", "%s", message.c_str()); #elif defined(VAVCORE_PLATFORM_WINDOWS) OutputDebugStringA(("VavCore Info: " + message + "\n").c_str()); #elif defined(VAVCORE_PLATFORM_APPLE) NSLog(@"VavCore Info: %s", message.c_str()); #else std::cout << "VavCore Info: " << message << std::endl; #endif } }; } // namespace VavCore ``` ### 4.3 Enhanced Godot 게임엔진 최적화 통합 #### 4.3.1 Godot 4 렌더링 아키텍처와 VavCore 통합 **Godot 4는 2024년 기준 다음과 같은 렌더링 백엔드를 사용:** - **Vulkan**: Forward+ 및 Mobile 렌더링 메서드 (주력) - **OpenGL ES 3.0**: Compatibility 렌더링 메서드 (호환성) - **Google 협력**: Android Vulkan 최적화 완료 **VavCore Surface 타입별 Godot 통합 방식:** ```cpp // Godot 4 Vulkan 렌더러 통합 (최우선) bool IntegrateWithGodotVulkan(VkImage vk_image, VkDevice vk_device) { // 1. MediaCodec → Vulkan VkImage 직접 디코딩 auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, DecoderType::AUTO); if (decoder->SupportsSurfaceType(VAVCORE_SURFACE_VULKAN_IMAGE)) { // 2. Godot Vulkan 렌더링 디바이스와 직접 연결 decoder->SetVulkanDevice(vk_device, vk_instance); // 3. Zero-copy: MediaCodec → VkImage → Godot 텍스처 VideoFrame output_frame; bool success = decoder->DecodeToSurface( packet_data, packet_size, VAVCORE_SURFACE_VULKAN_IMAGE, vk_image, output_frame ); // 4. Godot에서 VkImage를 텍스처로 직접 사용 // RenderingDevice.texture_create_from_extension() 활용 return success; } return false; } // Godot 4 OpenGL ES Compatibility 렌더러 통합 bool IntegrateWithGodotOpenGLES(GLuint texture_id, EGLContext egl_context) { // 1. MediaCodec → SurfaceTexture → GL_TEXTURE_EXTERNAL_OES auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, DecoderType::AUTO); if (decoder->SupportsSurfaceType(VAVCORE_SURFACE_OPENGL_ES_TEXTURE)) { // 2. Godot OpenGL ES 컨텍스트와 연결 decoder->SetOpenGLESContext(egl_context); // 3. SurfaceTexture 생성 (JNI를 통해) SurfaceTexture* surface_texture = CreateSurfaceTexture(texture_id); ANativeWindow* native_window = CreateNativeWindowFromSurfaceTexture(surface_texture); // 4. MediaCodec → SurfaceTexture → Godot GL 텍스처 VideoFrame output_frame; bool success = decoder->DecodeToSurface( packet_data, packet_size, VAVCORE_SURFACE_OPENGL_ES_TEXTURE, native_window, output_frame ); // 5. updateTexImage() 호출 후 Godot에서 텍스처 사용 return success; } return false; } ``` #### 4.3.2 Godot Android 플러그인 구조 ```cpp // Godot Android VavCore 플러그인 (JNI 인터페이스) extern "C" { // 디코더 생성 및 초기화 JNIEXPORT jlong JNICALL Java_org_godotengine_plugin_vavcore_VavCorePlugin_createDecoder(JNIEnv* env, jclass clazz) { auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, DecoderType::AUTO); return reinterpret_cast(decoder.release()); } // Godot 렌더링 백엔드별 최적화 설정 JNIEXPORT jint JNICALL Java_org_godotengine_plugin_vavcore_VavCorePlugin_getOptimalSurfaceType( JNIEnv* env, jclass clazz, jlong decoder_ptr) { auto* decoder = reinterpret_cast(decoder_ptr); return static_cast(decoder->GetOptimalSurfaceType()); } // Vulkan 렌더러 통합 (Godot 4 Forward+/Mobile) JNIEXPORT jboolean JNICALL Java_org_godotengine_plugin_vavcore_VavCorePlugin_setupVulkanIntegration( JNIEnv* env, jclass clazz, jlong decoder_ptr, jlong vk_device, jlong vk_instance) { auto* decoder = reinterpret_cast(decoder_ptr); bool success = decoder->SetVulkanDevice( reinterpret_cast(vk_device), reinterpret_cast(vk_instance) ); return success ? JNI_TRUE : JNI_FALSE; } // OpenGL ES 렌더러 통합 (Godot 4 Compatibility) JNIEXPORT jboolean JNICALL Java_org_godotengine_plugin_vavcore_VavCorePlugin_setupOpenGLESIntegration( JNIEnv* env, jclass clazz, jlong decoder_ptr, jobject surface_texture) { auto* decoder = reinterpret_cast(decoder_ptr); // SurfaceTexture → ANativeWindow 변환 ANativeWindow* native_window = ANativeWindow_fromSurface(env, surface_texture); if (!native_window) { return JNI_FALSE; } bool success = decoder->SetAndroidSurface(native_window); ANativeWindow_release(native_window); return success ? JNI_TRUE : JNI_FALSE; } // 프레임 디코딩 (Godot 텍스처로 직접 출력) JNIEXPORT jboolean JNICALL Java_org_godotengine_plugin_vavcore_VavCorePlugin_decodeFrameToTexture( JNIEnv* env, jclass clazz, jlong decoder_ptr, jbyteArray packet_data, jlong texture_handle) { auto* decoder = reinterpret_cast(decoder_ptr); // JNI 바이트 배열 → 네이티브 포인터 jbyte* data = env->GetByteArrayElements(packet_data, nullptr); jsize size = env->GetArrayLength(packet_data); VavCoreSurfaceType surface_type = decoder->GetOptimalSurfaceType(); void* target_surface = reinterpret_cast(texture_handle); VideoFrame output_frame; bool success = decoder->DecodeToSurface( reinterpret_cast(data), static_cast(size), surface_type, target_surface, output_frame ); env->ReleaseByteArrayElements(packet_data, data, JNI_ABORT); return success ? JNI_TRUE : JNI_FALSE; } // Godot 통합 상태 정보 JNIEXPORT jstring JNICALL Java_org_godotengine_plugin_vavcore_VavCorePlugin_getGodotIntegrationInfo( JNIEnv* env, jclass clazz, jlong decoder_ptr) { auto* decoder = reinterpret_cast(decoder_ptr); std::string info = decoder->GetGodotIntegrationInfo(); return env->NewStringUTF(info.c_str()); } } ``` #### 4.3.3 Godot GDScript 인터페이스 ```gdscript # Godot VavCore 플러그인 GDScript 인터페이스 class_name VavCoreVideoPlayer extends RefCounted # 네이티브 플러그인 참조 var _native_decoder: int = 0 var _surface_type: int = 0 var _texture: Texture2D # 초기화 func initialize() -> bool: if not Engine.has_singleton("VavCorePlugin"): push_error("VavCore plugin not found") return false var plugin = Engine.get_singleton("VavCorePlugin") _native_decoder = plugin.createDecoder() if _native_decoder == 0: push_error("Failed to create VavCore decoder") return false # Godot 렌더링 백엔드에 맞는 최적 Surface 타입 확인 _surface_type = plugin.getOptimalSurfaceType(_native_decoder) # 렌더링 백엔드별 초기화 match _surface_type: VavCoreSurfaceType.VULKAN_IMAGE: return _setup_vulkan_integration() VavCoreSurfaceType.OPENGL_ES_TEXTURE: return _setup_opengl_integration() _: push_warning("Using CPU decoding - not optimal for Godot") return true # Vulkan 통합 설정 func _setup_vulkan_integration() -> bool: var rendering_device = RenderingServer.create_local_rendering_device() if not rendering_device: return false # Vulkan 디바이스 정보 전달 (실제 구현에서는 RenderingDevice API 사용) var plugin = Engine.get_singleton("VavCorePlugin") return plugin.setupVulkanIntegration(_native_decoder, 0, 0) # VkDevice, VkInstance # OpenGL ES 통합 설정 func _setup_opengl_integration() -> bool: # SurfaceTexture 생성 및 설정 var plugin = Engine.get_singleton("VavCorePlugin") # 실제 구현에서는 Android SurfaceTexture API 사용 return plugin.setupOpenGLESIntegration(_native_decoder, null) # AV1 비디오 프레임 디코딩 func decode_frame(packet_data: PackedByteArray) -> bool: if _native_decoder == 0: return false var plugin = Engine.get_singleton("VavCorePlugin") return plugin.decodeFrameToTexture(_native_decoder, packet_data, 0) # 통합 정보 확인 func get_integration_info() -> String: if _native_decoder == 0: return "Decoder not initialized" var plugin = Engine.get_singleton("VavCorePlugin") return plugin.getGodotIntegrationInfo(_native_decoder) ``` ### 4.4 Unity/Unreal 엔진 통합 (참조용) Java_com_vavcore_VavCore_createDecoder(JNIEnv* env, jclass clazz) { auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, DecoderType::AUTO); return reinterpret_cast(decoder.release()); } JNIEXPORT jboolean JNICALL Java_com_vavcore_VavCore_setupAndroidSurface(JNIEnv* env, jclass clazz, jlong decoder_ptr, jobject surface) { auto* decoder = reinterpret_cast(decoder_ptr); ANativeWindow* native_window = ANativeWindow_fromSurface(env, surface); return decoder->SetAndroidSurface(native_window) ? JNI_TRUE : JNI_FALSE; } JNIEXPORT jboolean JNICALL Java_com_vavcore_VavCore_decodeToSurface(JNIEnv* env, jclass clazz, jlong decoder_ptr, jbyteArray packet_data, jint surface_type, jlong surface_handle) { auto* decoder = reinterpret_cast(decoder_ptr); // JNI 바이트 배열을 네이티브 포인터로 변환 jbyte* data = env->GetByteArrayElements(packet_data, nullptr); jsize size = env->GetArrayLength(packet_data); void* surface = reinterpret_cast(surface_handle); VideoFrame output_frame; bool result = decoder->DecodeToSurface( reinterpret_cast(data), static_cast(size), static_cast(surface_type), surface, output_frame ); env->ReleaseByteArrayElements(packet_data, data, JNI_ABORT); return result ? JNI_TRUE : JNI_FALSE; } } // Unity Native Plugin 인터페이스 (크로스 플랫폼) extern "C" { UNITY_INTERFACE_EXPORT void* UNITY_INTERFACE_API VavCore_CreateDecoder() { auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, DecoderType::AUTO); return decoder.release(); } UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API VavCore_SetupGraphicsAPI(void* decoder_ptr, int surface_type, void* graphics_device) { auto* decoder = static_cast(decoder_ptr); switch (static_cast(surface_type)) { case VAVCORE_SURFACE_D3D11_TEXTURE: return decoder->SetD3DDevice(graphics_device, VAVCORE_SURFACE_D3D11_TEXTURE); case VAVCORE_SURFACE_OPENGL_TEXTURE: return decoder->SetOpenGLContext(graphics_device); case VAVCORE_SURFACE_METAL_TEXTURE: return decoder->SetMetalDevice(graphics_device); default: return false; } } } ``` ## 5. Enhanced 성능 최적화 및 Zero-Copy 아키텍처 ### 5.1 완전한 Zero-Copy Graphics Pipeline **Android MediaCodec + GPU 직접 렌더링 최적화:** ```cpp // Zero-Copy 성능 최적화 클래스 class AndroidZeroCopyOptimizer { public: // GPU-to-GPU 직접 전송 (메모리 복사 완전 제거) bool OptimizeForSoC(const std::string& soc_name) { if (IsQualcommSnapdragon(soc_name)) { // Qualcomm Adreno GPU 최적화 EnableAdrenoGPUMemoryExtensions(); SetOptimalColorFormat(COLOR_FormatYUV420SemiPlanar); return true; } if (IsSamsungExynos(soc_name)) { // Samsung Mali GPU 최적화 EnableMaliGPUDirectRendering(); SetOptimalColorFormat(COLOR_FormatYUV420Flexible); return true; } if (IsMediaTekDimensity(soc_name)) { // MediaTek Mali GPU 최적화 EnableMaliGPUOptimizations(); return true; } return false; // 기본 설정 사용 } // 메모리 대역폭 최적화 void OptimizeMemoryBandwidth() { // SoC별 메모리 대역폭 특성에 맞춰 버퍼 크기 조정 m_optimal_buffer_count = GetOptimalBufferCount(); m_optimal_buffer_size = GetOptimalBufferSize(); } private: int m_optimal_buffer_count = 4; // SoC별 최적화 size_t m_optimal_buffer_size = 0; }; ``` ### 5.2 Enhanced Graceful Fallback 전략 (다단계) ```cpp class EnhancedFallbackStrategy { public: std::unique_ptr CreateOptimalDecoder(VideoCodecType codec_type) { // 1단계: 하드웨어 가속 시도 (우선순위 순) if (auto decoder = TryHardwareDecoders(codec_type)) { LogInfo("Hardware decoder selected: " + decoder->GetCodecName()); return decoder; } // 2단계: 하이브리드 디코더 시도 (일부 하드웨어 가속) if (auto decoder = TryHybridDecoders(codec_type)) { LogInfo("Hybrid decoder selected: " + decoder->GetCodecName()); return decoder; } // 3단계: 최적화된 소프트웨어 디코더 auto decoder = std::make_unique(); decoder->SetOptimizations(GetCPUOptimizations()); LogInfo("Optimized software decoder selected"); return decoder; } private: std::unique_ptr TryHardwareDecoders(VideoCodecType codec_type) { #ifdef VAVCORE_PLATFORM_ANDROID // Android 하드웨어 디코더들 시도 std::vector hw_codecs = { "c2.qti.av1.decoder", // Qualcomm 최신 "OMX.qcom.video.decoder.av1", // Qualcomm 레거시 "c2.mtk.av1.decoder", // MediaTek "c2.exynos.av1.decoder" // Samsung Exynos }; for (const auto& codec_name : hw_codecs) { if (auto decoder = TryCreateMediaCodec(codec_name)) { return decoder; } } #endif return nullptr; } CPUOptimizations GetCPUOptimizations() { CPUOptimizations opts; opts.enable_neon = HasNEONSupport(); opts.thread_count = GetOptimalThreadCount(); opts.simd_level = GetMaxSIMDLevel(); return opts; } }; ``` ### 5.3 실시간 성능 모니터링 및 동적 최적화 ```cpp class PerformanceMonitor { public: void UpdateFrameStats(double decode_time_ms, bool hardware_accelerated) { m_frame_times.push_back(decode_time_ms); if (m_frame_times.size() > 30) { // 30프레임 이동평균 m_frame_times.pop_front(); } double avg_time = CalculateAverage(m_frame_times); // 성능이 목표치 미달 시 동적 최적화 if (avg_time > TARGET_DECODE_TIME_MS) { TriggerPerformanceOptimization(); } // 하드웨어 가속 효과 모니터링 if (!hardware_accelerated && avg_time > SW_FALLBACK_THRESHOLD_MS) { LogWarning("Software decoder performance below threshold, consider resolution scaling"); } } private: static constexpr double TARGET_DECODE_TIME_MS = 16.67; // 60fps 목표 static constexpr double SW_FALLBACK_THRESHOLD_MS = 33.33; // 30fps 최소 std::deque m_frame_times; void TriggerPerformanceOptimization() { // 동적 해상도 스케일링 // 품질 레벨 조정 // 버퍼 크기 최적화 } }; ``` ## 6. Enhanced 테스트 및 검증 시스템 ### 6.1 포괄적인 Android 테스트 애플리케이션 ```cpp // VavCore Android 종합 테스트 애플리케이션 class ComprehensiveAndroidTest { public: void RunAllTests() { TestHardwareDetection(); TestAllSurfaceTypes(); TestPerformanceBenchmark(); TestFallbackScenarios(); TestMemoryLeaks(); } private: void TestAllSurfaceTypes() { auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, DecoderType::AUTO); // ANativeWindow 테스트 if (decoder->SupportsSurfaceType(VAVCORE_SURFACE_ANDROID_NATIVE_WINDOW)) { TestNativeWindowRendering(decoder.get()); } // OpenGL ES 텍스처 테스트 if (decoder->SupportsSurfaceType(VAVCORE_SURFACE_OPENGL_ES_TEXTURE)) { TestOpenGLESTextureRendering(decoder.get()); } // Vulkan 이미지 테스트 if (decoder->SupportsSurfaceType(VAVCORE_SURFACE_VULKAN_IMAGE)) { TestVulkanImageRendering(decoder.get()); } // AHardwareBuffer 테스트 if (decoder->SupportsSurfaceType(VAVCORE_SURFACE_ANDROID_HARDWARE_BUFFER)) { TestHardwareBufferRendering(decoder.get()); } } void TestPerformanceBenchmark() { // 다양한 해상도 및 비트레이트 테스트 std::vector test_videos = { {"1080p_av1.webm", 1920, 1080, 5000}, // 5Mbps {"4k_av1.webm", 3840, 2160, 15000}, // 15Mbps {"720p_av1.webm", 1280, 720, 2000} // 2Mbps }; for (const auto& test_video : test_videos) { BenchmarkVideo(test_video); } } }; ``` ### 6.2 성능 벤치마크 및 최적화 메트릭스 **측정 항목들:** - **초기화 시간**: MediaCodec vs dav1d 시작 시간 비교 - **디코딩 지연시간**: 하드웨어 vs 소프트웨어 프레임별 처리 시간 - **GPU 사용률**: 하드웨어 가속 시 GPU 점유율 - **전력 소비**: 배터리 소모량 측정 (Android Battery Historian) - **메모리 사용량**: 피크 메모리 및 메모리 누수 검사 - **열 관리**: SoC 온도 상승 및 스로틀링 감지 - **Surface 렌더링 성능**: 각 Graphics API별 렌더링 성능 ## 7. Enhanced 구현 로드맵 (완전한 크로스 플랫폼 지원) ### Phase 1: 핵심 크로스 플랫폼 인프라 (1-2주) ✅ **완료** - [x] **VavCoreSurfaceType 시스템**: 완전한 크로스 플랫폼 Surface 타입 열거형 - [x] **Enhanced IVideoDecoder 인터페이스**: 모든 플랫폼의 Graphics API 지원 - [x] **VideoDecoderFactory 확장**: 플랫폼별 디코더 등록 및 우선순위 시스템 - [x] **크로스 플랫폼 빌드 시스템**: CMake + 플랫폼별 조건부 컴파일 ### Phase 2: AndroidMediaCodecAV1Decoder 구현 (2-3주) - [ ] **Enhanced AndroidMediaCodecAV1Decoder**: 모든 IVideoDecoder 메서드 구현 - [ ] **Android SoC별 하드웨어 감지**: Qualcomm, Samsung, MediaTek, Google Tensor 지원 - [ ] **Graphics API 통합**: OpenGL ES, Vulkan, ANativeWindow, AHardwareBuffer - [ ] **Zero-Copy Surface 디코딩**: GPU-to-GPU 직접 전송 최적화 ### Phase 3: 성능 최적화 및 테스트 (3-4주) - [ ] **포괄적인 테스트 애플리케이션**: 모든 Surface 타입 및 SoC 조합 테스트 - [ ] **성능 벤치마킹**: 하드웨어 vs 소프트웨어 성능 비교 - [ ] **메모리 및 전력 최적화**: SoC별 최적화 설정 적용 - [ ] **Graceful Fallback 시스템**: 다단계 디코더 선택 및 전환 ### Phase 4: 게임 엔진 통합 및 배포 (4-5주) - [ ] **Godot Android 플러그인**: Native Surface 지원 완전 통합 - [ ] **Unity/Unreal 플러그인**: 크로스 플랫폼 Native Plugin 인터페이스 - [ ] **Android Studio 프로젝트**: 완전한 예제 애플리케이션 - [ ] **문서화 및 튜토리얼**: 개발자 가이드 및 API 레퍼런스 ## 8. Enhanced 리스크 관리 및 완화 전략 ### 8.1 하드웨어 호환성 리스크 (CRITICAL) - **리스크**: Android 기기별 AV1 하드웨어 지원 차이 - **완화 전략**: - 포괄적인 SoC 데이터베이스 구축 (Qualcomm, Samsung, MediaTek 등) - 런타임 하드웨어 감지 및 자동 최적화 - 견고한 dav1d 소프트웨어 fallback 보장 - 성능 모니터링 기반 동적 디코더 전환 ### 8.2 Android API 파편화 리스크 (MEDIUM) - **리스크**: Android 버전별 MediaCodec API 변경 및 동작 차이 - **완화 전략**: - 안정적인 NDK API만 사용 (API Level 21+) - 버전별 조건부 컴파일 및 호환성 레이어 - 광범위한 Android 버전 테스트 (API 21~34) ### 8.3 성능 최적화 리스크 (MEDIUM) - **리스크**: 특정 상황에서 하드웨어 디코더가 소프트웨어보다 성능 저하 - **완화 전략**: - 실시간 성능 모니터링 시스템 - SoC별 성능 프로파일링 데이터베이스 - 동적 디코더 전환 알고리즘 - 사용자 정의 성능 임계값 설정 ### 8.4 메모리 및 전력 소비 리스크 (LOW) - **리스크**: 하드웨어 가속으로 인한 예상치 못한 메모리/전력 증가 - **완화 전략**: - Zero-Copy 아키텍처로 메모리 사용량 최소화 - SoC별 전력 효율성 프로파일링 - 배터리 상태 기반 동적 최적화 ## 9. 결론 및 향후 전망 ### 9.1 프로젝트 성과 요약 본 Enhanced VavCore Android MediaCodec 통합 설계는 다음과 같은 혁신적 성과를 달성합니다: **✅ 완전한 크로스 플랫폼 지원:** - Windows (NVDEC, VPL, AMF, Media Foundation) - Android (MediaCodec + OpenGL ES/Vulkan) - macOS/iOS (Metal, VideoToolbox - 미래 확장) - Linux (OpenGL, Vulkan - 미래 확장) **✅ Zero-Copy 렌더링 아키텍처:** - GPU-to-GPU 직접 전송으로 성능 최적화 - 메모리 복사 완전 제거 - SoC별 최적화된 Graphics API 선택 **✅ 완전한 역호환성:** - 기존 Windows 코드 100% 호환 - 플랫폼 투명한 API 설계 - 점진적 마이그레이션 지원 ### 9.2 기술적 혁신 포인트 1. **Unified Surface Type System**: 모든 플랫폼의 Graphics API를 단일 열거형으로 통합 2. **Enhanced IVideoDecoder Interface**: 플랫폼별 특성을 반영한 확장 가능한 인터페이스 3. **Smart Hardware Detection**: SoC별 최적 디코더 및 Graphics API 자동 선택 4. **Multi-layer Fallback**: 하드웨어 → 하이브리드 → 최적화된 소프트웨어 다단계 전환 ### 9.3 향후 확장 계획 **즉시 확장 가능한 영역:** - **VP9 지원**: 동일한 아키텍처로 VP9 디코더 추가 - **H.264/H.265 지원**: 레거시 코덱 지원 확장 - **iOS/macOS 지원**: VideoToolbox + Metal 통합 - **Linux 지원**: VAAPI + OpenGL/Vulkan 통합 **장기 확장 목표:** - **실시간 스트리밍**: WebRTC + MediaCodec 통합 - **인코딩 지원**: 디코딩뿐만 아니라 인코딩 파이프라인 - **AI 후처리**: SoC NPU를 활용한 실시간 화질 개선 - **클라우드 연동**: 클라우드 GPU 리소스 활용 ### 9.4 산업적 영향 본 설계는 다음과 같은 산업적 파급 효과를 기대합니다: **게임 산업 (Godot 최적화):** - **Godot 4**: Vulkan/OpenGL ES 텍스처와 직접 통합하여 Zero-Copy 비디오 재생 - **Unity/Unreal**: 크로스 플랫폼 Native Plugin 인터페이스 지원 - **모바일 게임**: 고화질 AV1 컷신 및 배경 영상을 최소 성능 오버헤드로 재생 **스트리밍 산업:** - 모바일 앱에서의 효율적인 AV1 스트리밍 재생 - 배터리 효율성과 화질의 최적 균형 **교육 및 미디어:** - 크로스 플랫폼 교육 애플리케이션 - 고화질 미디어 콘텐츠의 효율적 배포 --- ### 📋 **문서 정보 (최종)** - **버전**: 3.0.0 (완전한 크로스 플랫폼 Graphics API 통합) - **최종 업데이트**: 2025-09-27 - **담당자**: Claude Code AI Assistant - **상태**: 구현 준비 완료 (Implementation Ready) --- *이 문서는 VavCore의 Android MediaCodec 통합뿐만 아니라 완전한 크로스 플랫폼 Graphics API 아키텍처를 제시하는 포괄적인 설계 문서입니다. 모든 주요 모바일 및 데스크톱 플랫폼에서 최적의 AV1 디코딩 성능을 보장하는 확장 가능한 솔루션을 제공합니다.*