├── LICENSE.md ├── .note.xml ├── .gitignore ├── Makefile ├── notes ├── notes.md └── notes_data_transmission.md ├── .github └── workflows │ ├── update.yml │ ├── archive.yml │ ├── publish.yml │ └── ghpages.yml ├── README.md ├── CONTRIBUTING.md ├── .circleci └── config.yml ├── draft-sharabayko-srt-over-quic.md └── images ├── SRT_DecoderUnhappy.svg └── SRT_DecoderHappy.svg /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | See the 4 | [guidelines for contributions](https://github.com/Haivision/srt-rfc/blob/master/CONTRIBUTING.md). 5 | -------------------------------------------------------------------------------- /.note.xml: -------------------------------------------------------------------------------- 1 | 2 | Source for this draft and an issue tracker can be found at 3 | https://github.com/haivision/srt-rfc. 4 | 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.pdf 3 | *.redxml 4 | *.swp 5 | *.txt 6 | *.upload 7 | *~ 8 | .refcache 9 | .tags 10 | .targets.mk 11 | /*-[0-9][0-9].xml 12 | issues.json 13 | pulls.json 14 | report.xml 15 | venv/ 16 | lib 17 | draft-sharabayko-srt.xml 18 | 19 | # Mac OS X 20 | .DS_Store 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | LIBDIR := lib 2 | include $(LIBDIR)/main.mk 3 | 4 | $(LIBDIR)/main.mk: 5 | ifneq (,$(shell grep "path *= *$(LIBDIR)" .gitmodules 2>/dev/null)) 6 | git submodule sync 7 | git submodule update $(CLONE_ARGS) --init 8 | else 9 | git clone -q --depth 10 $(CLONE_ARGS) \ 10 | -b main https://github.com/martinthomson/i-d-template $(LIBDIR) 11 | endif 12 | -------------------------------------------------------------------------------- /notes/notes.md: -------------------------------------------------------------------------------- 1 | # Notes 2 | 3 | 1. Create "Notations" section and collect all the abbreviations, e.g., TSBPD, TLPKTDROP, SRT, round-trip time (RTT), etc. 4 | 5 | ## ToDo - Next iteration 6 | 7 | Maria: 8 | - Rework Acknowledgemnets section, 9 | - How the estimations are obtained: bw, rcv speed, RTT - separate section with the algorithm description. 10 | - SRT statisitcs which is avaialable from sender, receiver 11 | - Improve TSBPD, TLPKTDROP 12 | - Rework Drift Management -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | name: "Update Generated Files" 2 | # This rule is not run automatically. 3 | # It can be run manually to update all of the files that are part 4 | # of the template, specifically: 5 | # - README.md 6 | # - CONTRIBUTING.md 7 | # - .note.xml 8 | # - .github/CODEOWNERS 9 | # - Makefile 10 | # 11 | # 12 | # This might be useful if you have: 13 | # - added, removed, or renamed drafts (including after adoption) 14 | # - added, removed, or changed draft editors 15 | # - changed the title of drafts 16 | # 17 | # Note that this removes any customizations you have made to 18 | # the affected files. 19 | on: workflow_dispatch 20 | 21 | jobs: 22 | build: 23 | name: "Update Files" 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: "Checkout" 27 | uses: actions/checkout@v2 28 | 29 | - name: "Update Generated Files" 30 | uses: martinthomson/i-d-template@v1 31 | with: 32 | make: update-files 33 | token: ${{ github.token }} 34 | 35 | - name: "Push Update" 36 | run: git push 37 | -------------------------------------------------------------------------------- /.github/workflows/archive.yml: -------------------------------------------------------------------------------- 1 | name: "Archive Issues and Pull Requests" 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * 0,2,4' 6 | repository_dispatch: 7 | types: [archive] 8 | workflow_dispatch: 9 | inputs: 10 | archive_full: 11 | description: 'Recreate the archive from scratch' 12 | default: false 13 | type: boolean 14 | 15 | jobs: 16 | build: 17 | name: "Archive Issues and Pull Requests" 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: "Checkout" 21 | uses: actions/checkout@v2 22 | 23 | # Note: No caching for this build! 24 | 25 | - name: "Update Archive" 26 | uses: martinthomson/i-d-template@v1 27 | env: 28 | ARCHIVE_FULL: ${{ inputs.archive_full }} 29 | with: 30 | make: archive 31 | token: ${{ github.token }} 32 | 33 | - name: "Update GitHub Pages" 34 | uses: martinthomson/i-d-template@v1 35 | with: 36 | make: gh-archive 37 | token: ${{ github.token }} 38 | 39 | - name: "Save Archive" 40 | uses: actions/upload-artifact@v2 41 | with: 42 | path: archive.json 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The SRT Protocol RFCs 2 | 3 | This is the working area for the individual Internet-Draft, "The SRT Protocol" and "Tunnelling SRT over QUIC". 4 | 5 | ## The SRT Protocol RFC 6 | 7 | * Working Copy: [html](https://Haivision.github.io/srt-rfc/#go.draft-sharabayko-srt.html), [plain text](https://Haivision.github.io/srt-rfc/#go.draft-sharabayko-srt.txt) 8 | * [Latest IETF RFC Draft](https://tools.ietf.org/html/draft-sharabayko-srt-00) 9 | * [Compare Working's Copy to IETF RFC Draft](https://Haivision.github.io/srt-rfc/#go.draft-sharabayko-srt.diff) 10 | 11 | ## Tunnelling SRT over QUIC RFC 12 | 13 | * Working Copy: [html](https://Haivision.github.io/srt-rfc/draft-sharabayko-srt-over-quic.html), [plain text](https://Haivision.github.io/srt-rfc/draft-sharabayko-srt-over-quic.txt) 14 | 15 | ## Building the Draft 16 | 17 | Formatted text and HTML versions of the draft can be built using `make`. 18 | 19 | ```sh 20 | $ make 21 | ``` 22 | 23 | This requires that you have the necessary software installed. See 24 | [the instructions](https://github.com/martinthomson/i-d-template/blob/master/doc/SETUP.md). 25 | 26 | ## Contributing 27 | 28 | See the 29 | [guidelines for contributions](https://github.com/Haivision/srt-rfc/blob/master/CONTRIBUTING.md). 30 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: "Publish New Draft Version" 2 | 3 | on: 4 | push: 5 | tags: 6 | - "draft-*" 7 | 8 | jobs: 9 | build: 10 | name: "Publish New Draft Version" 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: "Checkout" 14 | uses: actions/checkout@v3 15 | 16 | # See https://github.com/actions/checkout/issues/290 17 | - name: "Get Tag Annotations" 18 | run: git fetch -f origin ${{ github.ref }}:${{ github.ref }} 19 | 20 | - name: "Setup" 21 | id: setup 22 | run: date -u "+::set-output name=date::%FT%T" 23 | 24 | - name: "Caching" 25 | uses: actions/cache@v3 26 | with: 27 | path: | 28 | .refcache 29 | .venv 30 | .gems 31 | node_modules 32 | .targets.mk 33 | key: i-d-${{ steps.setup.outputs.date }} 34 | restore-keys: i-d- 35 | 36 | - name: "Build Drafts" 37 | uses: martinthomson/i-d-template@v1 38 | with: 39 | token: ${{ github.token }} 40 | 41 | - name: "Upload to Datatracker" 42 | uses: martinthomson/i-d-template@v1 43 | with: 44 | make: upload 45 | 46 | - name: "Archive Submitted Drafts" 47 | uses: actions/upload-artifact@v2 48 | with: 49 | path: "draft-*-[0-9][0-9].xml" 50 | -------------------------------------------------------------------------------- /.github/workflows/ghpages.yml: -------------------------------------------------------------------------------- 1 | name: "Update Editor's Copy" 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - README.md 7 | - CONTRIBUTING.md 8 | - LICENSE.md 9 | - .gitignore 10 | pull_request: 11 | paths-ignore: 12 | - README.md 13 | - CONTRIBUTING.md 14 | - LICENSE.md 15 | - .gitignore 16 | 17 | jobs: 18 | build: 19 | name: "Update Editor's Copy" 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: "Checkout" 23 | uses: actions/checkout@v3 24 | 25 | - name: "Setup" 26 | id: setup 27 | run: date -u "+::set-output name=date::%FT%T" 28 | 29 | - name: "Caching" 30 | uses: actions/cache@v3 31 | with: 32 | path: | 33 | .refcache 34 | .venv 35 | .gems 36 | node_modules 37 | .targets.mk 38 | key: i-d-${{ steps.setup.outputs.date }} 39 | restore-keys: i-d- 40 | 41 | - name: "Build Drafts" 42 | uses: martinthomson/i-d-template@main 43 | with: 44 | token: ${{ github.token }} 45 | 46 | - name: "Update GitHub Pages" 47 | uses: martinthomson/i-d-template@v1 48 | if: ${{ github.event_name == 'push' }} 49 | with: 50 | make: gh-pages 51 | token: ${{ github.token }} 52 | 53 | - name: "Archive Built Drafts" 54 | uses: actions/upload-artifact@v2 55 | with: 56 | path: | 57 | draft-*.html 58 | draft-*.txt 59 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This repository relates to activities in the Internet Engineering Task Force 4 | ([IETF](https://www.ietf.org/)). All material in this repository is considered 5 | Contributions to the IETF Standards Process, as defined in the intellectual 6 | property policies of IETF currently designated as 7 | [BCP 78](https://www.rfc-editor.org/info/bcp78), 8 | [BCP 79](https://www.rfc-editor.org/info/bcp79) and the 9 | [IETF Trust Legal Provisions (TLP) Relating to IETF Documents](http://trustee.ietf.org/trust-legal-provisions.html). 10 | 11 | Any edit, commit, pull request, issue, comment or other change made to this 12 | repository constitutes Contributions to the IETF Standards Process 13 | (https://www.ietf.org/). 14 | 15 | You agree to comply with all applicable IETF policies and procedures, including, 16 | BCP 78, 79, the TLP, and the TLP rules regarding code components (e.g. being 17 | subject to a Simplified BSD License) in Contributions. 18 | 19 | 20 | ## Other Resources 21 | 22 | Discussion of this work occurs on the 23 | [srt working group mailing list](https://mailarchive.ietf.org/arch/browse/srt/) 24 | ([subscribe](https://www.ietf.org/mailman/listinfo/srt)). In addition to 25 | contributions in GitHub, you are encouraged to participate in discussions there. 26 | 27 | **Note**: Some working groups adopt a policy whereby substantive discussion of 28 | technical issues needs to occur on the mailing list. 29 | 30 | You might also like to familiarize yourself with other 31 | [working group documents](https://datatracker.ietf.org/wg/srt/documents/). 32 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: martinthomson/i-d-template:latest 6 | working_directory: ~/draft 7 | 8 | steps: 9 | - run: 10 | name: "Print Configuration" 11 | command: | 12 | xml2rfc --version 13 | gem list -q kramdown-rfc2629 14 | echo -n 'mmark '; mmark --version 15 | 16 | - restore_cache: 17 | name: "Restoring cache - Git" 18 | keys: 19 | - v1-cache-git-{{ .Branch }}-{{ .Revision }} 20 | - v1-cache-git-{{ .Branch }} 21 | - v1-cache-git-master 22 | - v1-cache-git- 23 | 24 | - restore_cache: 25 | name: "Restoring cache - References" 26 | keys: 27 | - v1-cache-references-{{ epoch }} 28 | - v1-cache-references- 29 | 30 | - checkout 31 | 32 | # Build txt and html versions of drafts 33 | - run: 34 | name: "Build Drafts" 35 | command: "make 'CLONE_ARGS=--reference ~/git-reference'" 36 | 37 | # Update editor's copy on gh-pages 38 | - run: 39 | name: "Update GitHub Pages" 40 | command: | 41 | if [ "${CIRCLE_TAG#draft-}" == "${CIRCLE_TAG}" ]; then 42 | make gh-pages 43 | fi 44 | 45 | # For tagged builds, upload to the datatracker. 46 | - deploy: 47 | name: "Upload to Datatracker" 48 | command: | 49 | if [ "${CIRCLE_TAG#draft-}" != "${CIRCLE_TAG}" ]; then 50 | make upload 51 | fi 52 | 53 | # Save GitHub issues 54 | - run: 55 | name: "Save GitHub Issues" 56 | command: "make issues || make issues DISABLE_ISSUE_FETCH=true && make gh-issues" 57 | 58 | # Create and store artifacts 59 | - run: 60 | name: "Create Artifacts" 61 | command: "make artifacts CI_ARTIFACTS=/tmp/artifacts" 62 | 63 | - store_artifacts: 64 | path: /tmp/artifacts 65 | 66 | - run: 67 | name: "Prepare for Caching" 68 | command: "git gc --auto" 69 | 70 | - save_cache: 71 | name: "Saving Cache - Git" 72 | key: v1-cache-git-{{ .Branch }}-{{ .Revision }} 73 | paths: 74 | - ~/draft 75 | 76 | - save_cache: 77 | name: "Saving Cache - Drafts" 78 | key: v1-cache-references-{{ epoch }} 79 | paths: 80 | - ~/.cache/xml2rfc 81 | 82 | 83 | workflows: 84 | version: 2 85 | build: 86 | jobs: 87 | - build: 88 | filters: 89 | tags: 90 | only: /.*?/ 91 | -------------------------------------------------------------------------------- /notes/notes_data_transmission.md: -------------------------------------------------------------------------------- 1 | # Notes - Data Transmission and Control Section 2 | 3 | ## Timestamp Based Packet Delivery {#tsbpd} 4 | 5 | 1. Insert link to SRT connection creation time, SRT latency. 6 | 7 | 2. Reflect three main ideas of this section: 8 | * After handshakes exchange - end-to-end delay is fixed 9 | * It's worth noting that TsbpdDelay limits the number of packet retransmissions to a certain extent making impossible to retransmit packets endlessly. This is important for live data transmission. 10 | * Each packet has timestamp (when it was ready to be sent), receiver uses this timestamp to calculate delivery time: send time + end-to-end delay = read time 11 | 12 | #### TSBPD Time Base Calculation {#tsbpd-time-base} 13 | 14 | 1. Some introductory notes - not necessary to add 15 | 16 | Timestamps are relative to the connection. The transmission is not based on an absolute time. 17 | The scheduled execution time is based on a real clock time. A time base is maintained to 18 | convert each packet‘s timestamp to local clock time. Packets are offset from the sender‘s 19 | StartTime. Any time reference based on local StartTime is maintained, taking into account RTT, 20 | time zone and drift caused by the sum of truncated nanoseconds and other measurements. 21 | 22 | 2. TSBPD wrapping period: add pseudo-code. 23 | 24 | 3. Deleted 25 | 26 | It is designed in a way that SRT receiver, using the timestamp of the SRT data packet header, 27 | delivers packets to a receiving application at the same pace they were provided to the SRT sender by a sending applicaton. 28 | 29 | 4. Rewrite introduction 30 | 31 | This 32 | The goal of the SRT Timestamp Based Packet Delivery (TSBPD) mechanism 33 | is to reproduce the output of the sending application (e.g., encoder) 34 | at the input of the receiving one (e.g., decoder) in live data 35 | transmission mode (see {{data-transmission-mode}}). In terms of SRT, 36 | it means to reproduce the timing of packets commited by the sending 37 | application to the SRT sender at the timing packets are scheduled 38 | for the delivery by the SRT receiver and ready to be read by the 39 | receiving application (see {{fig-latency-points}}). 40 | 41 | This 42 | The packet timestamp (in microseconds) is relative to the SRT connection creation time. 43 | **It is worth mentioning that the use of the packet sending time to stamp the packets is 44 | inappropriate for TSBPD feature since a new time (current sending time) is used for retransmitted packets, 45 | putting them out of order when inserted at their proper place in the stream. Packets are 46 | inserted based on the sequence number in the header field.** The origin time (in microseconds) 47 | of the packet is already sampled when a packet is first submitted by the application to the SRT sender. 48 | The TSBPD feature uses this time to stamp the packet for first transmission and any subsequent retransmission. 49 | This timestamp and the configured SRT latency control the recovery buffer size and the instant that packets 50 | are delivered at the destination. 51 | 52 | ## Too-Late Packet Drop {#too-late-packet-drop} 53 | 54 | 1. Rephrase this part 55 | 56 | Implementation related, delete implementation details in future: 57 | In the SRT sender, when Too-Late Packet Drop is enabled, a packet is 58 | considered too late to be delivered and may be dropped by the sending 59 | application if its timestamp is older than 125% of the SRT latency. 60 | However, the sender keeps packets for at least 1 second in case the 61 | SRT latency is not enough for a large RTT (that is, if 125% of the 62 | SRT latency is less than 1 second). 63 | 64 | 2. Pictures and tables to illustrate pseudo-code 65 | 66 | This table should be corrected, but as an example 67 | 68 | | s @ Dst | SrcTime (PKT_TIMESTAMP) | SND Clock | Time Base | RCV Clock | SRT Latency | Drift | Packet Delivery Time | | 69 | |---------|-------------------------|--------------|--------------|--------------|-------------|-------|----------------------|---| 70 | | 1 | 20 | 00:00:00,020 | 00:00:00,040 | 00:00:00,060 | 120 | 0 | 00:00:00,180 | | 71 | | 2 | 40 | 00:00:00,040 | 00:00:00,040 | 00:00:00,080 | 120 | 0 | 00:00:00,200 | | 72 | | 5 | 100 | 00:00:00,100 | 00:00:00,040 | 00:00:00,140 | 120 | 0 | 00:00:00,260 | | 73 | | 6 | 120 | 00:00:00,120 | 00:00:00,040 | 00:00:00,160 | 120 | 0 | 00:00:00,280 | | 74 | | 7 | 140 | 00:00:00,140 | 00:00:00,040 | 00:00:00,180 | 120 | 0 | 00:00:00,300 | | 75 | | 8 | 160 | 00:00:00,160 | 00:00:00,040 | 00:00:00,200 | 120 | 0 | 00:00:00,320 | | 76 | | 3 | 60 | 00:00:00,060 | 00:00:00,040 | 00:00:00,210 | 120 | 0 | 00:00:00,220 | | 77 | | 4 | 80 | 00:00:00,080 | 00:00:00,040 | 00:00:00,212 | 120 | 0 | 00:00:00,240 | | 78 | | 9 | 180 | 00:00:00,180 | 00:00:00,040 | 00:00:00,220 | 120 | 0 | 00:00:00,340 | | 79 | | 10 | 200 | 00:00:00,200 | 00:00:00,040 | 00:00:00,240 | 120 | 0 | 00:00:00,360 | | 80 | 81 | 3. According to Maxim, this additional delay is implementation related 82 | 83 | From API 84 | 85 | NB: The default live mode settings set SRTO_SNDDROPDELAY to 0. The buffer mode settings set SRTO_SNDDROPDELAY to -1. 86 | 87 | [SET] - Sets an extra delay before TLPKTDROP is triggered on the data sender. TLPKTDROP discards packets reported as lost if it is already too late to send them (the receiver would discard them even if received). The total delay before TLPKTDROP is triggered consists of the LATENCY (SRTO_PEERLATENCY), plus SRTO_SNDDROPDELAY, plus 2 * the ACK interval (default ACK interval is 10ms). The minimum total delay is 1 second. A value of -1 discards packet drop. SRTO_SNDDROPDELAY extends the tolerance for retransmitting packets at the expense of more likely retransmitting them uselessly. To be effective, it must have a value greater than 1000 - SRTO_PEERLATENCY. 88 | 89 | 4. Note regarding acknowledgment process for dropped packets. 90 | 91 | TODO: It also sends a fake ACK message to the sender. - Should we write about this? 92 | 93 | ## Drift Management {#drift-management} 94 | 95 | 1. Add detailed description of the algorithm with pseudo-code. 96 | https://srtlab.github.io/srt-cookbook/protocol/tsbpd/drift-management/ 97 | 98 | 2. Some parts of the current drift description can be moved into introduction or other sections of TSBPD as the introductory words. Here we can leave only the idea and pseudo-code. 99 | 100 | E.g., this part 101 | 102 | The receiver uses local time to be able to schedule events — to 103 | determine, for example, if it's time to deliver a certain packet 104 | right away. The timestamps in the packets themselves are just 105 | references to the beginning of the session. When a packet is received 106 | (with a timestamp from the sender), the receiver makes a reference to 107 | the beginning of the session to recalculate its timestamp. The start 108 | time is derived from the local time at the moment that the session is 109 | connected. A packet timestamp equals "now" minus "StartTime", where 110 | zthe latter is the point in time when the socket was created. 111 | 112 | 3. Note regarding drift tracer: The current algorithm does not take into account RTT variations, but we are going to improve this. 113 | 114 | Assuming that the link latency is constant (RTT=const), the only cause of the drift fluctuations should be clock inaccuracy. 115 | 116 | ## SRT Buffer Latency 117 | 118 | 1. Describe the difference between sender buffer latency and receiver buffer latency which is configered in SRT settings and is TsbpdDelay at the same time. 119 | 120 | ## Acknowledgement and Lost Packet Handling 121 | 122 | This section should be reworked completely. 123 | 124 | 1. From the very beginning we should list the types of ack packets. 125 | 126 | We should say that there are two types of packets: data and control. Then there several types of control packets: list them -> maybe it's better to do at the very beginning of Data Transmission section. 127 | 128 | And here we say that ack packets are control packets. And there are several types of ack packets, list them. 129 | 130 | - ACK (full ACK, light ACK) 131 | - ACKACK 132 | - NAK 133 | - Periodic NAK 134 | 135 | 2. Later we should have the algorithms of working with each type of ack like 136 | 137 | On receipt of ACK do: 1, 2, etc. 138 | Plus the timing of receiving and processing ack-s. 139 | 140 | 3. Tell what's inside ack-s: RTT, BW, Rcv speed estimations, etc. 141 | 142 | Each ACK has a number. A corresponding ACKACK has that same number. 143 | The receiver keeps a list of all ACKs in a queue to match them. Unlike a full ACK, 144 | which contains the current RTT and several other values in the CIF, 145 | a light ACK just contains the sequence number. All control messages are sent directly and 146 | processed upon reception, but ACKACK processing time is negligible (the time this takes 147 | is included in the round-trip time). 148 | 149 | 4. How the estimations are obtained: bw, rcv speed, RTT - separate section with the algorithm description. 150 | 151 | 5. Move the bold part to TLPKTDROP, TSBPD regarding 1 second latency in sender buffer 152 | 153 | This condition where packets are unsent doesn't happen often. There is a maximum number of 154 | packets held in the send buffer based on the configured latency. Older packets that have no 155 | chance to be retransmitted and played in time are dropped, making room for newer real-time 156 | packets produced by the sending application. See sections {{tsbpd}}, {{too-late-packet-drop}} for details. 157 | **A minimum of one second is applied before 158 | dropping the packet when low latency is configured. This one-second limit derives from the 159 | behavior of MPEG I-frames with SRT used as transport. I-frames are very large (typically 8 times 160 | larger than other packets), and consequently take more time to transmit. They can be too large 161 | to keep in the latency window, and can cause packets to be dropped from the queue. To 162 | prevent this, SRT imposes a minimum of one second (or the latency value) before dropping a 163 | packet. This allows for large I-frames when using small latency values.** -------------------------------------------------------------------------------- /draft-sharabayko-srt-over-quic.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tunnelling SRT over QUIC 3 | abbrev: SRTQ 4 | docname: draft-sharabayko-srt-over-quic-latest 5 | category: exp 6 | submissiontype: independent 7 | 8 | ipr: trust200902 9 | area: 10 | workgroup: TODO Working Group 11 | keyword: Internet-Draft 12 | 13 | stand_alone: yes 14 | pi: [toc, sortrefs, symrefs] 15 | 16 | author: 17 | - 18 | ins: "M.P. Sharabayko" 19 | name: "Maxim Sharabayko" 20 | organization: "Haivision Network Video, GmbH" 21 | email: maxsharabayko@haivision.com 22 | - 23 | ins: "M.A. Sharabayko" 24 | name: "Maria Sharabayko" 25 | organization: "Haivision Network Video, GmbH" 26 | email: msharabayko@haivision.com 27 | 28 | normative: 29 | RFC7323: 30 | RFC9000: 31 | RFC2119: 32 | RFC8174: 33 | informative: 34 | SRTRFC: 35 | target: https://datatracker.ietf.org/doc/draft-sharabayko-srt/ 36 | title: The SRT Protocol 37 | author: 38 | - 39 | name: Maxim Sharabayko 40 | - 41 | name: Maria Sharabayko 42 | - 43 | name: Jean Dube 44 | - 45 | name: Jeongseok Kim 46 | - 47 | name: Joonwoong Kim 48 | date: December, 2019 49 | 50 | QUIC-DATAGRAM: 51 | target: https://datatracker.ietf.org/doc/draft-ietf-quic-datagram/ 52 | title: An Unreliable Datagram Extension to QUIC 53 | author: 54 | - 55 | name: T. Pauly 56 | - 57 | name: E. Kinnear 58 | - 59 | name: D. Schinazi 60 | 61 | QUICLY: 62 | target: https://github.com/h2o/quicly 63 | title: QUIC protocol implementation quicly for H2O server 64 | date: none 65 | 66 | --- abstract 67 | 68 | This document presents an approach to tunnelling SRT live streams over QUIC datagrams. 69 | 70 | QUIC {{RFC9000}} is a UDP-based transport protocol providing TLS encryption, stream multiplexing, 71 | and connection migration. It was designed to become a faster alternative to the TCP protocol {{RFC7323}}. 72 | 73 | An Unreliable Datagram Extension to QUIC {{QUIC-DATAGRAM}} adds support for sending and receiving 74 | unreliable datagrams over a QUIC connection, but transfers the responsibility for multiplexing different kinds 75 | of datagrams, or flows of datagrams, to an application protocol. 76 | 77 | SRT {{SRTRFC}} is a UDP-based transport protocol. Essentially, it can operate over any unreliable datagram transport. 78 | SRT provides loss recovery and stream multiplexing mechanisms. 79 | In its live streaming configuration SRT provides an end-to-end latency-aware mechanism for packet loss recovery. 80 | If SRT fails to recover a packet loss within a specified latency, then the packet is dropped to avoid 81 | blocking playback of further packets. 82 | 83 | The Datagram Extension to QUIC could be used as an underlying transport instead of UDP. 84 | This way QUIC would provide TLS-level security, connection migration, and potentially multi-path support. 85 | It would be easier for existing network facilities to process, route, and load balance the unified QUIC traffic. 86 | SRT on its side would provide end-to-end latency tracking and latency-aware loss recovery. 87 | 88 | --- middle 89 | 90 | # Introduction 91 | 92 | ## SRT for Low Latency 93 | 94 | The Secure Reliable Transport (SRT) protocol {{SRTRFC}} is a connection-based transport protocol 95 | that enables the secure, reliable transport of data across 96 | unpredictable networks, such as the Internet. While any data type can be transferred 97 | via SRT, it is ideal for low latency (sub-second) video streaming. 98 | SRT enables high contribution bitrates over long distance connections. 99 | 100 | To achieve low latency streaming, SRT addresses timing issues. The characteristics 101 | of a stream from a source network can be notably changed by transmission over the public 102 | Internet, introducing delays, jitter, and packet loss. This, in turn, leads to 103 | problems with decoding, as audio and video decoders do not receive packets at the 104 | expected pace. The use of large buffers helps, but latency is increased. 105 | SRT includes a mechanism to keep a constant end-to-end latency, thus recreating 106 | the signal characteristics on the receiver side, and reducing the need for buffering. 107 | 108 | SRT employs a listener (server) / caller (client) model. The data flow is bi-directional and 109 | independent of the connection initiation - either the sender or receiver can operate 110 | as listener or caller to initiate a connection. 111 | 112 | The SRT protocol provides an internal multiplexing mechanism, allowing multiple SRT connections 113 | to share the same UDP port, providing access control functionality to identify the caller on the listener side. 114 | This mechanism is exactly what QUIC DATAGRAM describes as a responsibility of the application protocol. 115 | 116 | Supporting forward error correction (FEC) and selective packet retransmission (ARQ), 117 | SRT provides the flexibility to use either of the two mechanisms or both combined, 118 | allowing for use cases ranging from the lowest possible latency to the highest possible 119 | reliability. 120 | 121 | SRT also allows fast file transfers, and adds support for AES encryption. 122 | 123 | ## QUIC for Universal Transport 124 | 125 | The QUIC transport protocol {{RFC9000}} is a connection-based transport protocol built on top of UDP. 126 | It provides a workflow similar to that of TCP, but for modern fast networks. 127 | 128 | TODO: Add more details to the current section. Write about lower connection times, faster delivery, ARQ, CC, etc. 129 | 130 | # Terms and Definitions 131 | 132 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", 133 | "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this 134 | document are to be interpreted as described in BCP 14 {{RFC2119}} {{RFC8174}} 135 | when, and only when, they appear in all capitals, as shown here. 136 | 137 | SRT: 138 | : The Secure Reliable Transport protocol. 139 | 140 | # Use Cases for SRT over QUIC 141 | 142 | SRT itself is very close to QUIC, and provides similar transport mechanisms. 143 | However, the main focus of SRT is on low-latency live contribution and distribution. 144 | SRT is widely used by various broadcasters to enable low-latency streaming of live events. 145 | It is also used in various mobile and IoT devices to get low-latency feedback and live feeds. 146 | 147 | QUIC is supported by CDN companies. Many facilities know how to handle and route QUIC traffic. 148 | QUIC provides certain security advantages (TLS, encrypting headers so that traffic is not distinguishable). 149 | 150 | SRT tunnelled over QUIC allows managing live delivery mechanisms (preserving end-to-end latency and dropping "too late" data). 151 | 152 | # Tunnelling SRT over QUIC 153 | 154 | The QUIC DATAGRAM frame is structured as follows: 155 | 156 | ~~~ 157 | 0 1 2 3 158 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 159 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 160 | | [Length (i)] ... 161 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 162 | | Datagram Data (*) ... 163 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 164 | ~~~ 165 | {: #quic-datagram-frame title="QUIC DATAGRAM Frame Format"} 166 | 167 | Length. 168 | : A variable-length integer specifying the length of the 169 | datagram in bytes. 170 | 171 | Datagram Data. 172 | : The bytes of the datagram to be delivered. 173 | 174 | 175 | The structure of the SRT packet is shown in {{srt-packet}}. For SRT over QUIC tunnelling 176 | the full SRT packet is placed inside the Datagram Data field. 177 | 178 | ~~~ 179 | 0 1 2 3 180 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 181 | +-+-+-+-+-+-+-+-+-+-+-+-+- SRT Header +-+-+-+-+-+-+-+-+-+-+-+-+-+ 182 | |F| (Field meaning depends on the packet type) | 183 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 184 | | (Field meaning depends on the packet type) | 185 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 186 | | Timestamp | 187 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 188 | | Destination Socket ID | 189 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 190 | | | 191 | + Packet Contents | 192 | | (depends on the packet type) + 193 | | | 194 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 195 | ~~~ 196 | {: #srt-packet title="SRT Packet Structure"} 197 | 198 | F: 1 bit. 199 | : Packet Type Flag. A control packet has this flag set to "1". 200 | A data packet has this flag set to "0". 201 | 202 | Timestamp: 32 bits. 203 | : The timestamp of the packet, in microseconds. 204 | The value is relative to the time the SRT connection was established. 205 | Depending on the transmission mode, 206 | the field stores the packet send time or the packet origin time. 207 | 208 | Destination Socket ID: 32 bits. 209 | : A fixed-width field providing the SRT socket ID to which a packet should be dispatched. 210 | The field may have the special value "0" when the packet is a connection request. 211 | 212 | Packet Contents. 213 | : Packet Contents as per packet type. 214 | 215 | ## Overhead 216 | 217 | An SRT data packet has a 16-byte header, which adds to the payload of a QUIC packet. 218 | 219 | For example, let us consider a payload size of 1128 bytes (six 188-byte MPEG-TS packets). 220 | For a 20 Mbps stream, knowing that each data packet gets an additional 16 bytes of overhead, 221 | SRT would provide an overhead of only ~280 kbits/s (or 1.4%). 222 | 223 | Increasing the size of the payload, e.g., to 1316 bytes (seven 188-byte MPEG-TS packets), SRT overhead at 20 Mbps 224 | would be ~240 kbits/s (or 1.2%). 225 | 226 | An SRT receiver also sends a full ACK packet every 10 ms. The size of the ACK packet is 44 bytes. This traffic goes in the opposite direction: from the payload receiver to the payload sender. The payload sender responds to every ACK packet with a corresponding 16-byte ACKACK packet. This gives an additional 1600 bytes per second, which may be considered negligible. 227 | 228 | ## Packet Integrity 229 | 230 | SRT does not provide mechanisms to verify the integrity of packets, 231 | nor to distinguish a packet from a continuous data stream. 232 | SRT assumes that the underlying transport protocol delivers a single and undamaged packet to SRT. 233 | Therefore, the underlying transport MUST provide a mechanism for SRT to send and receive 234 | exactly one packet. 235 | 236 | One SRT packet MUST be sent over exactly one QUIC Datagram frame. 237 | 238 | ## Connection Establishment 239 | 240 | QUIC has a fast and secure crypto handshake based on TLS. 241 | A client connects to a server, and it can verify the server based on its certificate. 242 | A new client connection takes two times the RTT to be established. 243 | If a client connects to a known server, then it can try to establish a faster 0-RTT connection. 244 | 245 | Once a QUIC connection is established, QUIC datagrams can be sent in both directions. 246 | SRT can use this QUIC datagram tunnelling to establish one or many connections on its own. 247 | Each SRT connection would take two times the RTT for handshaking. 248 | 249 | The first handshake round of SRT is intended to get an initial response from the server, 250 | identifying handshake procedure version and getting a cookie from the server (listener) 251 | to mitigate potential DoS attacks. Apart from that, no viable data is exchanged during 252 | this first "induction" handshake phase. 253 | 254 | If an SRT connection is established over an established and verified QUIC connection, 255 | the SRT connection time could be reduced to a single RTT interval if only the "conclusion" handshaking phase 256 | is performed. However SRT does not currently provide this functionality, thus appropriate 257 | modifications are required. 258 | 259 | ## Bidirectional Transmission 260 | 261 | Both QUIC and SRT allow bidirectional transmission of a payload over a single SRT connection. 262 | Even with a payload sent in one direction, some control packets are still sent in the opposite direction over the same connection. 263 | 264 | ## Congestion Control 265 | 266 | QUIC as a transport mechanism can apply congestion control. It is worth noting, however, the specifics of live streaming compared 267 | to file-based transmissions. The payload is not available right away, therefore using regular bandwidth probing mechanisms 268 | to increase or decrease the sending rate would not work. 269 | 270 | The current sending rate is provided by SRT, which in turn receives the payload from a live source and can add some overhead 271 | when retransmission of lost packets is performed. 272 | 273 | However, QUIC can use congestion control to detect congestion and throughput bottlenecks, and prevent sending above a certain limit. 274 | SRT MUST handle such cases by eventually dropping packets, which can no longer be recovered. 275 | 276 | It would make sense for a QUIC connection to provide this throughput limitation value back to SRT. In that case SRT could use the number to 277 | make clever and transport-aware retransmission decisions. 278 | 279 | It is also possible for QUIC to not apply any congestion control, relying on SRT. However, SRT does not reduce the sending rate below the input rate. 280 | If the bitrate of the original stream already exceeds network throughput, SRT would still try to deliver it, maintaining congestion and 281 | eventually breaking the SRT connection. 282 | 283 | It is worth mentioning that in a live streaming scenario it may be beneficial to move congestion control mechanisms outside of the protocol 284 | towards the encoder (payload producer), implementing a network adaptive encoding based on the telemetry provided 285 | by the SRT and QUIC protocols. 286 | 287 | ## Pacing 288 | 289 | SRT uses ACK/ACKACK packet pairs to measure RTT on a link, and to track latency and clock drift. 290 | It also uses packet pair probing to estimate connection bandwidth, although in live configurations 291 | such estimates are informative only. 292 | 293 | Buffering and pacing of SRT packets by QUIC SHOULD be done with the understanding that this would interfere with the corresponding SRT mechanisms. 294 | Alternatively, SRT may implement a pacer on top of QUIC’s congestion control and probing mechanisms to abstract the complexity associated with live streaming use cases. 295 | 296 | ## Connection Mitigation 297 | 298 | QUIC utilizes Connection UUID to distinguish between connections (compared to the IP:Port scheme used by UDP and TCP). 299 | This enables already established connections to be handed over seamlessly across network interfaces without requiring a new handshake/negotiation. 300 | SRT may expand on this to enable network bonded delivery workflows to switch between optimal transports without a latency hit. 301 | 302 | ## Datagram vs H3 Datagram 303 | 304 | As an alternative to using the QUIC Datagram extension, it might be possible to consider the H3 Datagram version in order to be compatible with more existing load balancers. 305 | 306 | # Security Considerations 307 | 308 | TODO 309 | 310 | # IANA Considerations 311 | 312 | TODO 313 | 314 | # Acknowledgments 315 | {:numbered="false"} 316 | 317 | It is worth acknowledging the participation of the following people in the project discussions: Ying Yin (Google), Ian Swett (Google), Victor Vasiliev (Google), Kazuko Oku (Fastly), 318 | Marc Cymontkowski (Haivision), Nikos Kyriopoulos (Haivision), Jake Weissman (Facebook), Jordi Cenzano (Facebook), Alan Frindell (Facebook), Jeongseok Kim (SK Telecom), Joonwoong Kim (SK Telecom). 319 | 320 | Quicly library {{QUICLY}} from Fastly was chosen to provide a QUIC datagram transport layer for SRT over QUIC PoC. We would like to thank Kazuho Oku (Fastly) for his help. 321 | -------------------------------------------------------------------------------- /images/SRT_DecoderUnhappy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 16 | bps 17 | T 18 | i 19 | m 20 | e 21 | 22 | ( 23 | m 24 | s 25 | ) 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | T 187 | i 188 | m 189 | e 190 | 191 | ( 192 | m 193 | s 194 | ) 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | T 353 | i 354 | m 355 | e 356 | 357 | ( 358 | m 359 | s 360 | ) 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 514 | 515 | S 516 | o 517 | u 518 | r 519 | c 520 | e 521 | N 522 | e 523 | t 524 | w 525 | o 526 | r 527 | k 528 | 529 | T 530 | r 531 | a 532 | n 533 | s 534 | m 535 | i 536 | s 537 | s 538 | i 539 | o 540 | n 541 | D 542 | e 543 | s 544 | t 545 | i 546 | n 547 | a 548 | t 549 | i 550 | o 551 | n 552 | C 553 | o 554 | n 555 | s 556 | t 557 | a 558 | n 559 | t 560 | 561 | F 562 | r 563 | a 564 | m 565 | e 566 | 567 | R 568 | a 569 | t 570 | e 571 | ( 572 | e 573 | . 574 | g 575 | . 576 | 577 | 1 578 | 579 | f 580 | r 581 | a 582 | m 583 | e 584 | 585 | e 586 | v 587 | e 588 | r 589 | y 590 | 591 | ~ 592 | 3 593 | 3 594 | 595 | m 596 | s 597 | ) 598 | V 599 | a 600 | r 601 | i 602 | a 603 | b 604 | l 605 | e 606 | 607 | B 608 | i 609 | t 610 | 611 | R 612 | a 613 | t 614 | e 615 | 616 | A 617 | N 618 | D 619 | 620 | V 621 | a 622 | r 623 | i 624 | a 625 | b 626 | l 627 | e 628 | 629 | F 630 | r 631 | a 632 | m 633 | e 634 | 635 | R 636 | a 637 | t 638 | e 639 | V 640 | a 641 | r 642 | i 643 | a 644 | b 645 | l 646 | e 647 | B 648 | i 649 | t 650 | 651 | R 652 | a 653 | t 654 | e 655 | 656 | 657 | 658 | 660 | 661 | 662 | 663 | -------------------------------------------------------------------------------- /images/SRT_DecoderHappy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 565 | 566 | 567 | 568 | 574 | 579 | bps 580 | T 581 | i 582 | m 583 | e 584 | 585 | ( 586 | m 587 | s 588 | ) 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | T 777 | i 778 | m 779 | e 780 | 781 | ( 782 | m 783 | s 784 | ) 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | T 980 | i 981 | m 982 | e 983 | 984 | ( 985 | m 986 | s 987 | ) 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | 1170 | S 1171 | o 1172 | u 1173 | r 1174 | c 1175 | e 1176 | N 1177 | e 1178 | t 1179 | w 1180 | o 1181 | r 1182 | k 1183 | 1184 | T 1185 | r 1186 | a 1187 | n 1188 | s 1189 | m 1190 | i 1191 | s 1192 | s 1193 | i 1194 | o 1195 | n 1196 | D 1197 | e 1198 | s 1199 | t 1200 | i 1201 | n 1202 | a 1203 | t 1204 | i 1205 | o 1206 | n 1207 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | E 1229 | n 1230 | c 1231 | a 1232 | p 1233 | s 1234 | u 1235 | l 1236 | a 1237 | t 1238 | i 1239 | o 1240 | n 1241 | , 1242 | 1243 | i 1244 | n 1245 | c 1246 | l 1247 | u 1248 | d 1249 | i 1250 | n 1251 | g 1252 | 1253 | N 1254 | e 1255 | t 1256 | w 1257 | o 1258 | r 1259 | k 1260 | 1261 | T 1262 | i 1263 | m 1264 | e 1265 | 1266 | S 1267 | t 1268 | a 1269 | m 1270 | p 1271 | s 1272 | F 1273 | e 1274 | e 1275 | d 1276 | b 1277 | a 1278 | c 1279 | k 1280 | 1281 | 1354 | 1355 | 1356 | 1357 | 1358 | 1359 | 1361 | 1362 | 1363 | S 1364 | R 1365 | T 1366 | 1367 | 1414 | 1415 | 1416 | 1463 | 1464 | S 1465 | e 1466 | n 1467 | d 1468 | e 1469 | r 1470 | B 1471 | u 1472 | f 1473 | f 1474 | e 1475 | r 1476 | R 1477 | e 1478 | c 1479 | e 1480 | i 1481 | v 1482 | e 1483 | r 1484 | B 1485 | u 1486 | f 1487 | f 1488 | e 1489 | r 1490 | C 1491 | o 1492 | n 1493 | s 1494 | t 1495 | a 1496 | n 1497 | t 1498 | 1499 | F 1500 | r 1501 | a 1502 | m 1503 | e 1504 | 1505 | R 1506 | a 1507 | t 1508 | e 1509 | ( 1510 | e 1511 | . 1512 | g 1513 | . 1514 | 1515 | 1 1516 | 1517 | f 1518 | r 1519 | a 1520 | m 1521 | e 1522 | 1523 | e 1524 | v 1525 | e 1526 | r 1527 | y 1528 | 1529 | ~ 1530 | 3 1531 | 3 1532 | 1533 | m 1534 | s 1535 | ) 1536 | R 1537 | e 1538 | c 1539 | o 1540 | n 1541 | s 1542 | t 1543 | r 1544 | u 1545 | c 1546 | t 1547 | e 1548 | d 1549 | 1550 | F 1551 | r 1552 | a 1553 | m 1554 | e 1555 | 1556 | R 1557 | a 1558 | t 1559 | e 1560 | ( 1561 | e 1562 | . 1563 | g 1564 | . 1565 | 1566 | 1 1567 | 1568 | f 1569 | r 1570 | a 1571 | m 1572 | e 1573 | 1574 | e 1575 | v 1576 | e 1577 | r 1578 | y 1579 | 1580 | ~ 1581 | 3 1582 | 3 1583 | 1584 | m 1585 | s 1586 | ) 1587 | 1588 | 1589 | --------------------------------------------------------------------------------