summaryrefslogtreecommitdiffstats
path: root/ui/gfx/video_decode_acceleration_support_mac_unittest.mm
blob: fa73b8367b0ba6c93adfda1e14adac73ef0a3229 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// 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"
#import "base/mac/mac_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() {
  if (base::mac::IsOSLeopardOrEarlier())
    return false;

  // 10.6.2 and earlier doesn't have the framework.
  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.
TEST_F(VideoDecodeAccelerationSupportTest, Create) {
  scoped_refptr<gfx::VideoDecodeAccelerationSupport> 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<gfx::VideoDecodeAccelerationSupport> 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<void*>(vda.get()),
      base::mac::NSToCFCast(info), kCallbackExpectedStatus, 0,
      static_cast<CVImageBufferRef>(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