use std::io::{Read, Write}; use trackable::*; use crate::traits::{Packet, ReadPacket, RtcpPacket, RtpPacket, WritePacket}; use crate::Result; #[derive(Debug, Clone, PartialEq, Eq)] pub struct MuxPacketReader { rtp_reader: T, rtcp_reader: U, } impl MuxPacketReader where T: ReadPacket, T::Packet: RtpPacket, U: ReadPacket, U::Packet: RtcpPacket, { pub fn new(rtp_reader: T, rtcp_reader: U) -> Self { MuxPacketReader { rtp_reader: rtp_reader, rtcp_reader: rtcp_reader, } } } impl ReadPacket for MuxPacketReader where T: ReadPacket, T::Packet: RtpPacket, U: ReadPacket, U::Packet: RtcpPacket, { type Packet = MuxedPacket; fn read_packet(&mut self, reader: &mut R) -> Result { let mut buf = [0; 2]; track_try!(reader.read_exact(&mut buf)); let ty = buf[1]; if self.rtcp_reader.supports_type(ty) { let reader = &mut (&buf[..]).chain(reader); track_err!(self.rtcp_reader.read_packet(reader).map(MuxedPacket::Rtcp)) } else { let reader = &mut (&buf[..]).chain(reader); track_err!(self.rtp_reader.read_packet(reader).map(MuxedPacket::Rtp)) } } fn supports_type(&self, ty: u8) -> bool { self.rtp_reader.supports_type(ty) || self.rtcp_reader.supports_type(ty) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct MuxPacketWriter { rtp_writer: T, rtcp_writer: U, } impl MuxPacketWriter where T: WritePacket, T::Packet: RtpPacket, U: WritePacket, U::Packet: RtcpPacket, { pub fn new(rtp_writer: T, rtcp_writer: U) -> Self { MuxPacketWriter { rtp_writer: rtp_writer, rtcp_writer: rtcp_writer, } } } impl WritePacket for MuxPacketWriter where T: WritePacket, T::Packet: RtpPacket, U: WritePacket, U::Packet: RtcpPacket, { type Packet = MuxedPacket; fn write_packet(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> { match *packet { MuxedPacket::Rtp(ref p) => self.rtp_writer.write_packet(writer, p), MuxedPacket::Rtcp(ref p) => self.rtcp_writer.write_packet(writer, p), } } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum MuxedPacket { Rtp(T), Rtcp(U), } impl Packet for MuxedPacket where T: RtpPacket, U: RtcpPacket, { }