Пример #1
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
        run(remote.send(load('rtp.bin')))

        # receive RTCP
        run(remote.send(load('rtcp_sr.bin')))

        # receive truncated RTCP
        run(remote.send(b'\x81\xca\x00'))

        # receive garbage
        run(remote.send(b'garbage'))

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

        # shutdown
        run(asyncio.sleep(0.1))
        receiver.stop()
        run(asyncio.sleep(0))
Пример #2
0
    def test_rtp_missing_video_packet(self):
        nacks = []

        async def mock_send_rtcp_nack(*args):
            nacks.append(args)

        receiver = RTCRtpReceiver('video', self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._send_rtcp_nack = mock_send_rtcp_nack
        receiver._track = RemoteStreamTrack(kind='video')
        run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC])))

        # generate some packets
        packets = create_rtp_video_packets(self, codec=VP8_CODEC, frames=3)

        # receive RTP with a with a gap
        run(receiver._handle_rtp_packet(packets[0], arrival_time_ms=0))
        run(receiver._handle_rtp_packet(packets[2], arrival_time_ms=0))

        # check NACK was triggered
        self.assertEqual(nacks, [(1234, [1])])

        # shutdown
        run(receiver.stop())
Пример #3
0
    def test_rtp_rtx(self):
        receiver = RTCRtpReceiver('video', self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._track = RemoteStreamTrack(kind='video')
        run(
            receiver.receive(
                RTCRtpReceiveParameters(
                    codecs=[
                        VP8_CODEC,
                        RTCRtpCodecParameters(mimeType='video/rtx',
                                              clockRate=90000,
                                              payloadType=101,
                                              parameters={'apt': 100}),
                    ],
                    encodings=[
                        RTCRtpEncodingParameters(
                            ssrc=1234,
                            payloadType=100,
                            rtx=RTCRtpRtxParameters(ssrc=2345))
                    ])))

        # receive RTX with payload
        packet = RtpPacket(payload_type=101, ssrc=2345, payload=b'\x00\x00')
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # receive RTX without payload
        packet = RtpPacket(payload_type=101, ssrc=2345)
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # shutdown
        run(receiver.stop())
Пример #4
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())
Пример #5
0
    def test_rtp_rtx_unknown_ssrc(self):
        receiver = RTCRtpReceiver("video", self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._track = RemoteStreamTrack(kind="video")
        run(
            receiver.receive(
                RTCRtpReceiveParameters(
                    codecs=[
                        VP8_CODEC,
                        RTCRtpCodecParameters(
                            mimeType="video/rtx",
                            clockRate=90000,
                            payloadType=101,
                            parameters={"apt": 100},
                        ),
                    ]
                )
            )
        )

        # receive RTX with unknown SSRC
        packet = RtpPacket(payload_type=101, ssrc=1234)
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # shutdown
        run(receiver.stop())
Пример #6
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))
Пример #7
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')
Пример #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())
Пример #9
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)

        run(receiver.receive(RTCRtpParameters(codecs=[PCMU_CODEC])))

        run(transport.close())
Пример #10
0
    def test_send_rtcp_nack(self):
        receiver = RTCRtpReceiver("video", self.local_transport)
        receiver._set_rtcp_ssrc(1234)
        receiver._track = RemoteStreamTrack(kind="video")

        run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC])))

        # send RTCP feedback NACK
        run(receiver._send_rtcp_nack(5678, [7654]))

        # shutdown
        run(receiver.stop())
Пример #11
0
    def test_send_rtcp_pli(self):
        receiver = RTCRtpReceiver('video', self.local_transport)
        receiver._set_rtcp_ssrc(1234)
        receiver._track = RemoteStreamTrack(kind='video')

        run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC])))

        # send RTCP feedback PLI
        run(receiver._send_rtcp_pli(5678))

        # shutdown
        run(receiver.stop())
Пример #12
0
    def test_rtp_unknown_payload_type(self):
        receiver = RTCRtpReceiver('video', self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._track = RemoteStreamTrack(kind='video')
        run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC])))

        # receive RTP with unknown payload type
        packet = RtpPacket(payload_type=123)
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # shutdown
        run(receiver.stop())
