// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/gfx/video_decode_acceleration_support_mac.h" #import "base/bind.h" #include "base/location.h" #import "base/mac/foundation_util.h" #include "base/mac/scoped_nsautorelease_pool.h" #include "base/message_loop.h" #import "base/sys_info.h" #import "base/threading/platform_thread.h" #import "base/threading/thread.h" #import "ui/base/test/ui_cocoa_test_helper.h" namespace { // Aribtrary values used to test the callback. const int kCallbackFrameID = 10; const int kCallbackExpectedStatus = 7; // Sample movie data to create the decoder. const int kSampleWidth = 1280; const int kSampleHeight = 720; const uint8_t kSampleAVCData[] = { 0x1, 0x64, 0x0, 0x1f, 0xff, 0xe1, 0x0, 0x1a, 0x67, 0x64, 0x0, 0x1f, 0xac, 0x2c, 0xc5, 0x1, 0x40, 0x16, 0xec, 0x4, 0x40, 0x0, 0x0, 0x3, 0x0, 0x40, 0x0, 0x0, 0xf, 0x23, 0xc6, 0xc, 0x65, 0x80, 0x1, 0x0, 0x5, 0x68, 0xe9, 0x2b, 0x2c, 0x8b, }; // Check to see if the OS we're running on should have // VideoDecodeAcceleration.framework installed. bool OSShouldHaveFramework() { // 10.6.2 and earlier doesn't have the framework. // If we ever drop 10.6 support and clean up IsOSSnowLeopard() calls, this // can be removed too. int32 major, minor, bugfix; base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); if (major == 10 && minor == 6 && bugfix <= 2) return false; return true; } // This function is provided as a callback for // VideoDecodeAccelerationSupport::Decode. It verifies that callback // arguments are correct and that the callback happened on the correct // thread. void FrameCallbackVerifier(bool* callback_done, MessageLoop* expected_loop, CVImageBufferRef image, int status) { EXPECT_EQ(kCallbackExpectedStatus, status); // Verify that the callback was invoked on the same thread that created the // VDAStatus object. EXPECT_EQ(expected_loop, MessageLoop::current()); *callback_done = true; } } // namespace namespace gfx { class VideoDecodeAccelerationSupportTest : public ui::CocoaTest { }; // Test that creating VideoDecodeAccelerationSupport works on hardware that // supports it. // http://crbug.com/103912 TEST_F(VideoDecodeAccelerationSupportTest, DISABLED_Create) { scoped_refptr vda( new gfx::VideoDecodeAccelerationSupport); gfx::VideoDecodeAccelerationSupport::Status status = vda->Create( kSampleWidth, kSampleHeight, kCVPixelFormatType_422YpCbCr8, kSampleAVCData, arraysize(kSampleAVCData)); // We should get an error loading the framework on 10.6.2 and earlier. if (!OSShouldHaveFramework()) { EXPECT_EQ(gfx::VideoDecodeAccelerationSupport::LOAD_FRAMEWORK_ERROR, status); return; } // If the hardware is not supported then there's not much we can do. if (status == gfx::VideoDecodeAccelerationSupport::HARDWARE_NOT_SUPPORTED_ERROR) { return; } EXPECT_EQ(gfx::VideoDecodeAccelerationSupport::SUCCESS, status); EXPECT_EQ(gfx::VideoDecodeAccelerationSupport::SUCCESS, vda->Flush(false)); EXPECT_EQ(gfx::VideoDecodeAccelerationSupport::SUCCESS, vda->Destroy()); } // Test that callback works. TEST_F(VideoDecodeAccelerationSupportTest, Callback) { MessageLoop loop; bool callback_done = false; scoped_refptr vda( new gfx::VideoDecodeAccelerationSupport); vda->frame_ready_callbacks_[kCallbackFrameID] = base::Bind( &FrameCallbackVerifier, &callback_done, &loop); base::Thread thread("calllback"); thread.Start(); NSDictionary* info = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCallbackFrameID] forKey:@"frame_id"]; thread.message_loop()->PostTask(FROM_HERE, base::Bind( &gfx::VideoDecodeAccelerationSupport::OnFrameReadyCallback, static_cast(vda.get()), base::mac::NSToCFCast(info), kCallbackExpectedStatus, 0, static_cast(NULL))); // Wait for the thread to complete. thread.Stop(); // Verify that the callback occured. EXPECT_FALSE(callback_done); loop.RunAllPending(); EXPECT_TRUE(callback_done); } } // namespace gfx