start work on nihed-cros-libva
[nihav-player.git] / nihed-cros-libva / src / context.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
5use std::rc::Rc;
6
7use anyhow::Result;
8use log::error;
9
10use crate::bindings;
11use crate::buffer::Buffer;
12use crate::buffer::BufferType;
13use crate::display::Display;
14use crate::status::Status;
15use crate::Config;
16use crate::Surface;
17
18/// A VA context for a particular [`Display`].
19pub struct Context {
20 display: Rc<Display>,
21 id: bindings::VAContextID,
22}
23
24impl Context {
25 /// Creates a Context by wrapping around a `vaCreateContext` call. This is just a helper for
26 /// [`Display::create_context`].
27 pub(crate) fn new(
28 display: Rc<Display>,
29 config: &Config,
30 coded_width: i32,
31 coded_height: i32,
32 surfaces: Option<&Vec<Surface>>,
33 progressive: bool,
34 ) -> Result<Rc<Self>> {
35 let mut context_id = 0;
36 let flags = if progressive {
37 bindings::constants::VA_PROGRESSIVE as i32
38 } else {
39 0
40 };
41
42 let mut render_targets = match surfaces {
43 Some(surfaces) => Surface::as_id_vec(surfaces),
44 None => Default::default(),
45 };
46
47 // Safe because `self` represents a valid VADisplay and render_targets
48 // and ntargets are properly initialized. Note that render_targets==NULL
49 // is valid so long as ntargets==0.
50 Status(unsafe {
51 bindings::vaCreateContext(
52 display.handle(),
53 config.id(),
54 coded_width,
55 coded_height,
56 flags,
57 render_targets.as_mut_ptr(),
58 render_targets.len() as i32,
59 &mut context_id,
60 )
61 })
62 .check()?;
63
64 Ok(Rc::new(Self {
65 display,
66 id: context_id,
67 }))
68 }
69
70 /// Returns a shared reference to the [`Display`] used by this context.
71 pub fn display(&self) -> &Rc<Display> {
72 &self.display
73 }
74
75 /// Returns the ID of this context.
76 pub(crate) fn id(&self) -> bindings::VAContextID {
77 self.id
78 }
79
80 /// Create a new buffer of type `type_`.
81 pub fn create_buffer(self: &Rc<Self>, type_: BufferType) -> Result<Buffer> {
82 Buffer::new(Rc::clone(self), type_)
83 }
84}
85
86impl Drop for Context {
87 fn drop(&mut self) {
88 // Safe because `self` represents a valid VAContext.
89 let status =
90 Status(unsafe { bindings::vaDestroyContext(self.display.handle(), self.id) }).check();
91 if status.is_err() {
92 error!("vaDestroyContext failed: {}", status.unwrap_err());
93 }
94 }
95}