summaryrefslogtreecommitdiffstats
path: root/ui/gfx/video_decode_acceleration_support_mac_unittest.mm
blob: bcc06237d60d9ccbb98c0c262b512ccb35acb6a0 (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
// 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.
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