Ejemplo n.º 1
0
 def test_with_csrc_truncated(self):
     data = load("rtp_with_csrc.bin")
     for length in range(12, 20):
         with self.assertRaises(ValueError) as cm:
             RtpPacket.parse(data[0:length])
         self.assertEqual(str(cm.exception),
                          "RTP packet has truncated CSRC")
Ejemplo n.º 2
0
    def test_with_sdes_mid_truncated(self):
        data = load('rtp_with_sdes_mid.bin')

        for length in range(12, 16):
            with self.assertRaises(ValueError) as cm:
                RtpPacket.parse(data[0:length])
            self.assertEqual(str(cm.exception),
                             'RTP packet has truncated extension profile / length')

        for length in range(16, 20):
            with self.assertRaises(ValueError) as cm:
                RtpPacket.parse(data[0:length])
            self.assertEqual(str(cm.exception), 'RTP packet has truncated extension value')
Ejemplo n.º 3
0
    def test_rtp_and_rtcp(self):
        transport, remote = dummy_dtls_transport_pair()

        receiver = RTCRtpReceiver('audio', transport)
        self.assertEqual(receiver.transport, transport)

        receiver._track = RemoteStreamTrack(kind='audio')
        self.assertEqual(receiver._track.readyState, 'live')
        run(receiver.receive(RTCRtpParameters(codecs=[PCMU_CODEC])))

        # receive RTP
        packet = RtpPacket.parse(load('rtp.bin'))
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # receive RTCP SR
        for packet in RtcpPacket.parse(load('rtcp_sr.bin')):
            run(receiver._handle_rtcp_packet(packet))

        # check stats
        report = run(receiver.getStats())
        self.assertTrue(isinstance(report, RTCStatsReport))
        self.assertEqual(sorted(report.keys()), ['inbound-rtp', 'remote-outbound-rtp'])

        # check remote track
        frame = run(receiver._track.recv())
        self.assertTrue(isinstance(frame, AudioFrame))

        # shutdown
        run(receiver.stop())
        self.assertEqual(receiver._track.readyState, 'ended')
Ejemplo n.º 4
0
    def test_rtp_and_rtcp(self):
        transport, remote = dummy_dtls_transport_pair()

        receiver = RTCRtpReceiver('audio', transport)
        self.assertEqual(receiver.transport, transport)

        receiver._track = RemoteStreamTrack(kind='audio')
        run(receiver.receive(RTCRtpParameters(codecs=[PCMU_CODEC])))

        # receive RTP
        packet = RtpPacket.parse(load('rtp.bin'))
        run(receiver._handle_rtp_packet(packet))

        # receive RTCP
        for packet in RtcpPacket.parse(load('rtcp_sr.bin')):
            run(receiver._handle_rtcp_packet(packet))
        self.assertEqual(sorted(receiver._stats.keys()),
                         ['remote-inbound-rtp', 'remote-outbound-rtp'])

        # check remote track
        frame = run(receiver._track.recv())
        self.assertTrue(isinstance(frame, AudioFrame))

        # shutdown
        run(receiver.stop())
        run(asyncio.sleep(0))
Ejemplo n.º 5
0
    def test_padding_only_with_header_extensions(self):
        extensions_map = rtp.HeaderExtensionsMap()
        extensions_map.configure(
            RTCRtpParameters(headerExtensions=[
                RTCRtpHeaderExtensionParameters(
                    id=2,
                    uri=
                    "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",
                )
            ]))

        data = load("rtp_only_padding_with_header_extensions.bin")
        packet = RtpPacket.parse(data, extensions_map)
        self.assertEqual(packet.version, 2)
        self.assertEqual(packet.marker, 0)
        self.assertEqual(packet.payload_type, 98)
        self.assertEqual(packet.sequence_number, 22138)
        self.assertEqual(packet.timestamp, 3171065731)
        self.assertEqual(packet.csrc, [])
        self.assertEqual(packet.extensions,
                         rtp.HeaderExtensions(abs_send_time=15846540))
        self.assertEqual(len(packet.payload), 0)
        self.assertEqual(packet.padding_size, 224)

        serialized = packet.serialize(extensions_map)
        self.assertEqual(len(serialized), len(data))
        self.assertEqual(serialized[0:20], data[0:20])
        self.assertEqual(serialized[-1], data[-1])
