nihed-cros-libva: use simple error enum instead of anyhow crate
[nihav-player.git] / nihed-cros-libva / src / buffer.rs
CommitLineData
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
7mod h264;
8mod mpeg2;
9mod vp8;
10mod vp9;
11
12pub use h264::*;
13pub use mpeg2::*;
14pub use vp8::*;
15pub use vp9::*;
16
17use std::rc::Rc;
18
68362724 19use crate::bindings;
69e6ce02 20use crate::status::*;
68362724
KS
21use crate::Context;
22
23/// Wrapper type representing a buffer created with `vaCreateBuffer`.
24pub struct Buffer {
25 context: Rc<Context>,
26 id: bindings::VABufferID,
27}
28
29impl 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
128impl 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.
142pub 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
155impl 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.
169pub 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
181pub 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.
193pub 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}