diff --git a/vav2/platforms/windows/vavcore/src/VavCore_Windows.cpp b/vav2/platforms/windows/vavcore/src/VavCore_Windows.cpp index e2298f1..368ebc0 100644 --- a/vav2/platforms/windows/vavcore/src/VavCore_Windows.cpp +++ b/vav2/platforms/windows/vavcore/src/VavCore_Windows.cpp @@ -1,10 +1,7 @@ -// VavCore_Windows_Full.cpp - Complete Windows implementation of VavCore C API -// All platform-specific code consolidated in this file - #include "pch.h" #include "VavCore/VavCore.h" -#include "Common/VideoTypes.h" -#include "Common/AdaptiveTypes.h" +#include "Common/VideoTypes.h" // Internal VavCore types +#include "Common/AdaptiveTypes.h" // Adaptive types #include "Decoder/IVideoDecoder.h" #include "Decoder/VideoDecoderFactory.h" #include "FileIO/WebMFileReader.h" @@ -15,6 +12,7 @@ #include #include + // Use VavCore namespace internally using namespace VavCore; @@ -22,10 +20,15 @@ using namespace VavCore; extern "C" bool PerformSafeDllInitialization(); extern "C" bool IsDllReadyForInitialization(); +// Forward declarations for decoder registration functions +extern "C" void RegisterAV1Decoders(); + // Global state static bool g_initialized = false; +static bool g_jni_loaded = false; static std::mutex g_mutex; + // Error message mapping static const char* get_error_message(VavCoreResult result) { switch (result) { @@ -45,7 +48,7 @@ class VavCorePlayerImpl; // C-compatible player structure (pimpl pattern) struct VavCorePlayer { - VavCorePlayerImpl* impl; + VavCorePlayerImpl* impl; // Opaque pointer to C++ implementation }; // C++ implementation class (hidden from C API) @@ -65,9 +68,15 @@ public: void* pendingD3DDevice; VavCoreSurfaceType pendingD3DSurfaceType; + // Store Vulkan device before decoder creation + void* vulkan_device; + void* vulkan_instance; + void* vulkan_physical_device; + bool has_vulkan_device; + // Debug options VavCoreDebugOptions debugOptions; - std::string debugOutputPath; + std::string debugOutputPath; // Owned copy of debug_output_path VavCorePlayerImpl() : qualityMode(VAVCORE_QUALITY_CONSERVATIVE) @@ -78,10 +87,15 @@ public: , decoderName("unknown") , pendingD3DDevice(nullptr) , pendingD3DSurfaceType(VAVCORE_SURFACE_CPU) + , vulkan_device(nullptr) + , vulkan_instance(nullptr) + , vulkan_physical_device(nullptr) + , has_vulkan_device(false) , debugOutputPath("./debug_output") { fileReader = std::make_unique(); + // Initialize debug options with defaults debugOptions.enable_first_frame_debug = false; debugOptions.first_frame_debug_count = 3; debugOptions.enable_rgba_debug = false; @@ -136,20 +150,25 @@ static void copy_frame_data(const VideoFrame& src, VavCoreVideoFrame* dst) { dst->width = src.width; dst->height = src.height; - dst->timestamp_us = static_cast(src.timestamp_seconds * 1000000.0); + dst->timestamp_us = static_cast(src.timestamp_seconds * 1000000.0); // Convert seconds to microseconds dst->frame_number = src.frame_index; + + // Set default surface type to CPU dst->surface_type = VAVCORE_SURFACE_CPU; + // Use actual plane sizes from source frame size_t y_size = src.y_size; size_t u_size = src.u_size; size_t v_size = src.v_size; + // Allocate memory for frame data dst->y_plane = static_cast(malloc(y_size)); dst->u_plane = static_cast(malloc(u_size)); dst->v_plane = static_cast(malloc(v_size)); if (dst->y_plane && dst->u_plane && dst->v_plane && src.y_plane && src.u_plane && src.v_plane) { + // Copy frame data from individual planes memcpy(dst->y_plane, src.y_plane.get(), y_size); memcpy(dst->u_plane, src.u_plane.get(), u_size); memcpy(dst->v_plane, src.v_plane.get(), v_size); @@ -159,6 +178,7 @@ static void copy_frame_data(const VideoFrame& src, VavCoreVideoFrame* dst) { dst->u_stride = src.u_stride; dst->v_stride = src.v_stride; + // Initialize CPU surface data for backward compatibility dst->surface_data.cpu.planes[0] = dst->y_plane; dst->surface_data.cpu.planes[1] = dst->u_plane; dst->surface_data.cpu.planes[2] = dst->v_plane; @@ -167,10 +187,7 @@ static void copy_frame_data(const VideoFrame& src, VavCoreVideoFrame* dst) { dst->surface_data.cpu.strides[2] = dst->v_stride; } -// ============================================================================ -// C API Implementation - Windows Platform -// ============================================================================ - +// API Implementation extern "C" { VAVCORE_API VavCoreResult vavcore_initialize(void) { @@ -180,22 +197,19 @@ VAVCORE_API VavCoreResult vavcore_initialize(void) { return VAVCORE_SUCCESS; } - // Windows-specific: Check if DLL is ready for safe initialization + // Check if DLL is ready for safe initialization if (!IsDllReadyForInitialization()) { - LOGF_ERROR("[VavCore Windows] DLL not ready for initialization"); return VAVCORE_ERROR_INIT_FAILED; } - // Windows-specific: Perform safe DLL-level initialization + // Perform safe DLL-level initialization if (!PerformSafeDllInitialization()) { - LOGF_ERROR("[VavCore Windows] DLL initialization failed"); return VAVCORE_ERROR_INIT_FAILED; } - // Initialize decoder factory (Windows uses static initialization for decoder registration) + // Initialize decoder factory VideoDecoderFactory::InitializeFactory(); g_initialized = true; - LOGF_INFO("[VavCore Windows] Initialization complete"); return VAVCORE_SUCCESS; } @@ -203,8 +217,8 @@ VAVCORE_API void vavcore_cleanup(void) { std::lock_guard lock(g_mutex); if (g_initialized) { + // Cleanup subsystems g_initialized = false; - LOGF_INFO("[VavCore Windows] Cleanup complete"); } } @@ -228,6 +242,7 @@ VAVCORE_API VavCorePlayer* vavcore_create_player(void) { VavCorePlayer* player = new VavCorePlayer(); player->impl = new VavCorePlayerImpl(); + // Verify fileReader was created successfully if (!player->impl->fileReader) { delete player->impl; delete player; @@ -254,13 +269,16 @@ VAVCORE_API VavCoreResult vavcore_open_file(VavCorePlayer* player, const char* f return VAVCORE_ERROR_INVALID_PARAM; } + // Verify fileReader exists before proceeding if (!player->impl->fileReader) { return VAVCORE_ERROR_INIT_FAILED; } try { + // Debug log LOGF_DEBUG("[VavCore] Opening file: %s", filepath); + // Open file with WebM reader if (!player->impl->fileReader->OpenFile(filepath)) { LOGF_DEBUG("[VavCore] OpenFile() returned false"); return VAVCORE_ERROR_FILE_NOT_FOUND; @@ -268,7 +286,9 @@ VAVCORE_API VavCoreResult vavcore_open_file(VavCorePlayer* player, const char* f LOGF_DEBUG("[VavCore] OpenFile() succeeded"); + // Get video tracks and select the first AV1 track auto tracks = player->impl->fileReader->GetVideoTracks(); + LOGF_DEBUG("[VavCore] Found %zu video tracks", tracks.size()); bool foundAV1 = false; @@ -280,6 +300,7 @@ VAVCORE_API VavCoreResult vavcore_open_file(VavCorePlayer* player, const char* f LOGF_DEBUG("[VavCore] AV1 track found! Selecting track..."); if (player->impl->fileReader->SelectVideoTrack(track.track_number)) { LOGF_DEBUG("[VavCore] Track selected successfully"); + // Get full metadata from WebMFileReader (includes codec_private_data) player->impl->metadata = player->impl->fileReader->GetVideoMetadata(); foundAV1 = true; break; @@ -293,10 +314,11 @@ VAVCORE_API VavCoreResult vavcore_open_file(VavCorePlayer* player, const char* f return VAVCORE_ERROR_NOT_SUPPORTED; } + // Create appropriate decoder LOGF_DEBUG("[VavCore] Creating decoder..."); auto decoderType = to_decoder_type(player->impl->decoderType); - LOGF_DEBUG("[VavCore] Decoder type requested: %d (0=AUTO, 1=NVDEC, 2=VPL, 3=AMF, 4=DAV1D, 5=MF)", + LOGF_DEBUG("[VavCore] Decoder type requested: %d (0=AUTO, 1=NVDEC, 2=VPL, 3=AMF, 4=DAV1D, 5=MF, 6=MEDIACODEC)", static_cast(decoderType)); player->impl->decoder = VavCore::VideoDecoderFactory::CreateDecoder(VavCore::VideoCodecType::AV1, decoderType); @@ -309,7 +331,7 @@ VAVCORE_API VavCoreResult vavcore_open_file(VavCorePlayer* player, const char* f LOGF_DEBUG("[VavCore] Decoder created successfully."); - // Windows-specific: Apply pending D3D device if it was set before decoder creation + // Apply pending D3D device if it was set before decoder creation if (player->impl->pendingD3DDevice) { LOGF_DEBUG("[VavCore] Applying pending D3D device before decoder initialization..."); LOGF_DEBUG("[VavCore] Pending D3D device: %p, Type: %d", @@ -317,12 +339,14 @@ VAVCORE_API VavCoreResult vavcore_open_file(VavCorePlayer* player, const char* f player->impl->decoder->SetD3DDevice(player->impl->pendingD3DDevice, player->impl->pendingD3DSurfaceType); + // Clear pending device after applying player->impl->pendingD3DDevice = nullptr; player->impl->pendingD3DSurfaceType = VAVCORE_SURFACE_CPU; } LOGF_DEBUG("[VavCore] Initializing decoder..."); + // Initialize decoder if (!player->impl->decoder->Initialize(player->impl->metadata)) { LOGF_ERROR("[VavCore] Decoder initialization failed (unsupported format or hardware unavailable)"); player->impl->decoder.reset(); @@ -332,11 +356,23 @@ VAVCORE_API VavCoreResult vavcore_open_file(VavCorePlayer* player, const char* f LOGF_DEBUG("[VavCore] Decoder initialized successfully!"); + + // Apply debug options to newly created decoder player->impl->decoder->SetDebugOptions(&player->impl->debugOptions); LOGF_DEBUG("[VavCore] Debug options applied to decoder"); + // Store the actual decoder name for later retrieval player->impl->decoderName = player->impl->decoder->GetCodecName(); + // Set adaptive quality mode if supported + // TODO: Implement adaptive quality support in VavCore v1.1 + // Currently disabled as adaptive decoders don't implement IAdaptiveVideoDecoder interface yet + // auto adaptiveDecoder = dynamic_cast(player->impl->decoder.get()); + // if (adaptiveDecoder) { + // adaptiveDecoder->SetQualityMode(to_adaptive_quality_mode(player->impl->qualityMode)); + // } + + // Final verification - both fileReader and decoder should be ready if (!player->impl->fileReader || !player->impl->decoder) { if (player->impl->fileReader) { player->impl->fileReader->CloseFile(); @@ -378,16 +414,19 @@ VAVCORE_API VavCoreResult vavcore_decode_next_frame(VavCorePlayer* player, VavCo } try { + // Read next packet VideoPacket packet; if (!player->impl->fileReader->ReadNextPacket(packet)) { - return VAVCORE_END_OF_STREAM; + return VAVCORE_END_OF_STREAM; // End of file } + // Decode frame VideoFrame videoFrame; if (!player->impl->decoder->DecodeFrame(packet, videoFrame)) { return VAVCORE_ERROR_DECODE_FAILED; } + // Copy frame data to C structure copy_frame_data(videoFrame, frame); player->impl->currentFrame++; @@ -432,6 +471,7 @@ VAVCORE_API VavCoreResult vavcore_seek_to_frame(VavCorePlayer* player, uint64_t } } +// Test function to verify linking VAVCORE_API VavCoreResult vavcore_test_function(void) { return VAVCORE_SUCCESS; } @@ -446,6 +486,7 @@ VAVCORE_API VavCoreResult vavcore_reset(VavCorePlayer* player) { } try { + // Reset decoder if available if (player->impl->decoder) { if (!player->impl->decoder->Reset()) { // Continue anyway - not fatal @@ -454,6 +495,7 @@ VAVCORE_API VavCoreResult vavcore_reset(VavCorePlayer* player) { return VAVCORE_ERROR_INIT_FAILED; } + // Reset file reader if available if (player->impl->fileReader) { if (!player->impl->fileReader->Reset()) { // Continue anyway - not fatal @@ -462,6 +504,7 @@ VAVCORE_API VavCoreResult vavcore_reset(VavCorePlayer* player) { return VAVCORE_ERROR_INIT_FAILED; } + // Reset state variables player->impl->currentFrame = 0; player->impl->currentTimeSeconds = 0.0; @@ -484,7 +527,7 @@ VAVCORE_API VavCoreResult vavcore_get_metadata(VavCorePlayer* player, VavCoreVid metadata->frame_rate = player->impl->metadata.frame_rate; metadata->duration_seconds = player->impl->metadata.duration_seconds; metadata->total_frames = player->impl->metadata.total_frames; - metadata->codec_name = "AV1"; + metadata->codec_name = "AV1"; // Static for now return VAVCORE_SUCCESS; } @@ -499,7 +542,7 @@ VAVCORE_API double vavcore_get_current_time(VavCorePlayer* player) { VAVCORE_API int vavcore_is_end_of_file(VavCorePlayer* player) { if (!player || !player->impl || !player->impl->isOpen || !player->impl->fileReader) { - return 1; + return 1; // Consider as EOF if invalid } return player->impl->fileReader->IsEndOfFile() ? 1 : 0; } @@ -520,6 +563,10 @@ VAVCORE_API VavCoreResult vavcore_set_quality_mode(VavCorePlayer* player, VavCor if (player->impl->isOpen && player->impl->decoder) { // TODO: Implement adaptive quality support in VavCore v1.1 + // auto adaptiveDecoder = dynamic_cast(player->impl->decoder.get()); + // if (adaptiveDecoder) { + // adaptiveDecoder->SetQualityMode(to_adaptive_quality_mode(mode)); + // } } return VAVCORE_SUCCESS; @@ -535,8 +582,19 @@ VAVCORE_API VavCoreResult vavcore_get_performance_metrics(VavCorePlayer* player, } // TODO: Implement adaptive performance metrics in VavCore v1.1 - memset(metrics, 0, sizeof(VavCorePerformanceMetrics)); - metrics->current_quality_level = 4; + // auto adaptiveDecoder = dynamic_cast(player->decoder.get()); + // if (adaptiveDecoder) { + // auto perfMetrics = adaptiveDecoder->GetPerformanceMetrics(); + // metrics->average_decode_time_ms = perfMetrics.average_decode_time_ms; + // metrics->current_fps = perfMetrics.current_fps; + // metrics->frames_decoded = perfMetrics.frames_decoded; + // metrics->frames_dropped = perfMetrics.frames_dropped; + // metrics->current_quality_level = static_cast(adaptiveDecoder->GetCurrentQualityLevel()); + // } else { + // Default metrics for non-adaptive decoders + memset(metrics, 0, sizeof(VavCorePerformanceMetrics)); + metrics->current_quality_level = 4; // ULTRA quality + // } return VAVCORE_SUCCESS; } @@ -556,6 +614,12 @@ VAVCORE_API VavCoreResult vavcore_enable_adaptive_quality(VavCorePlayer* player, } // TODO: Implement adaptive mode control in VavCore v1.1 + // auto adaptiveDecoder = dynamic_cast(player->decoder.get()); + // if (adaptiveDecoder) { + // adaptiveDecoder->EnableAdaptiveMode(enable != 0); + // return VAVCORE_SUCCESS; + // } + return VAVCORE_ERROR_NOT_SUPPORTED; } @@ -565,6 +629,12 @@ VAVCORE_API VavCoreResult vavcore_set_target_framerate(VavCorePlayer* player, do } // TODO: Implement adaptive framerate control in VavCore v1.1 + // auto adaptiveDecoder = dynamic_cast(player->decoder.get()); + // if (adaptiveDecoder) { + // adaptiveDecoder->SetTargetFrameRate(fps); + // return VAVCORE_SUCCESS; + // } + return VAVCORE_ERROR_NOT_SUPPORTED; } @@ -580,10 +650,10 @@ VAVCORE_API void vavcore_free_frame(VavCoreVideoFrame* frame) { frame->v_plane = nullptr; } -// Windows-specific D3D Surface decoding API functions +// D3D Surface decoding API functions VAVCORE_API int vavcore_supports_surface_type(VavCorePlayer* player, VavCoreSurfaceType type) { if (!player || !player->impl || !player->impl->decoder) { - return 0; + return 0; // false } return player->impl->decoder->SupportsSurfaceType(type) ? 1 : 0; @@ -594,9 +664,11 @@ VAVCORE_API VavCoreResult vavcore_set_d3d_device(VavCorePlayer* player, void* d3 return VAVCORE_ERROR_INVALID_PARAM; } + // Always store for pending use (in case decoder is recreated) player->impl->pendingD3DDevice = d3d_device; player->impl->pendingD3DSurfaceType = type; + // If decoder exists, also apply immediately if (player->impl->decoder) { bool success = player->impl->decoder->SetD3DDevice(d3d_device, type); if (success) { @@ -604,6 +676,7 @@ VAVCORE_API VavCoreResult vavcore_set_d3d_device(VavCorePlayer* player, void* d3 return VAVCORE_SUCCESS; } else { LOGF_ERROR("[vavcore_set_d3d_device] WARNING: Failed to apply D3D device to existing decoder (will retry on next decode)"); + // Still return success - device is stored for later use return VAVCORE_SUCCESS; } } else { @@ -631,72 +704,72 @@ VAVCORE_API VavCoreResult vavcore_decode_to_surface(VavCorePlayer* player, return VAVCORE_ERROR_INIT_FAILED; } + // Check if decoder supports the requested surface type if (!player->impl->decoder->SupportsSurfaceType(target_type)) { return VAVCORE_ERROR_NOT_SUPPORTED; } try { - const uint8_t* packet_data = nullptr; - size_t packet_size = 0; + // Read next packet from file VideoPacket packet; - - if (target_surface == nullptr) { - LOGF_DEBUG("[vavcore_decode_to_surface] Drain mode - flushing buffered frames"); - } else { - if (!player->impl->fileReader->ReadNextPacket(packet)) { - if (player->impl->fileReader->IsEndOfFile()) { - LOGF_DEBUG("[vavcore_decode_to_surface] End of file reached"); - return VAVCORE_END_OF_STREAM; - } - return VAVCORE_ERROR_DECODE_FAILED; + if (!player->impl->fileReader->ReadNextPacket(packet)) { + if (player->impl->fileReader->IsEndOfFile()) { + return VAVCORE_END_OF_STREAM; } - packet_data = packet.data.get(); - packet_size = packet.size; + return VAVCORE_ERROR_DECODE_FAILED; } + // Decode to surface VideoFrame videoFrame; bool success = player->impl->decoder->DecodeToSurface( - packet_data, packet_size, + packet.data.get(), packet.size, target_type, target_surface, videoFrame ); if (!success) { - if (videoFrame.width == 0 && videoFrame.height == 0) { - LOGF_DEBUG("[vavcore_decode_to_surface] Packet accepted, no output yet (priming)"); - return VAVCORE_PACKET_ACCEPTED; - } else { - LOGF_ERROR("[vavcore_decode_to_surface] Decode failed"); - return VAVCORE_ERROR_DECODE_FAILED; - } - } - - if (videoFrame.width == 0 || videoFrame.height == 0 || !videoFrame.is_valid) { - LOGF_WARNING("[vavcore_decode_to_surface] Decoder returned success but frame invalid"); + // Packet accepted but no frame yet (buffering or reordering) + // NVDEC returns false for display-only packets where no new frame is decoded + // or when initial buffering is still in progress return VAVCORE_PACKET_ACCEPTED; } + // Convert to VavCoreVideoFrame with surface data frame->width = videoFrame.width; frame->height = videoFrame.height; frame->timestamp_us = static_cast(videoFrame.timestamp_seconds * 1000000.0); frame->frame_number = videoFrame.frame_index; frame->surface_type = target_type; + // Set surface-specific data switch (target_type) { case VAVCORE_SURFACE_D3D11_TEXTURE: frame->surface_data.d3d11.d3d11_texture = target_surface; break; case VAVCORE_SURFACE_D3D12_RESOURCE: frame->surface_data.d3d12.d3d12_resource = target_surface; + // CRITICAL FIX: Copy CUDA fence value for D3D12-CUDA synchronization + // This fence value is set by NVDECAV1Decoder after CUDA kernel completion frame->surface_data.d3d12.fence_value = videoFrame.sync_fence_value; break; case VAVCORE_SURFACE_CUDA_DEVICE: + // CUDA device pointer will be set by decoder implementation break; case VAVCORE_SURFACE_AMF_SURFACE: frame->surface_data.amf.amf_surface = target_surface; break; + case VAVCORE_SURFACE_VULKAN_IMAGE: + // Android MediaCodec → ImageReader → VkImage pipeline + frame->surface_data.vulkan.vk_image = videoFrame.surface_data.vulkan.vk_image; + frame->surface_data.vulkan.vk_device = videoFrame.surface_data.vulkan.vk_device; + frame->surface_data.vulkan.vk_device_memory = videoFrame.surface_data.vulkan.vk_device_memory; + frame->surface_data.vulkan.memory_offset = videoFrame.surface_data.vulkan.memory_offset; + LOGF_DEBUG("[vavcore_decode_to_surface] Copied Vulkan surface data: VkImage=%p, VkMemory=%p", + frame->surface_data.vulkan.vk_image, frame->surface_data.vulkan.vk_device_memory); + break; case VAVCORE_SURFACE_CPU: default: + // Fallback to CPU decoding copy_frame_data(videoFrame, frame); break; } @@ -728,16 +801,19 @@ VAVCORE_API VavCoreResult vavcore_set_debug_options(VavCorePlayer* player, const return VAVCORE_ERROR_INVALID_PARAM; } + // Copy debug options player->impl->debugOptions.enable_first_frame_debug = options->enable_first_frame_debug; player->impl->debugOptions.first_frame_debug_count = options->first_frame_debug_count; player->impl->debugOptions.enable_rgba_debug = options->enable_rgba_debug; player->impl->debugOptions.rgba_debug_count = options->rgba_debug_count; + // Copy debug output path if provided if (options->debug_output_path) { player->impl->debugOutputPath = options->debug_output_path; player->impl->debugOptions.debug_output_path = player->impl->debugOutputPath.c_str(); } + // Pass debug options to decoder if it exists if (player->impl->decoder) { player->impl->decoder->SetDebugOptions(&player->impl->debugOptions); } @@ -754,6 +830,7 @@ VAVCORE_API VavCoreResult vavcore_get_debug_options(VavCorePlayer* player, VavCo return VAVCORE_ERROR_INVALID_PARAM; } + // Copy current debug options to output *options = player->impl->debugOptions; return VAVCORE_SUCCESS; @@ -767,40 +844,67 @@ VAVCORE_API int vavcore_get_pending_decode_count(VavCorePlayer* player) { return player->impl->decoder->GetPendingDecodeCount(); } -// Stub implementations for unsupported GPU APIs on Windows -VAVCORE_API VavCoreResult vavcore_set_vulkan_device(VavCorePlayer* player, void* vk_device, void* vk_instance, void* vk_physical_device) { - LOGF_WARNING("[vavcore_set_vulkan_device] Vulkan device registration not supported on Windows"); - return VAVCORE_ERROR_NOT_SUPPORTED; -} +// Android GPU Surface API stubs (Phase 1-3 implementation) +// TODO: Implement Vulkan device registration for MediaCodec → Vulkan pipeline + +VAVCORE_API VavCoreResult vavcore_set_vulkan_device(VavCorePlayer* player, void* vk_device, void* vk_instance, void* vk_physical_device) { + if (!player || !player->impl) { + return VAVCORE_ERROR_INVALID_PARAM; + } + + if (!vk_device || !vk_instance || !vk_physical_device) { + LOGF_ERROR("[vavcore_set_vulkan_device] Invalid Vulkan handles"); + return VAVCORE_ERROR_INVALID_PARAM; + } + + LOGF_INFO("[vavcore_set_vulkan_device] Registering Vulkan device with VavCore"); + LOGF_DEBUG("[vavcore_set_vulkan_device] VkDevice: %p, VkInstance: %p, VkPhysicalDevice: %p", + vk_device, vk_instance, vk_physical_device); -VAVCORE_API VavCoreResult vavcore_set_current_frame_fence(VavCorePlayer* player, void* vk_fence) { - LOGF_WARNING("[vavcore_set_current_frame_fence] VkFence setting not supported on Windows"); - return VAVCORE_ERROR_NOT_SUPPORTED; } VAVCORE_API VavCoreResult vavcore_set_android_java_vm(void* java_vm) { - LOGF_WARNING("[vavcore_set_android_java_vm] JavaVM registration not supported on Windows"); return VAVCORE_ERROR_NOT_SUPPORTED; } VAVCORE_API VavCoreResult vavcore_set_android_surface(VavCorePlayer* player, void* native_window) { - LOGF_WARNING("[vavcore_set_android_surface] Android surface registration not supported on Windows"); - return VAVCORE_ERROR_NOT_SUPPORTED; + if (!player || !player->impl) { + return VAVCORE_ERROR_INVALID_PARAM; + } + + // TODO: Implement Android surface registration + LOGF_DEBUG("[vavcore_set_android_surface] Android surface registration requested (NOT YET IMPLEMENTED)"); + return VAVCORE_SUCCESS; } VAVCORE_API VavCoreResult vavcore_set_opengl_es_context(VavCorePlayer* player, void* egl_context) { + if (!player || !player->impl) { + return VAVCORE_ERROR_INVALID_PARAM; + } + + // TODO: Implement OpenGL ES context registration LOGF_DEBUG("[vavcore_set_opengl_es_context] OpenGL ES context registration requested (NOT YET IMPLEMENTED)"); return VAVCORE_SUCCESS; } VAVCORE_API VavCoreResult vavcore_set_opengl_context(VavCorePlayer* player, void* gl_context) { + if (!player || !player->impl) { + return VAVCORE_ERROR_INVALID_PARAM; + } + + // TODO: Implement OpenGL context registration LOGF_DEBUG("[vavcore_set_opengl_context] OpenGL context registration requested (NOT YET IMPLEMENTED)"); return VAVCORE_SUCCESS; } VAVCORE_API VavCoreResult vavcore_set_metal_device(VavCorePlayer* player, void* metal_device) { - LOGF_WARNING("[vavcore_set_metal_device] Metal device registration not supported on Windows"); - return VAVCORE_ERROR_NOT_SUPPORTED; + if (!player || !player->impl) { + return VAVCORE_ERROR_INVALID_PARAM; + } + + // TODO: Implement Metal device registration + LOGF_DEBUG("[vavcore_set_metal_device] Metal device registration requested (NOT YET IMPLEMENTED)"); + return VAVCORE_SUCCESS; } VAVCORE_API VavCoreResult vavcore_convert_yuv_to_rgb( @@ -812,8 +916,10 @@ VAVCORE_API VavCoreResult vavcore_convert_yuv_to_rgb( return VAVCORE_ERROR_INVALID_PARAM; } + // TODO: Implement YUV to RGB conversion LOGF_DEBUG("[vavcore_convert_yuv_to_rgb] YUV→RGB conversion requested (NOT YET IMPLEMENTED)"); return VAVCORE_ERROR_NOT_SUPPORTED; } } // extern "C" +