Ejemplo n.º 6
0
    def test_connection_error(self):
        """
        Close the underlying transport before the receiver.
        """
        transport, _ = dummy_dtls_transport_pair()

        receiver = RTCRtpReceiver('audio', transport)
        self.assertEqual(receiver.transport, transport)

        receiver._track = RemoteStreamTrack(kind='audio')
        receiver._ssrc = 1234
        run(receiver.receive(RTCRtpParameters(codecs=[PCMU_CODEC])))

        # receive a packet to prime RTCP
        packet = RtpPacket.parse(load('rtp.bin'))
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # break connection
        run(transport.stop())

        # give RTCP time to send a report
        run(asyncio.sleep(2))

        # shutdown
        run(receiver.stop())
Ejemplo n.º 7
0
    def test_rtx(self):
        extensions_map = rtp.HeaderExtensionsMap()
        extensions_map.configure(
            RTCRtpParameters(headerExtensions=[
                RTCRtpHeaderExtensionParameters(
                    id=9, uri="urn:ietf:params:rtp-hdrext:sdes:mid")
            ]))

        data = load("rtp_with_sdes_mid.bin")
        packet = RtpPacket.parse(data, extensions_map)

        # wrap / unwrap RTX
        rtx = wrap_rtx(packet,
                       payload_type=112,
                       sequence_number=12345,
                       ssrc=1234)
        recovered = unwrap_rtx(rtx, payload_type=111, ssrc=4084547440)

        # check roundtrip
        self.assertEqual(recovered.version, packet.version)
        self.assertEqual(recovered.marker, packet.marker)
        self.assertEqual(recovered.payload_type, packet.payload_type)
        self.assertEqual(recovered.sequence_number, packet.sequence_number)
        self.assertEqual(recovered.timestamp, packet.timestamp)
        self.assertEqual(recovered.ssrc, packet.ssrc)
        self.assertEqual(recovered.csrc, packet.csrc)
        self.assertEqual(recovered.extensions, packet.extensions)
        self.assertEqual(recovered.payload, packet.payload)
