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