Пример #13
0
    def test_rtp_empty_video_packet(self):
        receiver = RTCRtpReceiver("video", self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._track = RemoteStreamTrack(kind="video")
        run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC])))

        # receive RTP with empty payload
        packet = RtpPacket(payload_type=100)
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # shutdown
        run(receiver.stop())
Пример #14
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())
Пример #15
0
    def test_send_rtcp_pli(self):
        receiver = RTCRtpReceiver('video', self.local_transport)
        receiver._ssrc = 1234
        receiver._track = RemoteStreamTrack(kind='video')

        run(receiver.receive(RTCRtpParameters(codecs=[
            RTCRtpCodecParameters(name='VP8', clockRate=90000, payloadType=100),
        ])))

        # send RTCP feedback PLI
        run(receiver._send_rtcp_pli(5678))

        # shutdown
        run(receiver.stop())
Пример #16
0
    def test_rtp_empty_video_packet(self):
        receiver = RTCRtpReceiver('video', self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._track = RemoteStreamTrack(kind='video')
        run(receiver.receive(RTCRtpParameters(codecs=[
            RTCRtpCodecParameters(name='VP8', clockRate=90000, payloadType=100),
        ])))

        # receive RTP with empty payload
        packet = RtpPacket(payload_type=100)
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # shutdown
        run(receiver.stop())
Пример #17
0
    def test_send_rtcp_nack(self):
        transport, remote = dummy_dtls_transport_pair()

        receiver = RTCRtpReceiver('video', transport)
        receiver._ssrc = 1234
        receiver._track = RemoteStreamTrack(kind='video')

        run(receiver.receive(RTCRtpParameters(codecs=[
            RTCRtpCodecParameters(name='VP8', clockRate=90000, payloadType=100),
        ])))

        # send RTCP feedback NACK
        run(receiver._send_rtcp_nack(5678, [7654]))

        # shutdown
        run(receiver.stop())
Пример #18
0
    def test_rtp_empty_video_packet(self):
        transport, remote = dummy_dtls_transport_pair()

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

        receiver._track = RemoteStreamTrack(kind='audio')
        run(
            receiver.receive(
                RTCRtpParameters(codecs=[
                    RTCRtpCodecParameters(
                        name='VP8', clockRate=90000, payloadType=100),
                ])))

        # receive RTP with empty payload
        packet = RtpPacket(payload_type=100)
        run(receiver._handle_rtp_packet(packet))
Пример #19
0
    def test_rtp_rtx_unknown_ssrc(self):
        receiver = RTCRtpReceiver('video', self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._track = RemoteStreamTrack(kind='video')
        run(receiver.receive(RTCRtpReceiveParameters(
            codecs=[
                RTCRtpCodecParameters(name='VP8', clockRate=90000, payloadType=100),
                RTCRtpCodecParameters(name='rtx', clockRate=90000, payloadType=101,
                                      parameters={'apt': 100}),
            ])))

        # receive RTX with unknown SSRC
        packet = RtpPacket(payload_type=101, ssrc=1234)
        run(receiver._handle_rtp_packet(packet, arrival_time_ms=0))

        # shutdown
        run(receiver.stop())
Пример #20
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())
Пример #21
0
    def test_rtp_missing_video_packet(self):
        nacks = []
        pli = []

        async def mock_send_rtcp_nack(*args):
            nacks.append(args)

        async def mock_send_rtcp_pli(*args):
            pli.append(args[0])

        receiver = RTCRtpReceiver("video", self.local_transport)
        self.assertEqual(receiver.transport, self.local_transport)

        receiver._send_rtcp_nack = mock_send_rtcp_nack
        receiver._send_rtcp_pli = mock_send_rtcp_pli
        receiver._track = RemoteStreamTrack(kind="video")
        run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC])))

        # generate some packets
        packets = create_rtp_video_packets(self, codec=VP8_CODEC, frames=129)

        # receive RTP with a with a gap
        run(receiver._handle_rtp_packet(packets[0], arrival_time_ms=0))
        run(receiver._handle_rtp_packet(packets[128], arrival_time_ms=0))

        # check NACK was triggered
        lost_packets = []
        for i in range(127):
            lost_packets.append(i + 1)
        self.assertEqual(nacks[0], (1234, lost_packets))

        # check PLI was triggered
        self.assertEqual(pli, [1234])

        # shutdown
        run(receiver.stop())