Commit | Line | Data |
---|---|---|
68362724 KS |
1 | // Copyright 2022 The ChromiumOS Authors |
2 | // Use of this source code is governed by a BSD-style license that can be | |
3 | // found in the LICENSE file. | |
4 | ||
5 | //! Wrappers and helpers around `VABuffer`s. | |
6 | ||
7 | mod h264; | |
8 | mod mpeg2; | |
9 | mod vp8; | |
10 | mod vp9; | |
11 | ||
12 | pub use h264::*; | |
13 | pub use mpeg2::*; | |
14 | pub use vp8::*; | |
15 | pub use vp9::*; | |
16 | ||
17 | use std::rc::Rc; | |
18 | ||
68362724 | 19 | use crate::bindings; |
69e6ce02 | 20 | use crate::status::*; |
68362724 KS |
21 | use crate::Context; |
22 | ||
23 | /// Wrapper type representing a buffer created with `vaCreateBuffer`. | |
24 | pub struct Buffer { | |
25 | context: Rc<Context>, | |
26 | id: bindings::VABufferID, | |
27 | } | |
28 | ||
29 | impl Buffer { | |
30 | /// Creates a new buffer by wrapping a `vaCreateBuffer` call. This is just a helper for | |
31 | /// [`Context::create_buffer`]. | |
69e6ce02 | 32 | pub(crate) fn new(context: Rc<Context>, mut type_: BufferType) -> VAResult<Self> { |
68362724 KS |
33 | let mut buffer_id = 0; |
34 | ||
35 | let (ptr, size) = match type_ { | |
36 | BufferType::PictureParameter(ref mut picture_param) => match picture_param { | |
37 | PictureParameter::MPEG2(ref mut wrapper) => ( | |
38 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
39 | std::mem::size_of_val(wrapper.inner_mut()), | |
40 | ), | |
41 | PictureParameter::VP8(ref mut wrapper) => ( | |
42 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
43 | std::mem::size_of_val(wrapper.inner_mut()), | |
44 | ), | |
45 | PictureParameter::VP9(ref mut wrapper) => ( | |
46 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
47 | std::mem::size_of_val(wrapper.inner_mut()), | |
48 | ), | |
49 | PictureParameter::H264(ref mut wrapper) => ( | |
50 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
51 | std::mem::size_of_val(wrapper.inner_mut()), | |
52 | ), | |
53 | }, | |
54 | ||
55 | BufferType::SliceParameter(ref mut slice_param) => match slice_param { | |
56 | SliceParameter::MPEG2(ref mut wrapper) => ( | |
57 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
58 | std::mem::size_of_val(wrapper.inner_mut()), | |
59 | ), | |
60 | SliceParameter::VP8(ref mut wrapper) => ( | |
61 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
62 | std::mem::size_of_val(wrapper.inner_mut()), | |
63 | ), | |
64 | SliceParameter::VP9(ref mut wrapper) => ( | |
65 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
66 | std::mem::size_of_val(wrapper.inner_mut()), | |
67 | ), | |
68 | SliceParameter::H264(ref mut wrapper) => ( | |
69 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
70 | std::mem::size_of_val(wrapper.inner_mut()), | |
71 | ), | |
72 | }, | |
73 | ||
74 | BufferType::IQMatrix(ref mut iq_matrix) => match iq_matrix { | |
75 | IQMatrix::MPEG2(ref mut wrapper) => ( | |
76 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
77 | std::mem::size_of_val(wrapper.inner_mut()), | |
78 | ), | |
79 | IQMatrix::VP8(ref mut wrapper) => ( | |
80 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
81 | std::mem::size_of_val(wrapper.inner_mut()), | |
82 | ), | |
83 | IQMatrix::H264(ref mut wrapper) => ( | |
84 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
85 | std::mem::size_of_val(wrapper.inner_mut()), | |
86 | ), | |
87 | }, | |
88 | ||
89 | BufferType::Probability(ref mut wrapper) => ( | |
90 | wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void, | |
91 | std::mem::size_of_val(wrapper.inner_mut()), | |
92 | ), | |
93 | ||
94 | BufferType::SliceData(ref mut data) => { | |
95 | (data.as_mut_ptr() as *mut std::ffi::c_void, data.len()) | |
96 | } | |
97 | }; | |
98 | ||
99 | // Safe because `self` represents a valid `VAContext`. `ptr` and `size` are also ensured to | |
100 | // be correct, as `ptr` is just a cast to `*c_void` from a Rust struct, and `size` is | |
101 | // computed from `std::mem::size_of_val`. | |
69e6ce02 | 102 | (unsafe { |
68362724 KS |
103 | bindings::vaCreateBuffer( |
104 | context.display().handle(), | |
105 | context.id(), | |
106 | type_.inner(), | |
107 | size as u32, | |
108 | 1, | |
109 | ptr, | |
110 | &mut buffer_id, | |
111 | ) | |
112 | }) | |
113 | .check()?; | |
114 | ||
115 | Ok(Self { | |
116 | context, | |
117 | id: buffer_id, | |
118 | }) | |
119 | } | |
120 | ||
121 | /// Convenience function to return a `VABufferID` vector from a slice of `Buffer`s in order to | |
122 | /// easily interface with the C API where a buffer array might be needed. | |
123 | pub fn as_id_vec(buffers: &[Self]) -> Vec<bindings::VABufferID> { | |
124 | buffers.iter().map(|buffer| buffer.id).collect() | |
125 | } | |
126 | } | |
127 | ||
128 | impl Drop for Buffer { | |
129 | fn drop(&mut self) { | |
130 | // Safe because `self` represents a valid buffer, created with | |
131 | // vaCreateBuffers. | |
132 | let status = | |
69e6ce02 | 133 | (unsafe { bindings::vaDestroyBuffer(self.context.display().handle(), self.id) }) |
68362724 KS |
134 | .check(); |
135 | if status.is_err() { | |
51b33b65 | 136 | println!("vaDestroyBuffer failed: {}", status.unwrap_err()); |
68362724 KS |
137 | } |
138 | } | |
139 | } | |
140 | ||
141 | /// Abstraction over `VABufferType`s. | |
142 | pub enum BufferType { | |
143 | /// Abstraction over `VAPictureParameterBufferType`. Needed for MPEG2, VP8, VP9, H264. | |
144 | PictureParameter(PictureParameter), | |
145 | /// Abstraction over `VASliceParameterBufferType`. Needed for MPEG2, VP8, VP9, H264. | |
146 | SliceParameter(SliceParameter), | |
147 | /// Abstraction over `VAIQMatrixBufferType`. Needed for VP8, H264. | |
148 | IQMatrix(IQMatrix), | |
149 | /// Abstraction over `VAProbabilityDataBufferType`. Needed for VP8. | |
150 | Probability(vp8::ProbabilityDataBufferVP8), | |
151 | /// Abstraction over `VASliceDataBufferType`. Needed for VP9, H264. | |
152 | SliceData(Vec<u8>), | |
153 | } | |
154 | ||
155 | impl BufferType { | |
156 | /// Returns the inner FFI buffer type. | |
157 | pub(crate) fn inner(&self) -> bindings::VABufferType::Type { | |
158 | match self { | |
159 | BufferType::PictureParameter(_) => bindings::VABufferType::VAPictureParameterBufferType, | |
160 | BufferType::SliceParameter(_) => bindings::VABufferType::VASliceParameterBufferType, | |
161 | BufferType::IQMatrix(_) => bindings::VABufferType::VAIQMatrixBufferType, | |
162 | BufferType::Probability(_) => bindings::VABufferType::VAProbabilityBufferType, | |
163 | BufferType::SliceData { .. } => bindings::VABufferType::VASliceDataBufferType, | |
164 | } | |
165 | } | |
166 | } | |
167 | ||
168 | /// Abstraction over the `PictureParameterBuffer` types we support. | |
169 | pub enum PictureParameter { | |
170 | /// Wrapper over VAPictureParameterBufferMPEG2. | |
171 | MPEG2(mpeg2::PictureParameterBufferMPEG2), | |
172 | /// Wrapper over VAPictureParameterBufferVP8. | |
173 | VP8(vp8::PictureParameterBufferVP8), | |
174 | /// Wrapper over VAPictureParameterBufferVP9. | |
175 | VP9(vp9::PictureParameterBufferVP9), | |
176 | /// Wrapper over VAPictureParameterBufferH264. | |
177 | H264(h264::PictureParameterBufferH264), | |
178 | } | |
179 | ||
180 | /// Abstraction over the `SliceParameterBuffer` types we support | |
181 | pub enum SliceParameter { | |
182 | /// Wrapper over VASliceParameterBufferMPEG2 | |
183 | MPEG2(mpeg2::SliceParameterBufferMPEG2), | |
184 | /// Wrapper over VASliceParameterBufferVP8 | |
185 | VP8(vp8::SliceParameterBufferVP8), | |
186 | /// Wrapper over VASliceParameterBufferVP9 | |
187 | VP9(vp9::SliceParameterBufferVP9), | |
188 | /// Wrapper over VASliceParameterBufferH264 | |
189 | H264(h264::SliceParameterBufferH264), | |
190 | } | |
191 | ||
192 | /// Abstraction over the `IQMatrixBuffer` types we support. | |
193 | pub enum IQMatrix { | |
194 | /// Abstraction over `VAIQMatrixBufferMPEG2` | |
195 | MPEG2(mpeg2::IQMatrixBufferMPEG2), | |
196 | /// Abstraction over `VAIQMatrixBufferVP8` | |
197 | VP8(vp8::IQMatrixBufferVP8), | |
198 | /// Abstraction over `VAIQMatrixBufferH264` | |
199 | H264(h264::IQMatrixBufferH264), | |
200 | } |