diff --git a/vav2/platforms/windows/vavcore/src/Decoder/MediaCodecAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/MediaCodecAV1Decoder.cpp index 9a10d92..899641d 100644 --- a/vav2/platforms/windows/vavcore/src/Decoder/MediaCodecAV1Decoder.cpp +++ b/vav2/platforms/windows/vavcore/src/Decoder/MediaCodecAV1Decoder.cpp @@ -745,6 +745,13 @@ bool MediaCodecAV1Decoder::InitializeMediaCodec() { AMediaFormat_setInt32(m_format, AMEDIAFORMAT_KEY_COLOR_FORMAT, 0x7F420888); LogInfo("Set MediaCodec output format: COLOR_FormatYUV420Flexible (0x7F420888)"); + // CRITICAL: Set color space parameters for correct YUV interpretation + // Most HD videos use BT.709 color standard with studio range (16-235) + // COLOR_STANDARD_BT709 = 1, COLOR_RANGE_LIMITED = 2 + AMediaFormat_setInt32(m_format, "color-standard", 1); // BT.709 + AMediaFormat_setInt32(m_format, "color-range", 2); // Limited/Studio range + LogInfo("Set MediaCodec color space: BT.709 + Limited range"); + // Set codec specific data (csd-0) - CRITICAL for AV1 decoding // This contains the AV1 sequence header from WebM CodecPrivate if (!m_codec_private_data.empty()) { diff --git a/vav2/platforms/windows/vavcore/src/Decoder/MediaCodecSurfaceManager.cpp b/vav2/platforms/windows/vavcore/src/Decoder/MediaCodecSurfaceManager.cpp index bebaff1..51cd33c 100644 --- a/vav2/platforms/windows/vavcore/src/Decoder/MediaCodecSurfaceManager.cpp +++ b/vav2/platforms/windows/vavcore/src/Decoder/MediaCodecSurfaceManager.cpp @@ -288,6 +288,35 @@ bool MediaCodecSurfaceManager::CreateVulkanImage(void* vk_device, void* vk_insta LogInfo("AHardwareBuffer desc: " + std::to_string(ahb_desc.width) + "x" + std::to_string(ahb_desc.height) + " format=" + std::to_string(ahb_desc.format)); + // DEBUG: Lock AHardwareBuffer and read first few pixels to verify data format +#ifdef _DEBUG + static int debug_frame_count = 0; + if (debug_frame_count < 3) { // Only log first 3 frames + void* data = nullptr; + int ret = AHardwareBuffer_lock(ahb, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr, &data); + if (ret == 0 && data != nullptr) { + uint8_t* pixels = static_cast(data); + + // Sample pixel at (100, 100) - should be in sky (red in correct image) + uint32_t offset_y = 100 * ahb_desc.stride + 100; + uint32_t offset_uv = (ahb_desc.width * ahb_desc.height) + (50 * ahb_desc.stride) + 100; // NV12 UV plane + + LogInfo("=== PIXEL DATA DEBUG (frame " + std::to_string(debug_frame_count) + ") ==="); + LogInfo(" Pixel (100,100) Y plane:"); + LogInfo(" pixels[" + std::to_string(offset_y) + "] = " + std::to_string((int)pixels[offset_y])); + LogInfo(" Pixel (50,50) UV plane (chroma):"); + LogInfo(" pixels[" + std::to_string(offset_uv) + "] = " + std::to_string((int)pixels[offset_uv]) + " (U)"); + LogInfo(" pixels[" + std::to_string(offset_uv + 1) + "] = " + std::to_string((int)pixels[offset_uv + 1]) + " (V)"); + LogInfo(" stride: " + std::to_string(ahb_desc.stride)); + + AHardwareBuffer_unlock(ahb, nullptr); + debug_frame_count++; + } else { + LogError("Failed to lock AHardwareBuffer for pixel inspection: " + std::to_string(ret)); + } + } +#endif + // Step 2: Query Android Hardware Buffer properties for Vulkan VkAndroidHardwareBufferFormatPropertiesANDROID ahb_format_props = {}; ahb_format_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;