Ejemplo n.º 8
0
    def test_rtp_and_rtcp(self):
        receiver = RTCRtpReceiver("audio", self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._track = RemoteStreamTrack(kind="audio")
        self.assertEqual(receiver._track.readyState, "live")
        run(receiver.receive(RTCRtpReceiveParameters(codecs=[PCMU_CODEC])))

        # receive RTP
        for i in range(10):
            packet = RtpPacket.parse(load("rtp.bin"))
            packet.sequence_number += i
            packet.timestamp += i * 160
            run(receiver._handle_rtp_packet(packet, arrival_time_ms=i * 20))

        # receive RTCP SR
        for packet in RtcpPacket.parse(load("rtcp_sr.bin")):
            run(receiver._handle_rtcp_packet(packet))

        # check stats
        report = run(receiver.getStats())
        self.assertTrue(isinstance(report, RTCStatsReport))
        self.assertEqual(
            sorted([s.type for s in report.values()]),
            ["inbound-rtp", "remote-outbound-rtp", "transport"],
        )

        # check sources
        sources = receiver.getSynchronizationSources()
        self.assertEqual(len(sources), 1)
        self.assertTrue(isinstance(sources[0], RTCRtpSynchronizationSource))
        self.assertEqual(sources[0].source, 4028317929)

        # check remote track
        frame = run(receiver._track.recv())
        self.assertEqual(frame.pts, 0)
        self.assertEqual(frame.sample_rate, 8000)
        self.assertEqual(frame.time_base, fractions.Fraction(1, 8000))

        frame = run(receiver._track.recv())
        self.assertEqual(frame.pts, 160)
        self.assertEqual(frame.sample_rate, 8000)
        self.assertEqual(frame.time_base, fractions.Fraction(1, 8000))

        # shutdown
        run(receiver.stop())

        # read until end
        with self.assertRaises(MediaStreamError):
            while True:
                run(receiver._track.recv())
        self.assertEqual(receiver._track.readyState, "ended")

        # try reading again
        with self.assertRaises(MediaStreamError):
            run(receiver._track.recv())
Ejemplo n.º 9
0
 def test_dtmf(self):
     data = load("rtp_dtmf.bin")
     packet = RtpPacket.parse(data)
     self.assertEqual(packet.version, 2)
     self.assertEqual(packet.marker, 1)
     self.assertEqual(packet.payload_type, 101)
     self.assertEqual(packet.sequence_number, 24152)
     self.assertEqual(packet.timestamp, 4021352124)
     self.assertEqual(packet.csrc, [])
     self.assertEqual(packet.extensions, rtp.HeaderExtensions())
     self.assertEqual(len(packet.payload), 4)
     self.assertEqual(packet.serialize(), data)
Ejemplo n.º 10
0
 def test_dtmf(self):
     data = load('rtp_dtmf.bin')
     packet = RtpPacket.parse(data)
     self.assertEqual(packet.version, 2)
     self.assertEqual(packet.extension, 0)
     self.assertEqual(packet.marker, 1)
     self.assertEqual(packet.payload_type, 101)
     self.assertEqual(packet.sequence_number, 24152)
     self.assertEqual(packet.timestamp, 4021352124)
     self.assertEqual(packet.csrc, [])
     self.assertEqual(len(packet.payload), 4)
     self.assertEqual(bytes(packet), data)
Ejemplo n.º 11
0
 def test_padding_only(self):
     data = load('rtp_only_padding.bin')
     packet = RtpPacket.parse(data)
     self.assertEqual(packet.version, 2)
     self.assertEqual(packet.extension, 0)
     self.assertEqual(packet.marker, 0)
     self.assertEqual(packet.payload_type, 120)
     self.assertEqual(packet.sequence_number, 27759)
     self.assertEqual(packet.timestamp, 4044047131)
     self.assertEqual(packet.csrc, [])
     self.assertEqual(len(packet.payload), 0)
     self.assertEqual(bytes(packet), b'\x80' + data[1:12])
Ejemplo n.º 12
0
 def test_with_csrc(self):
     data = load('rtp_with_csrc.bin')
     packet = RtpPacket.parse(data)
     self.assertEqual(packet.version, 2)
     self.assertEqual(packet.extension, 0)
     self.assertEqual(packet.marker, 0)
     self.assertEqual(packet.payload_type, 0)
     self.assertEqual(packet.sequence_number, 16082)
     self.assertEqual(packet.timestamp, 144)
     self.assertEqual(packet.csrc, [2882400001, 3735928559])
     self.assertEqual(len(packet.payload), 160)
     self.assertEqual(bytes(packet), data)
Ejemplo n.º 13
0
 def test_with_csrc(self):
     data = load("rtp_with_csrc.bin")
     packet = RtpPacket.parse(data)
     self.assertEqual(packet.version, 2)
     self.assertEqual(packet.marker, 0)
     self.assertEqual(packet.payload_type, 0)
     self.assertEqual(packet.sequence_number, 16082)
     self.assertEqual(packet.timestamp, 144)
     self.assertEqual(packet.csrc, [2882400001, 3735928559])
     self.assertEqual(packet.extensions, rtp.HeaderExtensions())
     self.assertEqual(len(packet.payload), 160)
     self.assertEqual(packet.serialize(), data)
Ejemplo n.º 14
0
    def test_map_header_extensions(self):
        data = bytearray([
            0x90, 0x64, 0x00, 0x58,
            0x65, 0x43, 0x12, 0x78,
            0x12, 0x34, 0x56, 0x78,  # SSRC
            0xbe, 0xde, 0x00, 0x08,  # Extension of size 8x32bit words.
            0x40, 0xda,              # AudioLevel.
            0x22, 0x01, 0x56, 0xce,  # TransmissionOffset.
            0x62, 0x12, 0x34, 0x56,  # AbsoluteSendTime.
            0x81, 0xce, 0xab,        # TransportSequenceNumber.
            0xa0, 0x03,              # VideoRotation.
            0xb2, 0x12, 0x48, 0x76,  # PlayoutDelayLimits.
            0xc2, 0x72, 0x74, 0x78,  # RtpStreamId
            0xd5, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,  # RepairedRtpStreamId
            0x00, 0x00,              # Padding to 32bit boundary.
        ])
        extensions_map = rtp.HeaderExtensionsMap()
        extensions_map.configure(RTCRtpParameters(
            headerExtensions=[
                RTCRtpHeaderExtensionParameters(
                    id=2,
                    uri='urn:ietf:params:rtp-hdrext:toffset'),
                RTCRtpHeaderExtensionParameters(
                    id=4,
                    uri='urn:ietf:params:rtp-hdrext:ssrc-audio-level'),
                RTCRtpHeaderExtensionParameters(
                    id=6,
                    uri='http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time'),
                RTCRtpHeaderExtensionParameters(
                    id=8,
                    uri='http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01'),  # noqa
                RTCRtpHeaderExtensionParameters(
                    id=12,
                    uri='urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id'),
                RTCRtpHeaderExtensionParameters(
                    id=13,
                    uri='urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id'),
            ]))

        packet = RtpPacket.parse(data, extensions_map)

        # check mapped values
        self.assertEqual(packet.extensions.abs_send_time, 0x123456)
        self.assertEqual(packet.extensions.audio_level, (True, 90))
        self.assertEqual(packet.extensions.mid, None)
        self.assertEqual(packet.extensions.repaired_rtp_stream_id, 'stream')
        self.assertEqual(packet.extensions.rtp_stream_id, 'rtx')
        self.assertEqual(packet.extensions.transmission_offset, 0x156ce)
        self.assertEqual(packet.extensions.transport_sequence_number, 0xceab)

        # TODO: check
        packet.serialize(extensions_map)
Ejemplo n.º 15
0
 def test_with_sdes_mid(self):
     data = load('rtp_with_sdes_mid.bin')
     packet = RtpPacket.parse(data)
     self.assertEqual(packet.version, 2)
     self.assertEqual(packet.marker, 1)
     self.assertEqual(packet.payload_type, 111)
     self.assertEqual(packet.sequence_number, 14156)
     self.assertEqual(packet.timestamp, 1327210925)
     self.assertEqual(packet.csrc, [])
     self.assertEqual(packet.extension_profile, 0xBEDE)
     self.assertEqual(packet.extension_value, b'\x900\x00\x00')
     self.assertEqual(len(packet.payload), 54)
     self.assertEqual(bytes(packet), data)
Ejemplo n.º 16
0
    def test_rtp_and_rtcp(self):
        transport, remote = dummy_dtls_transport_pair()

        receiver = RTCRtpReceiver('audio', transport)
        self.assertEqual(receiver.transport, transport)

        receiver._track = RemoteStreamTrack(kind='audio')
        self.assertEqual(receiver._track.readyState, 'live')
        run(receiver.receive(RTCRtpParameters(codecs=[PCMU_CODEC])))

        # receive RTP
        for i in range(10):
            packet = RtpPacket.parse(load('rtp.bin'))
            packet.sequence_number += i
            packet.timestamp += i * 160
            run(receiver._handle_rtp_packet(packet, arrival_time_ms=i * 20))

        # receive RTCP SR
        for packet in RtcpPacket.parse(load('rtcp_sr.bin')):
            run(receiver._handle_rtcp_packet(packet))

        # check stats
        report = run(receiver.getStats())
        self.assertTrue(isinstance(report, RTCStatsReport))
        self.assertEqual(sorted([s.type for s in report.values()]),
                         ['inbound-rtp', 'remote-outbound-rtp', 'transport'])

        # check remote track
        frame = run(receiver._track.recv())
        self.assertEqual(frame.pts, 0)
        self.assertEqual(frame.sample_rate, 8000)
        self.assertEqual(frame.time_base, fractions.Fraction(1, 8000))

        frame = run(receiver._track.recv())
        self.assertEqual(frame.pts, 160)
        self.assertEqual(frame.sample_rate, 8000)
        self.assertEqual(frame.time_base, fractions.Fraction(1, 8000))

        # shutdown
        run(receiver.stop())

        # read until end
        with self.assertRaises(MediaStreamError):
            while True:
                run(receiver._track.recv())
        self.assertEqual(receiver._track.readyState, 'ended')

        # try reading again
        with self.assertRaises(MediaStreamError):
            run(receiver._track.recv())
Ejemplo n.º 17
0
    def test_no_ssrc(self):
        data = load('rtp.bin')
        packet = RtpPacket.parse(data)
        self.assertEqual(packet.version, 2)
        self.assertEqual(packet.marker, 0)
        self.assertEqual(packet.payload_type, 0)
        self.assertEqual(packet.sequence_number, 15743)
        self.assertEqual(packet.timestamp, 3937035252)
        self.assertEqual(packet.csrc, [])
        self.assertEqual(packet.extensions, rtp.HeaderExtensions())
        self.assertEqual(len(packet.payload), 160)
        self.assertEqual(packet.serialize(), data)

        self.assertEqual(repr(packet),
                         'RtpPacket(seq=15743, ts=3937035252, marker=0, payload=0, 160 bytes)')
Ejemplo n.º 18
0
    def test_padding_only(self):
        data = load("rtp_only_padding.bin")
        packet = RtpPacket.parse(data)
        self.assertEqual(packet.version, 2)
        self.assertEqual(packet.marker, 0)
        self.assertEqual(packet.payload_type, 120)
        self.assertEqual(packet.sequence_number, 27759)
        self.assertEqual(packet.timestamp, 4044047131)
        self.assertEqual(packet.csrc, [])
        self.assertEqual(packet.extensions, rtp.HeaderExtensions())
        self.assertEqual(len(packet.payload), 0)
        self.assertEqual(packet.padding_size, 224)

        serialized = packet.serialize()
        self.assertEqual(len(serialized), len(data))
        self.assertEqual(serialized[0:12], data[0:12])
        self.assertEqual(serialized[-1], data[-1])
Ejemplo n.º 19
0
    def test_padding_only(self):
        data = load('rtp_only_padding.bin')
        packet = RtpPacket.parse(data)
        self.assertEqual(packet.version, 2)
        self.assertEqual(packet.marker, 0)
        self.assertEqual(packet.payload_type, 120)
        self.assertEqual(packet.sequence_number, 27759)
        self.assertEqual(packet.timestamp, 4044047131)
        self.assertEqual(packet.csrc, [])
        self.assertEqual(packet.extension_profile, 0)
        self.assertEqual(packet.extension_value, None)
        self.assertEqual(len(packet.payload), 0)
        self.assertEqual(packet.padding_size, 224)

        serialized = bytes(packet)
        self.assertEqual(len(serialized), len(data))
        self.assertEqual(serialized[0:12], data[0:12])
        self.assertEqual(serialized[-1], data[-1])
Ejemplo n.º 20
0
    async def test_connection_error(self):
        """
        Close the underlying transport before the receiver.
        """
        async with create_receiver("audio") as receiver:
            receiver._track = RemoteStreamTrack(kind="audio")
            receiver._set_rtcp_ssrc(1234)

            await receiver.receive(RTCRtpReceiveParameters(codecs=[PCMU_CODEC]))

            # receive a packet to prime RTCP
            packet = RtpPacket.parse(load("rtp.bin"))
            await receiver._handle_rtp_packet(packet, arrival_time_ms=0)

            # break connection
            await receiver.transport.stop()

            # give RTCP time to send a report
            await asyncio.sleep(2)
Ejemplo n.º 21
0
    def test_with_sdes_mid(self):
        extensions_map = rtp.HeaderExtensionsMap()
        extensions_map.configure(
            RTCRtpParameters(headerExtensions=[
                RTCRtpHeaderExtensionParameters(
                    id=9, uri="urn:ietf:params:rtp-hdrext:sdes:mid")
            ]))

        data = load("rtp_with_sdes_mid.bin")
        packet = RtpPacket.parse(data, extensions_map)
        self.assertEqual(packet.version, 2)
        self.assertEqual(packet.marker, 1)
        self.assertEqual(packet.payload_type, 111)
        self.assertEqual(packet.sequence_number, 14156)
        self.assertEqual(packet.timestamp, 1327210925)
        self.assertEqual(packet.csrc, [])
        self.assertEqual(packet.extensions, rtp.HeaderExtensions(mid="0"))
        self.assertEqual(len(packet.payload), 54)
        self.assertEqual(packet.serialize(extensions_map), data)
Ejemplo n.º 22
0
    def _crypt_packet(self, rtp_packet: bytes, encrypt: bool) -> RtpPacket:
        rtp_header = rtp_packet[:12]
        parsed = RtpPacket.parse(rtp_packet)

        if parsed.sequence_number < self.seq:
            self.roc += 1
        self.seq = parsed.sequence_number
        pkt_i = SrtpContext.packet_index(self.roc, self.seq)
        iv = SrtpContext._calc_iv(self.session_keys.salt_key[2:], parsed.ssrc,
                                  pkt_i)

        if encrypt:
            transformed_payload = SrtpContext._encrypt(self.crypto_ctx, iv,
                                                       parsed.payload,
                                                       rtp_header)
        else:
            transformed_payload = SrtpContext._decrypt(self.crypto_ctx, iv,
                                                       parsed.payload,
                                                       rtp_header)

        parsed.payload = transformed_payload
        return parsed
Ejemplo n.º 23
0
    def test_connection_error(self):
        """
        Close the underlying transport before the receiver.
        """
        receiver = RTCRtpReceiver("audio", self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._track = RemoteStreamTrack(kind="audio")
        receiver._set_rtcp_ssrc(1234)
        run(receiver.receive(RTCRtpReceiveParameters(codecs=[PCMU_CODEC])))

        # receive a packet to prime RTCP
        packet = RtpPacket.parse(load("rtp.bin"))
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # break connection
        run(self.local_transport.stop())

        # give RTCP time to send a report
        run(asyncio.sleep(2))

        # shutdown
        run(receiver.stop())
Ejemplo n.º 24
0
 def test_padding_too_long(self):
     data = load("rtp_only_padding.bin")[0:12] + b"\x02"
     with self.assertRaises(ValueError) as cm:
         RtpPacket.parse(data)
     self.assertEqual(str(cm.exception),
                      "RTP packet padding length is invalid")
Ejemplo n.º 25
0
 def test_bad_version(self):
     data = b'\xc0' + load('rtp.bin')[1:]
     with self.assertRaises(ValueError) as cm:
         RtpPacket.parse(data)
     self.assertEqual(str(cm.exception), 'RTP packet has invalid version')
Ejemplo n.º 26
0
 def test_truncated(self):
     data = load('rtp.bin')[0:11]
     with self.assertRaises(ValueError) as cm:
         RtpPacket.parse(data)
     self.assertEqual(str(cm.exception),
                      'RTP packet length is less than 12 bytes')
Ejemplo n.º 27
0
 async def _send_rtp(self, data):
     if not is_rtcp(data):
         packet = RtpPacket.parse(data)
         await self.queue.put(packet)
Ejemplo n.º 28
0
 def test_padding_zero(self):
     data = load('rtp_only_padding.bin')[0:12] + b'\x00'
     with self.assertRaises(ValueError) as cm:
         RtpPacket.parse(data)
     self.assertEqual(str(cm.exception),
                      'RTP packet padding length is invalid')
Ejemplo n.º 29
0
 async def mock_send_rtp(data):
     if not is_rtcp(data):
         await queue.put(RtpPacket.parse(data))