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