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