Add `ReadPacket` and `WritePacket` traits
parent
26cb2783bc
commit
77ad3db255
|
@ -1,13 +1,14 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate trackable;
|
extern crate trackable;
|
||||||
extern crate handy_async;
|
extern crate handy_async;
|
||||||
|
extern crate crypto;
|
||||||
|
|
||||||
pub use error::{Error, ErrorKind};
|
pub use error::{Error, ErrorKind};
|
||||||
|
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod packet;
|
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
pub mod rfc3550;
|
pub mod rfc3550;
|
||||||
|
pub mod rfc3711;
|
||||||
pub mod rfc4585;
|
pub mod rfc4585;
|
||||||
pub mod rfc5761;
|
pub mod rfc5761;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
use io::{ReadFrom, WriteTo};
|
|
||||||
|
|
||||||
pub trait Packet: ReadFrom + WriteTo {}
|
|
|
@ -3,8 +3,7 @@ use handy_async::sync_io::{ReadExt, WriteExt};
|
||||||
|
|
||||||
use {Result, ErrorKind};
|
use {Result, ErrorKind};
|
||||||
use io::{ReadFrom, WriteTo};
|
use io::{ReadFrom, WriteTo};
|
||||||
use packet::Packet;
|
use traits::{self, Packet};
|
||||||
use traits;
|
|
||||||
use types::{U5, U24, RtpTimestamp, NtpTimestamp, NtpMiddleTimetamp, Ssrc, SsrcOrCsrc};
|
use types::{U5, U24, RtpTimestamp, NtpTimestamp, NtpMiddleTimetamp, Ssrc, SsrcOrCsrc};
|
||||||
use constants::RTP_VERSION;
|
use constants::RTP_VERSION;
|
||||||
|
|
||||||
|
@ -25,16 +24,13 @@ pub const SDES_ITEM_TYPE_NOTE: u8 = 7;
|
||||||
pub const SDES_ITEM_TYPE_PRIV: u8 = 8;
|
pub const SDES_ITEM_TYPE_PRIV: u8 = 8;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum RtcpPacket {
|
pub struct RtcpPacketReader;
|
||||||
Sr(RtcpSenderReport),
|
impl traits::ReadPacket for RtcpPacketReader {
|
||||||
Rr(RtcpReceiverReport),
|
type Packet = RtcpPacket;
|
||||||
Sdes(RtcpSourceDescription),
|
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||||
Bye(RtcpGoodbye),
|
RtcpPacket::read_from(reader)
|
||||||
App(RtcpApplicationDefined),
|
}
|
||||||
}
|
fn supports_type(&self, ty: u8) -> bool {
|
||||||
impl Packet for RtcpPacket {}
|
|
||||||
impl traits::RtcpPacket for RtcpPacket {
|
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
match ty {
|
match ty {
|
||||||
RTCP_PACKET_TYPE_SR |
|
RTCP_PACKET_TYPE_SR |
|
||||||
RTCP_PACKET_TYPE_RR |
|
RTCP_PACKET_TYPE_RR |
|
||||||
|
@ -45,6 +41,26 @@ impl traits::RtcpPacket for RtcpPacket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct RtcpPacketWriter;
|
||||||
|
impl traits::WritePacket for RtcpPacketWriter {
|
||||||
|
type Packet = RtcpPacket;
|
||||||
|
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
||||||
|
packet.write_to(writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum RtcpPacket {
|
||||||
|
Sr(RtcpSenderReport),
|
||||||
|
Rr(RtcpReceiverReport),
|
||||||
|
Sdes(RtcpSourceDescription),
|
||||||
|
Bye(RtcpGoodbye),
|
||||||
|
App(RtcpApplicationDefined),
|
||||||
|
}
|
||||||
|
impl Packet for RtcpPacket {}
|
||||||
|
impl traits::RtcpPacket for RtcpPacket {}
|
||||||
impl ReadFrom for RtcpPacket {
|
impl ReadFrom for RtcpPacket {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let mut buf = [0; 2];
|
let mut buf = [0; 2];
|
||||||
|
@ -186,11 +202,7 @@ impl RtcpSenderReport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Packet for RtcpSenderReport {}
|
impl Packet for RtcpSenderReport {}
|
||||||
impl traits::RtcpPacket for RtcpSenderReport {
|
impl traits::RtcpPacket for RtcpSenderReport {}
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
ty == RTCP_PACKET_TYPE_SR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ReadFrom for RtcpSenderReport {
|
impl ReadFrom for RtcpSenderReport {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let (reception_report_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SR));
|
let (reception_report_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SR));
|
||||||
|
@ -320,11 +332,7 @@ impl RtcpReceiverReport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Packet for RtcpReceiverReport {}
|
impl Packet for RtcpReceiverReport {}
|
||||||
impl traits::RtcpPacket for RtcpReceiverReport {
|
impl traits::RtcpPacket for RtcpReceiverReport {}
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
ty == RTCP_PACKET_TYPE_RR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ReadFrom for RtcpReceiverReport {
|
impl ReadFrom for RtcpReceiverReport {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let (reception_report_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_RR));
|
let (reception_report_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_RR));
|
||||||
|
@ -375,11 +383,7 @@ impl RtcpSourceDescription {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Packet for RtcpSourceDescription {}
|
impl Packet for RtcpSourceDescription {}
|
||||||
impl traits::RtcpPacket for RtcpSourceDescription {
|
impl traits::RtcpPacket for RtcpSourceDescription {}
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
ty == RTCP_PACKET_TYPE_SDES
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ReadFrom for RtcpSourceDescription {
|
impl ReadFrom for RtcpSourceDescription {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SDES));
|
let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SDES));
|
||||||
|
@ -530,11 +534,7 @@ impl RtcpGoodbye {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Packet for RtcpGoodbye {}
|
impl Packet for RtcpGoodbye {}
|
||||||
impl traits::RtcpPacket for RtcpGoodbye {
|
impl traits::RtcpPacket for RtcpGoodbye {}
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
ty == RTCP_PACKET_TYPE_BYE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ReadFrom for RtcpGoodbye {
|
impl ReadFrom for RtcpGoodbye {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_BYE));
|
let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_BYE));
|
||||||
|
@ -585,11 +585,7 @@ pub struct RtcpApplicationDefined {
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
impl Packet for RtcpApplicationDefined {}
|
impl Packet for RtcpApplicationDefined {}
|
||||||
impl traits::RtcpPacket for RtcpApplicationDefined {
|
impl traits::RtcpPacket for RtcpApplicationDefined {}
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
ty == RTCP_PACKET_TYPE_APP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ReadFrom for RtcpApplicationDefined {
|
impl ReadFrom for RtcpApplicationDefined {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let (subtype, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_APP));
|
let (subtype, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_APP));
|
||||||
|
|
|
@ -3,11 +3,31 @@ use handy_async::sync_io::{ReadExt, WriteExt};
|
||||||
|
|
||||||
use {Result, ErrorKind};
|
use {Result, ErrorKind};
|
||||||
use io::{ReadFrom, WriteTo};
|
use io::{ReadFrom, WriteTo};
|
||||||
use packet::Packet;
|
use traits::{self, Packet};
|
||||||
use traits;
|
|
||||||
use types::{U7, RtpTimestamp, Ssrc, Csrc};
|
use types::{U7, RtpTimestamp, Ssrc, Csrc};
|
||||||
use constants::RTP_VERSION;
|
use constants::RTP_VERSION;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct RtpPacketReader;
|
||||||
|
impl traits::ReadPacket for RtpPacketReader {
|
||||||
|
type Packet = RtpPacket;
|
||||||
|
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||||
|
RtpPacket::read_from(reader)
|
||||||
|
}
|
||||||
|
fn supports_type(&self, _ty: u8) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct RtpPacketWriter;
|
||||||
|
impl traits::WritePacket for RtpPacketWriter {
|
||||||
|
type Packet = RtpPacket;
|
||||||
|
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
||||||
|
packet.write_to(writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct RtpPacket {
|
pub struct RtpPacket {
|
||||||
pub header: RtpFixedHeader,
|
pub header: RtpFixedHeader,
|
||||||
|
@ -15,11 +35,7 @@ pub struct RtpPacket {
|
||||||
pub padding: Vec<u8>,
|
pub padding: Vec<u8>,
|
||||||
}
|
}
|
||||||
impl Packet for RtpPacket {}
|
impl Packet for RtpPacket {}
|
||||||
impl traits::RtpPacket for RtpPacket {
|
impl traits::RtpPacket for RtpPacket {}
|
||||||
fn supports_type(_ty: U7) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ReadFrom for RtpPacket {
|
impl ReadFrom for RtpPacket {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let header = track_try!(RtpFixedHeader::read_from(reader));
|
let header = track_try!(RtpFixedHeader::read_from(reader));
|
||||||
|
|
|
@ -3,8 +3,7 @@ use handy_async::sync_io::{ReadExt, WriteExt};
|
||||||
|
|
||||||
use {Result, ErrorKind};
|
use {Result, ErrorKind};
|
||||||
use io::{ReadFrom, WriteTo};
|
use io::{ReadFrom, WriteTo};
|
||||||
use packet::Packet;
|
use traits::{self, Packet};
|
||||||
use traits;
|
|
||||||
use types::{U5, U6, U7, U13, Ssrc};
|
use types::{U5, U6, U7, U13, Ssrc};
|
||||||
use constants::RTP_VERSION;
|
use constants::RTP_VERSION;
|
||||||
use rfc3550;
|
use rfc3550;
|
||||||
|
@ -20,18 +19,13 @@ pub const PSFB_MESSAGE_TYPE_RPSI: u8 = 3;
|
||||||
pub const PSFB_MESSAGE_TYPE_AFB: u8 = 15;
|
pub const PSFB_MESSAGE_TYPE_AFB: u8 = 15;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum RtcpPacket {
|
pub struct RtcpPacketReader;
|
||||||
Sr(rfc3550::RtcpSenderReport),
|
impl traits::ReadPacket for RtcpPacketReader {
|
||||||
Rr(rfc3550::RtcpReceiverReport),
|
type Packet = RtcpPacket;
|
||||||
Sdes(rfc3550::RtcpSourceDescription),
|
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||||
Bye(rfc3550::RtcpGoodbye),
|
RtcpPacket::read_from(reader)
|
||||||
App(rfc3550::RtcpApplicationDefined),
|
}
|
||||||
Rtpfb(RtcpTransportLayerFeedback),
|
fn supports_type(&self, ty: u8) -> bool {
|
||||||
Psfb(RtcpPayloadSpecificFeedback),
|
|
||||||
}
|
|
||||||
impl Packet for RtcpPacket {}
|
|
||||||
impl traits::RtcpPacket for RtcpPacket {
|
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
match ty {
|
match ty {
|
||||||
rfc3550::RTCP_PACKET_TYPE_SR |
|
rfc3550::RTCP_PACKET_TYPE_SR |
|
||||||
rfc3550::RTCP_PACKET_TYPE_RR |
|
rfc3550::RTCP_PACKET_TYPE_RR |
|
||||||
|
@ -44,6 +38,28 @@ impl traits::RtcpPacket for RtcpPacket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct RtcpPacketWriter;
|
||||||
|
impl traits::WritePacket for RtcpPacketWriter {
|
||||||
|
type Packet = RtcpPacket;
|
||||||
|
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
||||||
|
packet.write_to(writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum RtcpPacket {
|
||||||
|
Sr(rfc3550::RtcpSenderReport),
|
||||||
|
Rr(rfc3550::RtcpReceiverReport),
|
||||||
|
Sdes(rfc3550::RtcpSourceDescription),
|
||||||
|
Bye(rfc3550::RtcpGoodbye),
|
||||||
|
App(rfc3550::RtcpApplicationDefined),
|
||||||
|
Rtpfb(RtcpTransportLayerFeedback),
|
||||||
|
Psfb(RtcpPayloadSpecificFeedback),
|
||||||
|
}
|
||||||
|
impl Packet for RtcpPacket {}
|
||||||
|
impl traits::RtcpPacket for RtcpPacket {}
|
||||||
impl ReadFrom for RtcpPacket {
|
impl ReadFrom for RtcpPacket {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let mut buf = [0; 2];
|
let mut buf = [0; 2];
|
||||||
|
@ -136,11 +152,7 @@ pub enum RtcpTransportLayerFeedback {
|
||||||
Nack(GenericNack),
|
Nack(GenericNack),
|
||||||
}
|
}
|
||||||
impl Packet for RtcpTransportLayerFeedback {}
|
impl Packet for RtcpTransportLayerFeedback {}
|
||||||
impl traits::RtcpPacket for RtcpTransportLayerFeedback {
|
impl traits::RtcpPacket for RtcpTransportLayerFeedback {}
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
ty == RTCP_PACKET_TYPE_RTPFB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ReadFrom for RtcpTransportLayerFeedback {
|
impl ReadFrom for RtcpTransportLayerFeedback {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let (fb_message_type, rest) = track_try!(read_common(reader, RTCP_PACKET_TYPE_RTPFB));
|
let (fb_message_type, rest) = track_try!(read_common(reader, RTCP_PACKET_TYPE_RTPFB));
|
||||||
|
@ -183,11 +195,7 @@ pub enum RtcpPayloadSpecificFeedback {
|
||||||
Afb(ApplicationLayerFeedback),
|
Afb(ApplicationLayerFeedback),
|
||||||
}
|
}
|
||||||
impl Packet for RtcpPayloadSpecificFeedback {}
|
impl Packet for RtcpPayloadSpecificFeedback {}
|
||||||
impl traits::RtcpPacket for RtcpPayloadSpecificFeedback {
|
impl traits::RtcpPacket for RtcpPayloadSpecificFeedback {}
|
||||||
fn supports_type(ty: u8) -> bool {
|
|
||||||
ty == RTCP_PACKET_TYPE_RTPFB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ReadFrom for RtcpPayloadSpecificFeedback {
|
impl ReadFrom for RtcpPayloadSpecificFeedback {
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||||
let (fb_message_type, rest) = track_try!(read_common(reader, RTCP_PACKET_TYPE_PSFB));
|
let (fb_message_type, rest) = track_try!(read_common(reader, RTCP_PACKET_TYPE_PSFB));
|
||||||
|
|
116
src/rfc5761.rs
116
src/rfc5761.rs
|
@ -1,9 +1,83 @@
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use {Result, ErrorKind};
|
use {Result};
|
||||||
use io::{ReadFrom, WriteTo};
|
use traits::{ReadPacket, WritePacket, RtpPacket, RtcpPacket, Packet};
|
||||||
use traits::{RtpPacket, RtcpPacket};
|
|
||||||
use packet::Packet;
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct MuxPacketReader<T, U> {
|
||||||
|
rtp_reader: T,
|
||||||
|
rtcp_reader: U,
|
||||||
|
}
|
||||||
|
impl<T, U> MuxPacketReader<T, U>
|
||||||
|
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<T, U> ReadPacket for MuxPacketReader<T, U>
|
||||||
|
where T: ReadPacket,
|
||||||
|
T::Packet: RtpPacket,
|
||||||
|
U: ReadPacket,
|
||||||
|
U::Packet: RtcpPacket
|
||||||
|
{
|
||||||
|
type Packet = MuxedPacket<T::Packet, U::Packet>;
|
||||||
|
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||||
|
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<T, U> {
|
||||||
|
rtp_writer: T,
|
||||||
|
rtcp_writer: U,
|
||||||
|
}
|
||||||
|
impl<T, U> MuxPacketWriter<T, U>
|
||||||
|
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<T, U> WritePacket for MuxPacketWriter<T, U>
|
||||||
|
where T: WritePacket,
|
||||||
|
T::Packet: RtpPacket,
|
||||||
|
U: WritePacket,
|
||||||
|
U::Packet: RtcpPacket
|
||||||
|
{
|
||||||
|
type Packet = MuxedPacket<T::Packet, U::Packet>;
|
||||||
|
fn write_packet<W: Write>(&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)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum MuxedPacket<T, U> {
|
pub enum MuxedPacket<T, U> {
|
||||||
|
@ -15,37 +89,3 @@ impl<T, U> Packet for MuxedPacket<T, U>
|
||||||
U: RtcpPacket
|
U: RtcpPacket
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
impl<T, U> ReadFrom for MuxedPacket<T, U>
|
|
||||||
where T: RtpPacket,
|
|
||||||
U: RtcpPacket
|
|
||||||
{
|
|
||||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
|
||||||
let mut buf = [0; 2];
|
|
||||||
track_try!(reader.read_exact(&mut buf));
|
|
||||||
|
|
||||||
let ty = buf[1];
|
|
||||||
if U::supports_type(ty) {
|
|
||||||
let reader = &mut (&buf[..]).chain(reader);
|
|
||||||
track_err!(U::read_from(reader).map(MuxedPacket::Rtcp))
|
|
||||||
} else if T::supports_type(ty & 0b0111_1111) {
|
|
||||||
let reader = &mut (&buf[..]).chain(reader);
|
|
||||||
track_err!(T::read_from(reader).map(MuxedPacket::Rtp))
|
|
||||||
} else {
|
|
||||||
track_panic!(ErrorKind::Unsupported,
|
|
||||||
"Unknown packet/payload type: {}",
|
|
||||||
ty)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T, U> WriteTo for MuxedPacket<T, U>
|
|
||||||
where T: RtpPacket,
|
|
||||||
U: RtcpPacket
|
|
||||||
{
|
|
||||||
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
|
|
||||||
match *self {
|
|
||||||
MuxedPacket::Rtp(ref p) => track_try!(p.write_to(writer)),
|
|
||||||
MuxedPacket::Rtcp(ref p) => track_try!(p.write_to(writer)),
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
use packet::Packet;
|
use std::io::{Read, Write};
|
||||||
use types::U7;
|
|
||||||
|
|
||||||
pub trait RtpPacket: Packet {
|
use Result;
|
||||||
fn supports_type(payload_type: U7) -> bool;
|
|
||||||
|
pub trait Packet {}
|
||||||
|
|
||||||
|
// TODO: DecodePacket(?)
|
||||||
|
pub trait ReadPacket {
|
||||||
|
type Packet: Packet;
|
||||||
|
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet>;
|
||||||
|
fn supports_type(&self, packet_type: u8) -> bool;
|
||||||
}
|
}
|
||||||
pub trait RtcpPacket: Packet {
|
|
||||||
fn supports_type(packet_type: u8) -> bool;
|
pub trait WritePacket {
|
||||||
|
type Packet: Packet;
|
||||||
|
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait RtpPacket: Packet {}
|
||||||
|
pub trait RtcpPacket: Packet {}
|
||||||
|
|
Loading…
Reference in New Issue