summaryrefslogtreecommitdiff
path: root/chromium/media/gpu/vaapi/vaapi_utils.h
blob: d6cb58aa527b6a75015169cecebb37c26e081829 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright 2018 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.

#ifndef MEDIA_GPU_VAAPI_VAAPI_UTILS_H_
#define MEDIA_GPU_VAAPI_VAAPI_UTILS_H_

#include "base/bind_helpers.h"
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/thread_annotations.h"
#include "ui/gfx/geometry/size.h"

// Forward declarations taken verbatim from <va/va.h>
typedef unsigned int VABufferID;
typedef void* VADisplay;
typedef struct _VAImage VAImage;
typedef struct _VAImageFormat VAImageFormat;
typedef int VAStatus;
typedef unsigned int VASurfaceID;

namespace base {
class Lock;
}

namespace media {
class VaapiWrapper;
class Vp8ReferenceFrameVector;
struct VAContextAndScopedVASurfaceDeleter;
struct Vp8FrameHeader;

// Class to map a given VABuffer, identified by |buffer_id|, for its lifetime.
// This class must operate under |lock_| acquired.
class ScopedVABufferMapping {
 public:
  // |release_callback| will be called if the mapping of the buffer failed.
  ScopedVABufferMapping(const base::Lock* lock,
                        VADisplay va_display,
                        VABufferID buffer_id,
                        base::OnceCallback<void(VABufferID)> release_callback =
                            base::NullCallback());
  ~ScopedVABufferMapping();
  bool IsValid() const { return !!va_buffer_data_; }
  void* data() const {
    DCHECK(IsValid());
    return va_buffer_data_;
  }
  // Explicit destruction method, to retrieve the success/error result. It is
  // safe to call this method several times.
  VAStatus Unmap();

 private:
  const base::Lock* lock_;  // Only for AssertAcquired() calls.
  const VADisplay va_display_;
  const VABufferID buffer_id_;

  void* va_buffer_data_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(ScopedVABufferMapping);
};

// This class tracks the VAImage life cycle from vaCreateImage() - vaGetImage()
// to vaDestroyImage(). In between creation and destruction, image()->buf  will
// try to be be mapped on user space using a ScopedVABufferMapping. All
// resources will be cleaned up appropriately. |lock| is acquired for
// destruction purposes.
class ScopedVAImage {
 public:
  ScopedVAImage(base::Lock* lock,
                VADisplay va_display,
                VASurfaceID va_surface_id,
                VAImageFormat* format /* Needs to be a pointer for libva */,
                const gfx::Size& size);
  ~ScopedVAImage();

  bool IsValid() const { return va_buffer_ && va_buffer_->IsValid(); }

  const VAImage* image() const { return image_.get(); }
  const ScopedVABufferMapping* va_buffer() const {
    DCHECK(IsValid());
    return va_buffer_.get();
  }

 private:
  base::Lock* lock_;
  const VADisplay va_display_ GUARDED_BY(lock_);
  std::unique_ptr<VAImage> image_;
  std::unique_ptr<ScopedVABufferMapping> va_buffer_;

  DISALLOW_COPY_AND_ASSIGN(ScopedVAImage);
};

// A VA-API-specific surface used by video/image codec accelerators to work on.
// As the name suggests, this class is self-cleaning.
class ScopedVASurface {
 public:
  ScopedVASurface(scoped_refptr<VaapiWrapper> vaapi_wrapper,
                  VASurfaceID va_surface_id,
                  const gfx::Size& size,
                  unsigned int va_rt_format);
  ~ScopedVASurface();

  bool IsValid() const;
  VASurfaceID id() const { return va_surface_id_; }
  const gfx::Size& size() const { return size_; }
  unsigned int format() const { return va_rt_format_; }

 private:
  friend struct VAContextAndScopedVASurfaceDeleter;
  const scoped_refptr<VaapiWrapper> vaapi_wrapper_;
  const VASurfaceID va_surface_id_;
  const gfx::Size size_;
  const unsigned int va_rt_format_;

  DISALLOW_COPY_AND_ASSIGN(ScopedVASurface);
};

// A combination of a numeric ID |id| and a callback to release it. This class
// makes no assumptions on threading or lifetimes; |release_cb_| must provide
// for this.
// ScopedID allows for object-specific release callbacks, whereas
// unique_ptr::deleter_type (or base::ScopedGeneric) only supports free
// functions (or class-static methods) for freeing.
template <typename T>
class ScopedID {
 public:
  using ReleaseCB = base::OnceCallback<void(T)>;

  ScopedID(T id, ReleaseCB release_cb)
      : id_(id), release_cb_(std::move(release_cb)) {
    DCHECK(release_cb_);
    static_assert(std::is_integral<T>::value, "T must be a numeric type.");
  }
  ~ScopedID() { std::move(release_cb_).Run(id_); }

  ScopedID& operator=(const ScopedID&) = delete;
  ScopedID(const ScopedID&) = delete;

  T id() const { return id_; }

 private:
  const T id_;
  ReleaseCB release_cb_;
};

// Adapts |frame_header| to the Vaapi data types, prepping it for consumption by
// |vaapi_wrapper|
bool FillVP8DataStructures(VaapiWrapper* vaapi_wrapper,
                           VASurfaceID va_surface_id,
                           const Vp8FrameHeader& frame_header,
                           const Vp8ReferenceFrameVector& reference_frames);
}  // namespace media

#endif  // MEDIA_GPU_VAAPI_VAAPI_UTILS_H_