👕 refactor
parent
677a8c7ebd
commit
fdec833fd0
|
@ -0,0 +1,295 @@
|
|||
use std::fmt;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive (Default)]
|
||||
pub struct Controller
|
||||
{
|
||||
/// Pipeline for pulling data from the network, decoding it,
|
||||
/// and displaying it.
|
||||
|
||||
rx_pipe: RxPipeline,
|
||||
|
||||
/// Pipeline for pulling data from capture devices, encoding it,
|
||||
/// and sending it over the network.
|
||||
|
||||
tx_pipe: TxPipeline,
|
||||
}
|
||||
|
||||
#[derive (Debug)]
|
||||
pub struct ControlEvent
|
||||
{
|
||||
pub rx: Option <RxPipelineEvent>,
|
||||
pub tx: Option <TxPipelineEvent>,
|
||||
}
|
||||
|
||||
impl Controller
|
||||
{
|
||||
pub fn handle_capture_frame (&mut self, buf_raw: BufRaw)
|
||||
-> Result <(), ControlError>
|
||||
{
|
||||
self.tx_pipe.handle_capture_frame (buf_raw)
|
||||
}
|
||||
|
||||
pub fn handle_encoder_finished (&mut self)
|
||||
{
|
||||
self.tx_pipe.encoder_is_busy = false;
|
||||
}
|
||||
|
||||
pub fn handle_encoded_packet (&mut self, buf_enc: Option <BufEncoded>) -> Result <(), ControlError>
|
||||
{
|
||||
self.tx_pipe.handle_encoded_packet (buf_enc)
|
||||
}
|
||||
|
||||
pub fn handle_network_busy (&mut self, x: bool)
|
||||
{
|
||||
self.tx_pipe.handle_network_busy (x)
|
||||
}
|
||||
|
||||
pub fn poll (&mut self) -> ControlEvent
|
||||
{
|
||||
let rx = self.rx_pipe.poll ();
|
||||
let tx = self.tx_pipe.poll ();
|
||||
|
||||
ControlEvent {
|
||||
rx,
|
||||
tx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Default)]
|
||||
struct RxPipeline
|
||||
{
|
||||
buf_enc: Option <BufEncoded>,
|
||||
buf_raw: Option <BufRaw>,
|
||||
}
|
||||
|
||||
#[derive (Debug)]
|
||||
pub enum RxPipelineEvent
|
||||
{
|
||||
DisplayRaw (BufRaw),
|
||||
Decode (BufEncoded),
|
||||
Receive,
|
||||
}
|
||||
|
||||
#[derive (Debug, Error)]
|
||||
enum RxPipeError
|
||||
{
|
||||
#[error ("already have encoded data")]
|
||||
AlreadyHaveEncodedData,
|
||||
#[error ("already have raw data")]
|
||||
AlreadyHaveRawData,
|
||||
}
|
||||
|
||||
impl RxPipeline
|
||||
{
|
||||
|
||||
fn handle_encoder_polled (&mut self, has_data: bool)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
fn handle_raw_frame (&mut self, buf_raw: BufRaw) -> Result <(), RxPipeError>
|
||||
{
|
||||
if self.has_raw_data ()
|
||||
{
|
||||
return Err (RxPipeError::AlreadyHaveRawData);
|
||||
}
|
||||
|
||||
self.buf_raw = Some (buf_raw);
|
||||
|
||||
Ok (())
|
||||
}
|
||||
|
||||
fn poll (&mut self) -> Option <RxPipelineEvent>
|
||||
{
|
||||
if let Some (buf_raw) = self.buf_raw.take ()
|
||||
{
|
||||
return Some (RxPipelineEvent::DisplayRaw (buf_raw));
|
||||
}
|
||||
|
||||
if ! self.has_raw_data ()
|
||||
{
|
||||
if let Some (buf_enc) = self.buf_enc.take ()
|
||||
{
|
||||
return Some (RxPipelineEvent::Decode (buf_enc));
|
||||
}
|
||||
}
|
||||
|
||||
if ! self.has_encoded_data ()
|
||||
{
|
||||
return Some (RxPipelineEvent::Receive);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// True if we have a buffer of received data, ready
|
||||
/// to be decoded.
|
||||
|
||||
fn has_encoded_data (&self) -> bool
|
||||
{
|
||||
self.buf_enc.is_some ()
|
||||
}
|
||||
|
||||
fn has_raw_data (&self) -> bool
|
||||
{
|
||||
self.buf_raw.is_some ()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Default)]
|
||||
struct TxPipeline
|
||||
{
|
||||
buf_enc: Option <BufEncoded>,
|
||||
buf_raw: Option <BufRaw>,
|
||||
capture_is_busy: bool,
|
||||
encoder_has_data: bool,
|
||||
encoder_is_busy: bool,
|
||||
network_busy: bool,
|
||||
}
|
||||
|
||||
#[derive (Debug)]
|
||||
pub enum TxPipelineEvent
|
||||
{
|
||||
/// Capture a raw frame and pass it to handle_capture_frame
|
||||
Capture,
|
||||
|
||||
/// Poll the encoder. If it returns a packet, pass it to
|
||||
/// handle_encoded_packet.
|
||||
PollEncoder,
|
||||
|
||||
/// Encode this raw frame and pass the encoded frame to
|
||||
/// handle_encoded_packet
|
||||
Encode (BufRaw),
|
||||
|
||||
/// Transmit this encoded frame to the network
|
||||
Transmit (BufEncoded),
|
||||
}
|
||||
|
||||
impl TxPipeline
|
||||
{
|
||||
fn handle_capture_frame (&mut self, buf_raw: BufRaw)
|
||||
-> Result <(), ControlError>
|
||||
{
|
||||
self.capture_is_busy = false;
|
||||
|
||||
if self.has_raw_frame ()
|
||||
{
|
||||
return Err (ControlError::AlreadyHaveRawData);
|
||||
}
|
||||
|
||||
self.buf_raw = Some (buf_raw);
|
||||
|
||||
Ok (())
|
||||
}
|
||||
|
||||
fn handle_encoded_packet (&mut self, buf_enc: Option <BufEncoded>) -> Result <(), ControlError>
|
||||
{
|
||||
self.encoder_has_data = buf_enc.is_some ();
|
||||
let buf_enc = match buf_enc
|
||||
{
|
||||
None => return Ok (()),
|
||||
Some (x) => x,
|
||||
};
|
||||
|
||||
self.encoder_is_busy = false;
|
||||
|
||||
if self.has_encoded_packet ()
|
||||
{
|
||||
return Err (ControlError::AlreadyHaveEncodedData);
|
||||
}
|
||||
|
||||
self.buf_enc = Some (buf_enc);
|
||||
|
||||
Ok (())
|
||||
}
|
||||
|
||||
fn handle_network_busy (&mut self, busy: bool)
|
||||
{
|
||||
self.network_busy = busy;
|
||||
}
|
||||
|
||||
fn has_encoded_packet (&self) -> bool
|
||||
{
|
||||
self.buf_enc.is_some ()
|
||||
}
|
||||
|
||||
fn has_raw_frame (&self) -> bool
|
||||
{
|
||||
self.buf_raw.is_some ()
|
||||
}
|
||||
|
||||
fn poll (&mut self) -> Option <TxPipelineEvent>
|
||||
{
|
||||
if ! self.network_busy
|
||||
{
|
||||
if let Some (buf_enc) = self.buf_enc.take ()
|
||||
{
|
||||
return Some (TxPipelineEvent::Transmit (buf_enc));
|
||||
}
|
||||
}
|
||||
|
||||
if ! self.has_encoded_packet () && ! self.encoder_is_busy
|
||||
{
|
||||
if self.encoder_has_data
|
||||
{
|
||||
return Some (TxPipelineEvent::PollEncoder);
|
||||
}
|
||||
|
||||
if let Some (buf_raw) = self.buf_raw.take ()
|
||||
{
|
||||
self.encoder_has_data = true;
|
||||
self.encoder_is_busy = true;
|
||||
return Some (TxPipelineEvent::Encode (buf_raw));
|
||||
}
|
||||
}
|
||||
|
||||
if ! self.has_raw_frame ()
|
||||
{
|
||||
if ! self.capture_is_busy
|
||||
{
|
||||
self.capture_is_busy = true;
|
||||
return Some (TxPipelineEvent::Capture);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BufEncoded
|
||||
{
|
||||
pub buf: Vec <u8>
|
||||
}
|
||||
|
||||
impl fmt::Debug for BufEncoded {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f
|
||||
.debug_struct("BufEncoded")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BufRaw
|
||||
{
|
||||
pub buf: Vec <u8>
|
||||
}
|
||||
|
||||
impl fmt::Debug for BufRaw {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f
|
||||
.debug_struct("BufRaw")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Debug, Error)]
|
||||
pub enum ControlError
|
||||
{
|
||||
#[error ("already have encoded data")]
|
||||
AlreadyHaveEncodedData,
|
||||
#[error ("already have raw data")]
|
||||
AlreadyHaveRawData,
|
||||
}
|
288
src/main.rs
288
src/main.rs
|
@ -6,7 +6,10 @@ use std::{
|
|||
};
|
||||
|
||||
use rayon::ThreadPool;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::controller::*;
|
||||
|
||||
mod controller;
|
||||
|
||||
fn main()
|
||||
{
|
||||
|
@ -89,7 +92,7 @@ impl <'a> Driver <'_>
|
|||
_ => panic! ("tried to finish an already finished capture"),
|
||||
};
|
||||
|
||||
self.ctl.tx_pipe.handle_capture_frame (buf_raw).unwrap ();
|
||||
self.ctl.handle_capture_frame (buf_raw).unwrap ();
|
||||
},
|
||||
TaskOutput::TxEncode (enc) =>
|
||||
{
|
||||
|
@ -99,7 +102,7 @@ impl <'a> Driver <'_>
|
|||
_ => panic! ("tried to finish an already finished encode"),
|
||||
};
|
||||
|
||||
self.ctl.tx_pipe.encoder_is_busy = false;
|
||||
self.ctl.handle_encoder_finished ();
|
||||
},
|
||||
TaskOutput::TxTransmit ((tx, busy)) =>
|
||||
{
|
||||
|
@ -109,7 +112,7 @@ impl <'a> Driver <'_>
|
|||
_ => panic! ("tried to finish an already finished transmit"),
|
||||
};
|
||||
|
||||
self.ctl.tx_pipe.handle_network_busy (busy);
|
||||
self.ctl.handle_network_busy (busy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,9 +160,12 @@ impl <'a> Driver <'_>
|
|||
let may_have_data = encoder.poll_encoded (&mut buf);
|
||||
if may_have_data
|
||||
{
|
||||
self.ctl.tx_pipe.handle_encoded_packet (BufEncoded {buf}).unwrap ();
|
||||
self.ctl.handle_encoded_packet (Some (BufEncoded {buf})).unwrap ();
|
||||
}
|
||||
else
|
||||
{
|
||||
self.ctl.handle_encoded_packet (None).unwrap ();
|
||||
}
|
||||
self.ctl.tx_pipe.encoder_has_data = may_have_data;
|
||||
}
|
||||
TxPipelineEvent::Encode (buf_raw) =>
|
||||
{
|
||||
|
@ -223,241 +229,6 @@ impl fmt::Debug for TaskOutput {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive (Default)]
|
||||
struct Controller
|
||||
{
|
||||
/// Pipeline for pulling data from the network, decoding it,
|
||||
/// and displaying it.
|
||||
|
||||
rx_pipe: RxPipeline,
|
||||
|
||||
/// Pipeline for pulling data from capture devices, encoding it,
|
||||
/// and sending it over the network.
|
||||
|
||||
tx_pipe: TxPipeline,
|
||||
}
|
||||
|
||||
#[derive (Debug)]
|
||||
struct ControlEvent
|
||||
{
|
||||
rx: Option <RxPipelineEvent>,
|
||||
tx: Option <TxPipelineEvent>,
|
||||
}
|
||||
|
||||
impl Controller
|
||||
{
|
||||
fn poll (&mut self) -> ControlEvent
|
||||
{
|
||||
let rx = self.rx_pipe.poll ();
|
||||
let tx = self.tx_pipe.poll ();
|
||||
|
||||
ControlEvent {
|
||||
rx,
|
||||
tx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Default)]
|
||||
struct RxPipeline
|
||||
{
|
||||
buf_enc: Option <BufEncoded>,
|
||||
buf_raw: Option <BufRaw>,
|
||||
}
|
||||
|
||||
#[derive (Debug)]
|
||||
enum RxPipelineEvent
|
||||
{
|
||||
DisplayRaw (BufRaw),
|
||||
Decode (BufEncoded),
|
||||
Receive,
|
||||
}
|
||||
|
||||
#[derive (Debug, Error)]
|
||||
enum RxPipeError
|
||||
{
|
||||
#[error ("already have encoded data")]
|
||||
AlreadyHaveEncodedData,
|
||||
#[error ("already have raw data")]
|
||||
AlreadyHaveRawData,
|
||||
}
|
||||
|
||||
impl RxPipeline
|
||||
{
|
||||
fn handle_encoded_packet (&mut self, buf_enc: BufEncoded) -> Result <(), RxPipeError>
|
||||
{
|
||||
if self.has_encoded_data ()
|
||||
{
|
||||
return Err (RxPipeError::AlreadyHaveEncodedData);
|
||||
}
|
||||
|
||||
self.buf_enc = Some (buf_enc);
|
||||
|
||||
Ok (())
|
||||
}
|
||||
|
||||
fn handle_raw_frame (&mut self, buf_raw: BufRaw) -> Result <(), RxPipeError>
|
||||
{
|
||||
if self.has_raw_data ()
|
||||
{
|
||||
return Err (RxPipeError::AlreadyHaveRawData);
|
||||
}
|
||||
|
||||
self.buf_raw = Some (buf_raw);
|
||||
|
||||
Ok (())
|
||||
}
|
||||
|
||||
fn poll (&mut self) -> Option <RxPipelineEvent>
|
||||
{
|
||||
if let Some (buf_raw) = self.buf_raw.take ()
|
||||
{
|
||||
return Some (RxPipelineEvent::DisplayRaw (buf_raw));
|
||||
}
|
||||
|
||||
if ! self.has_raw_data ()
|
||||
{
|
||||
if let Some (buf_enc) = self.buf_enc.take ()
|
||||
{
|
||||
return Some (RxPipelineEvent::Decode (buf_enc));
|
||||
}
|
||||
}
|
||||
|
||||
if ! self.has_encoded_data ()
|
||||
{
|
||||
return Some (RxPipelineEvent::Receive);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// True if we have a buffer of received data, ready
|
||||
/// to be decoded.
|
||||
|
||||
fn has_encoded_data (&self) -> bool
|
||||
{
|
||||
self.buf_enc.is_some ()
|
||||
}
|
||||
|
||||
fn has_raw_data (&self) -> bool
|
||||
{
|
||||
self.buf_raw.is_some ()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Default)]
|
||||
struct TxPipeline
|
||||
{
|
||||
buf_enc: Option <BufEncoded>,
|
||||
buf_raw: Option <BufRaw>,
|
||||
capture_is_busy: bool,
|
||||
encoder_has_data: bool,
|
||||
encoder_is_busy: bool,
|
||||
network_busy: bool,
|
||||
}
|
||||
|
||||
#[derive (Debug)]
|
||||
enum TxPipelineEvent
|
||||
{
|
||||
/// Capture a raw frame and pass it to handle_capture_frame
|
||||
Capture,
|
||||
|
||||
/// Poll the encoder. If it returns a packet, pass it to
|
||||
/// handle_encoded_packet.
|
||||
PollEncoder,
|
||||
|
||||
/// Encode this raw frame and pass the encoded frame to
|
||||
/// handle_encoded_packet
|
||||
Encode (BufRaw),
|
||||
|
||||
/// Transmit this encoded frame to the network
|
||||
Transmit (BufEncoded),
|
||||
}
|
||||
|
||||
impl TxPipeline
|
||||
{
|
||||
fn handle_capture_frame (&mut self, buf_raw: BufRaw)
|
||||
-> Result <(), ControlError>
|
||||
{
|
||||
self.capture_is_busy = false;
|
||||
|
||||
if self.has_raw_frame ()
|
||||
{
|
||||
return Err (ControlError::AlreadyHaveRawData);
|
||||
}
|
||||
|
||||
self.buf_raw = Some (buf_raw);
|
||||
|
||||
Ok (())
|
||||
}
|
||||
|
||||
fn handle_encoded_packet (&mut self, buf_enc: BufEncoded) -> Result <(), ControlError>
|
||||
{
|
||||
self.encoder_is_busy = false;
|
||||
|
||||
if self.has_encoded_packet ()
|
||||
{
|
||||
return Err (ControlError::AlreadyHaveEncodedData);
|
||||
}
|
||||
|
||||
self.buf_enc = Some (buf_enc);
|
||||
|
||||
Ok (())
|
||||
}
|
||||
|
||||
fn handle_network_busy (&mut self, busy: bool)
|
||||
{
|
||||
self.network_busy = busy;
|
||||
}
|
||||
|
||||
fn has_encoded_packet (&self) -> bool
|
||||
{
|
||||
self.buf_enc.is_some ()
|
||||
}
|
||||
|
||||
fn has_raw_frame (&self) -> bool
|
||||
{
|
||||
self.buf_raw.is_some ()
|
||||
}
|
||||
|
||||
fn poll (&mut self) -> Option <TxPipelineEvent>
|
||||
{
|
||||
if ! self.network_busy
|
||||
{
|
||||
if let Some (buf_enc) = self.buf_enc.take ()
|
||||
{
|
||||
return Some (TxPipelineEvent::Transmit (buf_enc));
|
||||
}
|
||||
}
|
||||
|
||||
if ! self.has_encoded_packet () && ! self.encoder_is_busy
|
||||
{
|
||||
if self.encoder_has_data
|
||||
{
|
||||
return Some (TxPipelineEvent::PollEncoder);
|
||||
}
|
||||
|
||||
if let Some (buf_raw) = self.buf_raw.take ()
|
||||
{
|
||||
self.encoder_has_data = true;
|
||||
self.encoder_is_busy = true;
|
||||
return Some (TxPipelineEvent::Encode (buf_raw));
|
||||
}
|
||||
}
|
||||
|
||||
if ! self.has_raw_frame ()
|
||||
{
|
||||
if ! self.capture_is_busy
|
||||
{
|
||||
self.capture_is_busy = true;
|
||||
return Some (TxPipelineEvent::Capture);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps non-thread-safe capture device like a v4l webcam
|
||||
|
||||
#[derive (Default)]
|
||||
|
@ -562,38 +333,3 @@ impl Transmitter
|
|||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct BufEncoded
|
||||
{
|
||||
buf: Vec <u8>
|
||||
}
|
||||
|
||||
impl fmt::Debug for BufEncoded {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f
|
||||
.debug_struct("BufEncoded")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
struct BufRaw
|
||||
{
|
||||
buf: Vec <u8>
|
||||
}
|
||||
|
||||
impl fmt::Debug for BufRaw {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f
|
||||
.debug_struct("BufRaw")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Debug, Error)]
|
||||
enum ControlError
|
||||
{
|
||||
#[error ("already have encoded data")]
|
||||
AlreadyHaveEncodedData,
|
||||
#[error ("already have raw data")]
|
||||
AlreadyHaveRawData,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue