1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! High-level interface for a V4L2 video decoder. Currently only supports the
//! [stateful interface](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/dev-encoder.html).
use crate::{
    device::queue::{
        direction::{Capture, Output},
        dqbuf::DqBuffer,
        handles_provider::HandlesProvider,
        CanceledBuffer, FormatBuilder,
    },
    memory::BufferHandles,
    Rect,
};

pub mod format;
pub mod stateful;

pub enum CompletedInputBuffer<OP: BufferHandles> {
    Dequeued(DqBuffer<Output, OP>),
    Canceled(CanceledBuffer<OP>),
}

pub trait InputDoneCallback<OP: BufferHandles>: Fn(CompletedInputBuffer<OP>) {}
impl<OP, F> InputDoneCallback<OP> for F
where
    OP: BufferHandles,
    F: Fn(CompletedInputBuffer<OP>),
{
}

// TODO: add errors?
pub enum DecoderEvent<P: HandlesProvider> {
    /// Emitted when a frame is decoded.
    ///
    /// The parameter is the dequeued buffer, containing the plane handles of
    /// the decoded frame as well as its V4L2 parameters such as flags. The
    /// flags remain untouched, but the client should not take action on some
    /// of them: for instance, when the `V4L2_BUF_FLAG_LAST` is set, the proper
    /// corresponding event (resolution change or end of stream) will be
    /// signaled appropriately.
    FrameDecoded(DqBuffer<Capture, P::HandleType>),
    /// Emitted when a previously requested `drain` request completes.
    ///
    /// When this event is emitted, the client knows that all the frames
    /// corresponding to all the input buffers queued before the `drain` request
    /// have been emitted.
    EndOfStream,
}

pub trait DecoderEventCallback<P: HandlesProvider>:
    FnMut(DecoderEvent<P>) + Send + 'static
{
}
impl<P, F> DecoderEventCallback<P> for F
where
    P: HandlesProvider,
    F: FnMut(DecoderEvent<P>) + Send + 'static,
{
}

pub struct FormatChangedReply<P: HandlesProvider> {
    pub provider: P,
    pub mem_type: <P::HandleType as BufferHandles>::SupportedMemoryType,
    pub num_buffers: usize,
}

pub trait FormatChangedCallback<P: HandlesProvider>:
    Fn(FormatBuilder, Rect, usize) -> anyhow::Result<FormatChangedReply<P>> + Send + 'static
{
}
impl<P, F> FormatChangedCallback<P> for F
where
    P: HandlesProvider,
    F: Fn(FormatBuilder, Rect, usize) -> anyhow::Result<FormatChangedReply<P>> + Send + 'static,
{
}