nihed-cros-libva: get rid of log dependency
[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
19use anyhow::Result;
68362724
KS
20
21use crate::bindings;
22use crate::status::Status;
23use crate::Context;
24
25/// Wrapper type representing a buffer created with `vaCreateBuffer`.
26pub struct Buffer {
27 context: Rc<Context>,
28 id: bindings::VABufferID,
29}
30
31impl 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
130impl 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() {
51b33b65 138 println!("vaDestroyBuffer failed: {}", status.unwrap_err());
68362724
KS
139 }
140 }
141}
142
143/// Abstraction over `VABufferType`s.
144pub 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
157impl 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.
171pub 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
183pub 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.
195pub 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}