Skip to main content

moq_vaapi/
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#[cfg(libva_1_14_or_higher)]
8mod av1;
9mod enc_jpeg;
10mod enc_misc;
11mod h264;
12mod hevc;
13mod jpeg_baseline;
14mod mpeg2;
15mod proc_pipeline;
16mod vp8;
17mod vp9;
18
19#[cfg(libva_1_14_or_higher)]
20pub use av1::*;
21pub use enc_jpeg::*;
22pub use enc_misc::*;
23pub use h264::*;
24pub use hevc::*;
25pub use jpeg_baseline::*;
26pub use mpeg2::*;
27pub use proc_pipeline::*;
28pub use vp8::*;
29pub use vp9::*;
30
31use std::rc::Rc;
32
33use log::error;
34
35use crate::bindings;
36use crate::va_check;
37use crate::Context;
38use crate::VaError;
39
40/// Wrapper type representing a buffer created with `vaCreateBuffer`.
41pub struct Buffer {
42	context: Rc<Context>,
43	id: bindings::VABufferID,
44}
45
46impl Buffer {
47	/// Creates a new buffer by wrapping a `vaCreateBuffer` call. This is just a helper for
48	/// [`Context::create_buffer`].
49	pub(crate) fn new(context: Rc<Context>, mut type_: BufferType) -> Result<Self, VaError> {
50		let mut buffer_id = 0;
51
52		/* we send all slices parameters as a single array in H264, AV1 */
53		let nb_elements = match type_ {
54			BufferType::SliceParameter(SliceParameter::H264(ref mut params)) => params.inner_mut().len(),
55			#[cfg(libva_1_14_or_higher)]
56			BufferType::SliceParameter(SliceParameter::AV1(ref mut params)) => params.inner_mut().len(),
57			_ => 1,
58		};
59
60		let (ptr, size) = match type_ {
61			BufferType::PictureParameter(ref mut picture_param) => match picture_param {
62				PictureParameter::MPEG2(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				PictureParameter::VP8(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				PictureParameter::VP9(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				PictureParameter::H264(ref mut wrapper) => (
75					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
76					std::mem::size_of_val(wrapper.inner_mut()),
77				),
78				PictureParameter::HEVC(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				PictureParameter::HEVCRext(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				PictureParameter::HEVCScc(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				#[cfg(libva_1_14_or_higher)]
91				PictureParameter::AV1(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				PictureParameter::JPEGBaseline(ref mut wrapper) => (
96					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
97					std::mem::size_of_val(wrapper.inner_mut()),
98				),
99				PictureParameter::EncJPEG(ref mut wrapper) => (
100					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
101					std::mem::size_of_val(wrapper.inner_mut()),
102				),
103			},
104
105			BufferType::SliceParameter(ref mut slice_param) => match slice_param {
106				SliceParameter::MPEG2(ref mut wrapper) => (
107					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
108					std::mem::size_of_val(wrapper.inner_mut()),
109				),
110				SliceParameter::VP8(ref mut wrapper) => (
111					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
112					std::mem::size_of_val(wrapper.inner_mut()),
113				),
114				SliceParameter::VP9(ref mut wrapper) => (
115					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
116					std::mem::size_of_val(wrapper.inner_mut()),
117				),
118				SliceParameter::H264(ref mut wrapper) => (
119					wrapper.inner_mut().as_mut_ptr() as *mut std::ffi::c_void,
120					std::mem::size_of::<bindings::VASliceParameterBufferH264>(),
121				),
122				SliceParameter::HEVC(ref mut wrapper) => (
123					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
124					std::mem::size_of_val(wrapper.inner_mut()),
125				),
126				SliceParameter::HEVCRext(ref mut wrapper) => (
127					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
128					std::mem::size_of_val(wrapper.inner_mut()),
129				),
130				#[cfg(libva_1_14_or_higher)]
131				SliceParameter::AV1(ref mut wrapper) => (
132					wrapper.inner_mut().as_mut_ptr() as *mut std::ffi::c_void,
133					std::mem::size_of::<bindings::VASliceParameterBufferAV1>(),
134				),
135				SliceParameter::JPEGBaseline(ref mut wrapper) => (
136					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
137					std::mem::size_of_val(wrapper.inner_mut()),
138				),
139				SliceParameter::EncJpeg(ref mut wrapper) => (
140					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
141					std::mem::size_of_val(wrapper.inner_mut()),
142				),
143			},
144
145			BufferType::IQMatrix(ref mut iq_matrix) => match iq_matrix {
146				IQMatrix::MPEG2(ref mut wrapper) => (
147					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
148					std::mem::size_of_val(wrapper.inner_mut()),
149				),
150				IQMatrix::VP8(ref mut wrapper) => (
151					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
152					std::mem::size_of_val(wrapper.inner_mut()),
153				),
154				IQMatrix::H264(ref mut wrapper) => (
155					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
156					std::mem::size_of_val(wrapper.inner_mut()),
157				),
158				IQMatrix::HEVC(ref mut wrapper) => (
159					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
160					std::mem::size_of_val(wrapper.inner_mut()),
161				),
162				IQMatrix::JPEGBaseline(ref mut wrapper) => (
163					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
164					std::mem::size_of_val(wrapper.inner_mut()),
165				),
166			},
167
168			BufferType::HuffmanTable(ref mut huffman_table) => match huffman_table {
169				HuffmanTable::JPEGBaseline(ref mut wrapper) => (
170					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
171					std::mem::size_of_val(wrapper.inner_mut()),
172				),
173			},
174
175			BufferType::Probability(ref mut wrapper) => (
176				wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
177				std::mem::size_of_val(wrapper.inner_mut()),
178			),
179
180			BufferType::SliceData(ref mut data) => (data.as_mut_ptr() as *mut std::ffi::c_void, data.len()),
181
182			BufferType::EncSequenceParameter(ref mut seq_param) => match seq_param {
183				EncSequenceParameter::H264(ref mut wrapper) => (
184					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
185					std::mem::size_of_val(wrapper.inner_mut()),
186				),
187				EncSequenceParameter::HEVC(ref mut wrapper) => (
188					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
189					std::mem::size_of_val(wrapper.inner_mut()),
190				),
191				EncSequenceParameter::VP8(ref mut wrapper) => (
192					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
193					std::mem::size_of_val(wrapper.inner_mut()),
194				),
195				EncSequenceParameter::VP9(ref mut wrapper) => (
196					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
197					std::mem::size_of_val(wrapper.inner_mut()),
198				),
199				#[cfg(libva_1_14_or_higher)]
200				EncSequenceParameter::AV1(ref mut wrapper) => (
201					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
202					std::mem::size_of_val(wrapper.inner_mut()),
203				),
204			},
205
206			BufferType::EncPictureParameter(ref mut picture_param) => match picture_param {
207				EncPictureParameter::H264(ref mut wrapper) => (
208					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
209					std::mem::size_of_val(wrapper.inner_mut()),
210				),
211				EncPictureParameter::HEVC(ref mut wrapper) => (
212					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
213					std::mem::size_of_val(wrapper.inner_mut()),
214				),
215				EncPictureParameter::VP8(ref mut wrapper) => (
216					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
217					std::mem::size_of_val(wrapper.inner_mut()),
218				),
219				EncPictureParameter::VP9(ref mut wrapper) => (
220					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
221					std::mem::size_of_val(wrapper.inner_mut()),
222				),
223				#[cfg(libva_1_14_or_higher)]
224				EncPictureParameter::AV1(ref mut wrapper) => (
225					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
226					std::mem::size_of_val(wrapper.inner_mut()),
227				),
228			},
229
230			BufferType::EncSliceParameter(ref mut slice_param) => match slice_param {
231				EncSliceParameter::H264(ref mut wrapper) => (
232					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
233					std::mem::size_of_val(wrapper.inner_mut()),
234				),
235				EncSliceParameter::HEVC(ref mut wrapper) => (
236					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
237					std::mem::size_of_val(wrapper.inner_mut()),
238				),
239				#[cfg(libva_1_14_or_higher)]
240				EncSliceParameter::AV1(ref mut wrapper) => (
241					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
242					std::mem::size_of_val(wrapper.inner_mut()),
243				),
244			},
245
246			BufferType::EncMacroblockParameterBuffer(ref mut mb_param) => match mb_param {
247				EncMacroblockParameterBuffer::H264(ref mut wrapper) => (
248					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
249					std::mem::size_of_val(wrapper.inner_mut()),
250				),
251			},
252
253			BufferType::EncCodedBuffer(size) => (std::ptr::null_mut(), size),
254
255			BufferType::EncMiscParameter(ref mut enc_misc_param) => match enc_misc_param {
256				EncMiscParameter::FrameRate(ref mut wrapper) => (
257					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
258					std::mem::size_of_val(wrapper.inner_mut()),
259				),
260				EncMiscParameter::RateControl(ref mut wrapper) => (
261					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
262					std::mem::size_of_val(wrapper.inner_mut()),
263				),
264				EncMiscParameter::MaxSliceSize(ref mut wrapper) => (
265					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
266					std::mem::size_of_val(wrapper.inner_mut()),
267				),
268				EncMiscParameter::MaxFrameSize(ref mut wrapper) => (
269					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
270					std::mem::size_of_val(wrapper.inner_mut()),
271				),
272				EncMiscParameter::SkipFrame(ref mut wrapper) => (
273					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
274					std::mem::size_of_val(wrapper.inner_mut()),
275				),
276				EncMiscParameter::HRD(ref mut wrapper) => (
277					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
278					std::mem::size_of_val(wrapper.inner_mut()),
279				),
280				EncMiscParameter::QualityLevel(ref mut wrapper) => (
281					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
282					std::mem::size_of_val(wrapper.inner_mut()),
283				),
284				EncMiscParameter::Quantization(ref mut wrapper) => (
285					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
286					std::mem::size_of_val(wrapper.inner_mut()),
287				),
288			},
289			BufferType::ProcPipelineParameter(ref mut proc_pipeline_param) => (
290				proc_pipeline_param.inner_mut() as *mut _ as *mut std::ffi::c_void,
291				std::mem::size_of_val(proc_pipeline_param.inner_mut()),
292			),
293			BufferType::QMatrix(ref mut q_matrix) => match q_matrix {
294				QMatrix::JPEG(ref mut wrapper) => (
295					wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
296					std::mem::size_of_val(wrapper.inner_mut()),
297				),
298			},
299			BufferType::EncPackedHeaderParameter(ref mut wrapper) => (
300				wrapper.inner_mut() as *mut _ as *mut std::ffi::c_void,
301				std::mem::size_of_val(wrapper.inner_mut()),
302			),
303
304			BufferType::EncPackedHeaderData(ref data) => (data.as_ptr() as *mut std::ffi::c_void, data.len()),
305		};
306
307		// Safe because `self` represents a valid `VAContext`. `ptr` and `size` are also ensured to
308		// be correct, as `ptr` is just a cast to `*c_void` from a Rust struct, and `size` is
309		// computed from `std::mem::size_of_val`.
310		va_check(unsafe {
311			bindings::vaCreateBuffer(
312				context.display().handle(),
313				context.id(),
314				type_.inner(),
315				size as u32,
316				nb_elements as u32,
317				ptr,
318				&mut buffer_id,
319			)
320		})?;
321
322		Ok(Self { context, id: buffer_id })
323	}
324
325	/// Convenience function to return a `VABufferID` vector from a slice of `Buffer`s in order to
326	/// easily interface with the C API where a buffer array might be needed.
327	pub fn as_id_vec(buffers: &[Self]) -> Vec<bindings::VABufferID> {
328		buffers.iter().map(|buffer| buffer.id).collect()
329	}
330}
331
332impl Drop for Buffer {
333	fn drop(&mut self) {
334		// Safe because `self` represents a valid buffer, created with
335		// vaCreateBuffers.
336		let status = va_check(unsafe { bindings::vaDestroyBuffer(self.context.display().handle(), self.id) });
337
338		if status.is_err() {
339			error!("vaDestroyBuffer failed: {}", status.unwrap_err());
340		}
341	}
342}
343
344/// Abstraction over `VABufferType`s.
345pub enum BufferType {
346	/// Abstraction over `VAPictureParameterBufferType`. Needed for MPEG2, VP8, VP9, H264, JPEGBaseline.
347	PictureParameter(PictureParameter),
348	/// Abstraction over `VASliceParameterBufferType`. Needed for MPEG2, VP8, VP9, H264, JPEGBaseline.
349	SliceParameter(SliceParameter),
350	/// Abstraction over `VAIQMatrixBufferType`. Needed for VP8, H264, JPEGBaseline.
351	IQMatrix(IQMatrix),
352	/// Abstraction over `HuffmanTableBufferType`. Needed for JPEGBaseline.
353	HuffmanTable(HuffmanTable),
354	/// Abstraction over `VAProbabilityDataBufferType`. Needed for VP8.
355	Probability(vp8::ProbabilityDataBufferVP8),
356	/// Abstraction over `VASliceDataBufferType`. Needed for VP9, H264.
357	SliceData(Vec<u8>),
358	/// Abstraction over `VAEncSequenceParameterBufferType`. Needed for MPEG2, VP8, VP9, H264, HEVC.
359	EncSequenceParameter(EncSequenceParameter),
360	/// Abstraction over `VAEncPictureParameterBufferType`. Needed for MPEG2, VP8, VP9, H264, HEVC.
361	EncPictureParameter(EncPictureParameter),
362	/// Abstraction over `VAEncSliceParameterBufferType`. Needed for MPEG2, VP8, VP9, H264, HEVC.
363	EncSliceParameter(EncSliceParameter),
364	/// Abstraction over `VAEncMacroblockMapBufferType`. Needed for H264.
365	EncMacroblockParameterBuffer(EncMacroblockParameterBuffer),
366	/// Abstraction over `VAEncCodedBufferType`. Needed for MPEG2, VP8, VP9, H264, HEVC.
367	EncCodedBuffer(usize),
368	/// Abstraction over `VAEncMiscParameterBuffer`.
369	EncMiscParameter(EncMiscParameter),
370	/// Abstraction over `VAProcPipelineParameterBuffer`.
371	ProcPipelineParameter(proc_pipeline::ProcPipelineParameterBuffer),
372	/// Abstraction over `VAQMatrixBufferType`.
373	QMatrix(QMatrix),
374	/// Abstraction over `VAEncPackedHeaderParameterBufferType`.
375	EncPackedHeaderParameter(EncPackedHeaderParameter),
376	/// Abstraction over `VAEncPackedHeaderDataBufferType`.
377	EncPackedHeaderData(Vec<u8>),
378}
379
380impl BufferType {
381	/// Returns the inner FFI buffer type.
382	pub(crate) fn inner(&self) -> bindings::VABufferType::Type {
383		match self {
384			BufferType::PictureParameter(_) => bindings::VABufferType::VAPictureParameterBufferType,
385			BufferType::SliceParameter(_) => bindings::VABufferType::VASliceParameterBufferType,
386			BufferType::IQMatrix(_) => bindings::VABufferType::VAIQMatrixBufferType,
387			BufferType::HuffmanTable(_) => bindings::VABufferType::VAHuffmanTableBufferType,
388			BufferType::Probability(_) => bindings::VABufferType::VAProbabilityBufferType,
389			BufferType::SliceData { .. } => bindings::VABufferType::VASliceDataBufferType,
390
391			BufferType::EncSequenceParameter(_) => bindings::VABufferType::VAEncSequenceParameterBufferType,
392
393			BufferType::EncPictureParameter(_) => bindings::VABufferType::VAEncPictureParameterBufferType,
394
395			BufferType::EncSliceParameter(_) => bindings::VABufferType::VAEncSliceParameterBufferType,
396
397			BufferType::EncMacroblockParameterBuffer(_) => bindings::VABufferType::VAEncMacroblockMapBufferType,
398
399			BufferType::EncCodedBuffer(_) => bindings::VABufferType::VAEncCodedBufferType,
400
401			BufferType::EncMiscParameter(_) => bindings::VABufferType::VAEncMiscParameterBufferType,
402
403			BufferType::ProcPipelineParameter(_) => bindings::VABufferType::VAProcPipelineParameterBufferType,
404
405			BufferType::QMatrix(_) => bindings::VABufferType::VAQMatrixBufferType,
406
407			BufferType::EncPackedHeaderParameter(_) => bindings::VABufferType::VAEncPackedHeaderParameterBufferType,
408
409			BufferType::EncPackedHeaderData(_) => bindings::VABufferType::VAEncPackedHeaderDataBufferType,
410		}
411	}
412}
413
414/// Abstraction over the `PictureParameterBuffer` types we support.
415pub enum PictureParameter {
416	/// Wrapper over VAPictureParameterBufferMPEG2.
417	MPEG2(mpeg2::PictureParameterBufferMPEG2),
418	/// Wrapper over VAPictureParameterBufferVP8.
419	VP8(vp8::PictureParameterBufferVP8),
420	/// Wrapper over VAPictureParameterBufferVP9.
421	VP9(vp9::PictureParameterBufferVP9),
422	/// Wrapper over VAPictureParameterBufferH264.
423	H264(h264::PictureParameterBufferH264),
424	/// Wrapper over VAPictureParameterBufferHEVC
425	HEVC(hevc::PictureParameterBufferHEVC),
426	/// Wrapper over VAPictureParameterBufferHEVCRext
427	HEVCRext(hevc::PictureParameterBufferHEVCRext),
428	/// Wrapper over VAPictureParameterBufferHEVCScc
429	HEVCScc(hevc::PictureParameterBufferHEVCScc),
430	#[cfg(libva_1_14_or_higher)]
431	/// Wrapper over VADecPictureParameterBufferAV1
432	AV1(av1::PictureParameterBufferAV1),
433	/// Wrapper over VAPictureParameterBufferJPEGBaseline
434	JPEGBaseline(jpeg_baseline::PictureParameterBufferJPEGBaseline),
435	/// Wrapper over VAEncPictureParameterBufferJPEG
436	EncJPEG(enc_jpeg::EncPictureParameterBufferJPEG),
437}
438
439/// Abstraction over the `SliceParameterBuffer` types we support
440pub enum SliceParameter {
441	/// Wrapper over VASliceParameterBufferMPEG2
442	MPEG2(mpeg2::SliceParameterBufferMPEG2),
443	/// Wrapper over VASliceParameterBufferVP8
444	VP8(vp8::SliceParameterBufferVP8),
445	/// Wrapper over VASliceParameterBufferVP9
446	VP9(vp9::SliceParameterBufferVP9),
447	/// Wrapper over VASliceParameterBufferH264
448	H264(h264::SliceParameterBufferH264),
449	/// Wrapper over VASliceParameterBufferHEVC
450	HEVC(hevc::SliceParameterBufferHEVC),
451	/// Wrapper over VASliceParameterBufferHEVCRext
452	HEVCRext(hevc::SliceParameterBufferHEVCRext),
453	#[cfg(libva_1_14_or_higher)]
454	/// Wrapper over VASliceParameterBufferAV1
455	AV1(av1::SliceParameterBufferAV1),
456	/// Wrapper over VASliceParameterBufferJPEGBaseline
457	JPEGBaseline(jpeg_baseline::SliceParameterBufferJPEGBaseline),
458	/// Wrapper over VAEncSliceParameterBufferJPEG
459	EncJpeg(enc_jpeg::EncSliceParameterBufferJPEG),
460}
461
462/// Abstraction over the `IQMatrixBuffer` types we support.
463pub enum IQMatrix {
464	/// Abstraction over `VAIQMatrixBufferMPEG2`
465	MPEG2(mpeg2::IQMatrixBufferMPEG2),
466	/// Abstraction over `VAIQMatrixBufferVP8`
467	VP8(vp8::IQMatrixBufferVP8),
468	/// Abstraction over `VAIQMatrixBufferH264`
469	H264(h264::IQMatrixBufferH264),
470	/// Abstraction over `VAIQMatrixBufferHEVC`
471	HEVC(hevc::IQMatrixBufferHEVC),
472	/// Abstraction over `VAIQMatrixBufferJPEGBaseline``
473	JPEGBaseline(jpeg_baseline::IQMatrixBufferJPEGBaseline),
474}
475
476/// Abstraction over the `HuffmanTable` types we support.
477pub enum HuffmanTable {
478	/// Abstraction over `VAHuffmanTableBufferJPEGBaseline`
479	JPEGBaseline(jpeg_baseline::HuffmanTableBufferJPEGBaseline),
480}
481
482/// Abstraction over the `QMatrix` types we support.
483pub enum QMatrix {
484	/// Abstraction over `VAQMatrixBufferJPEG`
485	JPEG(enc_jpeg::QMatrixBufferJPEG),
486}
487
488/// Abstraction over the `EncSequenceParameter` types we support.
489pub enum EncSequenceParameter {
490	/// Abstraction over `VAEncSequenceParameterBufferH264`
491	H264(h264::EncSequenceParameterBufferH264),
492	/// Abstraction over `VAEncSequenceParameterBufferHEVC`
493	HEVC(hevc::EncSequenceParameterBufferHEVC),
494	/// Abstraction over `VAEncSequenceParameterBufferVP8`
495	VP8(vp8::EncSequenceParameterBufferVP8),
496	/// Abstraction over `VAEncSequenceParameterBufferVP9`
497	VP9(vp9::EncSequenceParameterBufferVP9),
498	#[cfg(libva_1_14_or_higher)]
499	/// Abstraction over `VAEncSequenceParameterBufferAV1`
500	AV1(av1::EncSequenceParameterBufferAV1),
501}
502
503/// Abstraction over the `EncPictureParameter` types we support.
504pub enum EncPictureParameter {
505	/// Abstraction over `VAEncPictureParameterBufferH264`
506	H264(h264::EncPictureParameterBufferH264),
507	/// Abstraction over `VAEncPictureParameterBufferHEVC`
508	HEVC(hevc::EncPictureParameterBufferHEVC),
509	/// Abstraction over `VAEncPictureParameterBufferVP8`
510	VP8(vp8::EncPictureParameterBufferVP8),
511	/// Abstraction over `VAEncPictureParameterBufferVP9`
512	VP9(vp9::EncPictureParameterBufferVP9),
513	#[cfg(libva_1_14_or_higher)]
514	/// Abstraction over `VAEncPictureParameterBufferAV1`
515	AV1(av1::EncPictureParameterBufferAV1),
516}
517
518/// Abstraction over the `EncSliceParameter` types we support.
519pub enum EncSliceParameter {
520	/// Abstraction over `VAEncSliceParameterBufferH264`
521	H264(h264::EncSliceParameterBufferH264),
522	/// Abstraction over `VAEncSliceParameterBufferHEVC`
523	HEVC(hevc::EncSliceParameterBufferHEVC),
524	#[cfg(libva_1_14_or_higher)]
525	/// Abstraction over `VAEncTileGroupBufferAV1`
526	AV1(av1::EncTileGroupBufferAV1),
527}
528
529/// Abstraction over the `EncMacroblockParameterBuffer` types we support.
530pub enum EncMacroblockParameterBuffer {
531	/// Abstraction over `VAEncMacroblockParameterBufferH264`
532	H264(h264::EncMacroblockParameterBufferH264),
533}
534
535/// Wrapper type representing a buffer created with `vaCreateBuffer` with VAEncCodedBufferType.
536pub struct EncCodedBuffer(Buffer);
537
538impl EncCodedBuffer {
539	pub(crate) fn new(context: Rc<Context>, size: usize) -> Result<Self, VaError> {
540		Ok(Self(Buffer::new(context, BufferType::EncCodedBuffer(size))?))
541	}
542
543	/// Convenience function to return buffer's `VABufferID`.
544	pub fn id(&self) -> bindings::VABufferID {
545		self.0.id
546	}
547}
548
549/// Helper to access a single segment of mapped coded buffer
550pub struct MappedCodedSegment<'s> {
551	pub bit_offset: u32,
552	pub status: u32,
553	pub buf: &'s [u8],
554}
555
556/// Helper to access segments of mapped coded buffer
557pub struct MappedCodedBuffer<'p> {
558	segments: Vec<MappedCodedSegment<'p>>,
559	buffer: &'p EncCodedBuffer,
560}
561
562impl<'p> MappedCodedBuffer<'p> {
563	/// Map a 'VAEncCodedBufferType' buffer.
564	pub fn new(buffer: &'p EncCodedBuffer) -> Result<Self, VaError> {
565		let mut addr = std::ptr::null_mut();
566		let mut segments = Vec::new();
567
568		va_check(unsafe { bindings::vaMapBuffer(buffer.0.context.display().handle(), buffer.id(), &mut addr) })?;
569
570		while !addr.is_null() {
571			let segment: &bindings::VACodedBufferSegment = unsafe { &*(addr as *const bindings::VACodedBufferSegment) };
572
573			let size = segment.size;
574			let buf = segment.buf;
575
576			let buf = unsafe { std::slice::from_raw_parts(buf as *mut u8, size as usize) };
577
578			segments.push(MappedCodedSegment {
579				bit_offset: segment.bit_offset,
580				status: segment.status,
581				buf,
582			});
583
584			addr = segment.next;
585		}
586
587		Ok(Self { segments, buffer })
588	}
589
590	/// Returns the iterator over segments
591	pub fn iter(&self) -> impl Iterator<Item = &MappedCodedSegment<'p>> {
592		self.segments.iter()
593	}
594
595	/// Returns the segments of mapped coded buffers.
596	pub fn segments(&self) -> &Vec<MappedCodedSegment<'p>> {
597		&self.segments
598	}
599}
600
601impl<'p> Drop for MappedCodedBuffer<'p> {
602	fn drop(&mut self) {
603		let status =
604			va_check(unsafe { bindings::vaUnmapBuffer(self.buffer.0.context.display().handle(), self.buffer.id()) });
605
606		if status.is_err() {
607			error!("vaUnmapBuffer failed: {}", status.unwrap_err());
608		}
609	}
610}
611
612/// Abstraction over the `EncMiscParameterBuffer` types we support.
613pub enum EncMiscParameter {
614	/// Wrapper over `VAEncMiscParameterBuffer` with `VAEncMiscParameterFrameRate`.
615	FrameRate(EncMiscParameterFrameRate),
616	/// Wrapper over `VAEncMiscParameterBuffer` with `VAEncMiscParameterRateControl`.
617	RateControl(EncMiscParameterRateControl),
618	/// Wrapper over `VAEncMiscParameterBuffer` with `VAEncMiscParameterMaxSliceSize`.
619	MaxSliceSize(EncMiscParameterMaxSliceSize),
620	/// Wrapper over `VAEncMiscParameterBuffer` with `VAEncMiscParameterBufferMaxFrameSize`.
621	MaxFrameSize(EncMiscParameterBufferMaxFrameSize),
622	/// Wrapper over `VAEncMiscParameterBuffer` with `VAEncMiscParameterSkipFrame`.
623	SkipFrame(EncMiscParameterSkipFrame),
624	/// Wrapper over `VAEncMiscParameterBuffer` with `VAEncMiscParameterHRD`.
625	HRD(EncMiscParameterHRD),
626	/// Wrapper over `VAEncMiscParameterBuffer` with `VAEncMiscParameterBufferQualityLevel`.
627	QualityLevel(EncMiscParameterBufferQualityLevel),
628	/// Wrapper over `VAEncMiscParameterBuffer` with `VAEncMiscParameterQuantization`.
629	Quantization(EncMiscParameterQuantization),
630}
631
632/// Abstraction over the `VAEncPackedHeaderType` enum values we support.
633#[repr(u32)]
634pub enum EncPackedHeaderType {
635	/// Sequence header
636	Sequence = bindings::VAEncPackedHeaderType::VAEncPackedHeaderSequence,
637	/// Picture header
638	Picture = bindings::VAEncPackedHeaderType::VAEncPackedHeaderPicture,
639	/// Slice header
640	Slice = bindings::VAEncPackedHeaderType::VAEncPackedHeaderSlice,
641	/// Raw data
642	RawData = bindings::VAEncPackedHeaderType::VAEncPackedHeaderRawData,
643}
644
645/// Abstraction over `EncPackedHeaderParameterBuffer` types we support
646pub struct EncPackedHeaderParameter(Box<bindings::VAEncPackedHeaderParameterBuffer>);
647
648impl EncPackedHeaderParameter {
649	/// Creates a new `EncPackedHeaderParameter` from the given `VAEncPackedHeaderParameterBuffer`.
650	pub fn new(type_: EncPackedHeaderType, length_in_bits: u32, has_emulation: bool) -> Self {
651		Self(Box::new(bindings::VAEncPackedHeaderParameterBuffer {
652			type_: type_ as _,
653			bit_length: length_in_bits,
654			has_emulation_bytes: has_emulation as u8,
655			..Default::default()
656		}))
657	}
658
659	/// Returns a mutable reference to the inner `VAEncPackedHeaderParameterBuffer`.
660	pub fn inner_mut(&mut self) -> &mut bindings::VAEncPackedHeaderParameterBuffer {
661		&mut self.0
662	}
663}