1. 소개
[WEBRTC-NV-USE-CASES] 문서는 다음 사용 사례를 설명한다
-
신뢰할 수 없는 JavaScript 클라우드 회의
이 명세는 인코딩된 미디어에 대한 접근을 제공한다. 인코딩된 미디어는 코덱의 인코더 부분의 출력이자 코덱의 디코더 부분의 입력이며, 이를 통해 사용자 에이전트가 암호화를 로컬에서 적용할 수 있게 한다.
이 인터페이스는 RTCPeerConnection의 설정 흐름을 유지하면서 이러한 기능에 접근할 수 있게 하기 위해 [WEBCODECS]에서 영감을 받았다
2. 명세
Streams 정의는 WebIDL을 많이 사용하지 않지만, WebRTC 명세는 사용한다. 이 명세는 WebRTC에 대한 IDL 확장을 보여준다.
이 명세는 파이프라인에 처리를 삽입하기 위해
RTCRtpSender
및 RTCRtpReceiver의
추가 API를 사용한다.
typedef (RTCRtpSFrameEncrypter or RTCRtpScriptTransform );RTCRtpSenderTransform typedef (RTCRtpSFrameDecrypter or RTCRtpScriptTransform ); // New methods for RTCRtpSender and RTCRtpReceiverRTCRtpReceiverTransform partial interface RTCRtpSender {attribute RTCRtpSenderTransform ?transform ; };partial interface RTCRtpReceiver {attribute RTCRtpReceiverTransform ?transform ; };
이 API는 RTCRtpSender의
기본 인코더와 패킷화기의 처리 단계 사이,
그리고/또는 RTCRtpReceiver의
기본 역패킷화기와
디코더 사이의 미디어
파이프라인에서 인코딩된 프레임을 조작할 수
있게 한다.
인코더와 역패킷화기는 각각 빈 큐로 초기화되는 [[processedFramesQueue]] 내부 슬롯과, 인코딩된 프레임 frame이 주어졌을 때 frame을 반환하는 통과 알고리즘으로 초기화되는 [[transformFrameAlgorithm]] 내부 슬롯을 가진다.
인코더가 인코딩된 프레임을 출력할 때마다, 사용자 에이전트는 그 프레임에 대해 인코더.[[transformFrameAlgorithm]]을 호출해야 하며, 원래 프레임 대신 그 결과를 관련 패킷화기에 전달해야 한다.
역패킷화기가 인코딩된 프레임을 출력할 때마다, 사용자 에이전트는 그 프레임에 대해 역패킷화기.[[transformFrameAlgorithm]]을 호출해야 하며, 원래 프레임 대신 그 결과를 관련 디코더에 전달해야 한다.
2.1. 확장 동작
각 RTCRtpTransceiver를
생성할 때 다음 단계를 실행한다:
-
this.
[[useSFrame]]을 undefined로 초기화한다. -
this가 미디어 설명과 관련되어 있으면, 미디어 설명에서 this.
[[useSFrame]]을 초기화한다. this.[[useSFrame]]이 true이면, this에 대해 SFrame RTP 패킷화를 활성화한다. -
그렇지 않으면, 다음 단계를 실행하도록 태스크를 큐에 넣는다:
RTCRtpTransceiver.[[useSFrame]]은
이미 SDP m-section에 연결된 경우에는 동기적으로, 또는 SDP m-section에 연결되기 전에
비동기적으로 설정되어야 한다.
이를 통해 RTCRtpTransceiver.[[useSFrame]]과
해당 SDP가 항상 동기화되도록 보장한다.
이렇게 하면 negotiation-needed 플래그 확인 알고리즘과 같은
negotiation-needed 플래그 관련 처리가 RTCRtpTransceiver.[[useSFrame]]을
고려할 필요가 없다.
각 RTCRtpSender
또는 RTCRtpReceiver를
생성할 때 다음 단계를 실행한다:
-
this.
[[transform]]을 null로 초기화한다. -
this.
[[pipeToController]]를 null로 초기화한다. -
this.
[[frameSource]]를 this가RTCRtpSender인 경우 this의 인코더로, 그렇지 않으면 this의 역패킷화기로 초기화한다.
2.1.1. 스트림 처리
Streams 역압은 데이터 파이프라인에서 가능한 한 이른 시점에 데이터 생성을 일시 중지함으로써 처리량을 최적화하고 처리 및 메모리 소비를 제한할 수 있다. 이는 신뢰성이 필수이고 지연 시간이 그다지 중요하지 않은 맥락에서 유용하다. 반면 WebRTC 미디어 파이프라인은 신뢰성보다 낮은 지연 시간을 선호한다. 예를 들어 여러 위치에서 프레임을 버릴 수 있게 하고 복구 메커니즘을 사용한다. 변환 내부의 버퍼링은 웹 애플리케이션이 크게 적응할 수 있게 하지 않으면서 지연 시간을 추가하게 된다. 사용자 에이전트는 특히 변환의 양 끝을 모두 제어하므로 이러한 적응을 수행할 책임이 있다. 이러한 이유로 WebRTC 인코딩된 변환에서는 스트림 역압이 비활성화된다.
readEncodedData 알고리즘은 RTCRtpScriptTransformer
transformer를 매개변수로, frame을 입력으로 받는다. 이는 다음 단계를 실행하여 정의된다:
-
frame.
[[owner]]를 transformer.[[frameSource]]로 설정한다. -
frame.
[[counter]]를 transformer.[[lastEnqueuedFrameCounter]]로 설정한다. -
frame.
[[owner]]가 역패킷화기이면:-
관련 RTP 패킷이 RTP Header Extension for Absolute Capture Time을 포함하는 경우, frame.
[[captureTime]]을 absolute capture timestamp 필드로 설정하고, 존재하는 경우 frame.[[senderCaptureTimeOffset]]을 capture clock offset 필드로 설정한다. -
그렇지 않고, 관련 RTP 패킷이 RTP Header Extension for Absolute Capture Time을 포함하지 않지만 이전 RTP 패킷이 포함했던 경우, timestamp interpolation에 따라 absolute capture timestamp를 계산한 결과로 frame.
[[captureTime]]을 설정하고, frame.[[senderCaptureTimeOffset]]을 존재했던 가장 최근 값으로 설정한다. -
그렇지 않으면, frame.
[[captureTime]]을 undefined로 설정하고 frame.[[senderCaptureTimeOffset]]을 undefined로 설정한다.
-
-
frame.
[[owner]]가 인코더이면, RTP Header Extension for Absolute Capture Time § absolute-capture-timestamp에 설명된 방법론을 사용하여 frame.[[captureTime]]을 capture timestamp로 설정하고 frame.[[senderCaptureTimeOffset]]을 undefined로 설정한다. -
frame을 transformer.
[[readable]]에 Enqueue한다.
writeEncodedData 알고리즘은 RTCRtpScriptTransformer
transformer를 매개변수로, frame을 입력으로 받는다. 이는 다음 단계를 실행하여 정의된다:
-
frame.
[[owner]]가 transformer.[[frameSource]]와 같지 않으면, 이 단계를 중단하고 undefined로 해결된 promise를 반환한다. 프로세서는 프레임을 생성하거나 스트림 사이에서 프레임을 이동할 수 없다. -
frame.
[[counter]]가 transformer.[[lastReceivedFrameCounter]]보다 작거나 같으면, 이 단계를 중단하고 undefined로 해결된 promise를 반환한다. 프로세서는 프레임의 순서를 바꿀 수 없지만, 지연시키거나 버릴 수는 있다. -
transformer.
[[lastReceivedFrameCounter]]를 frame.[[counter]]로 설정한다. -
data를 frame.
[[data]]라고 한다. -
serializedFrame을 StructuredSerializeWithTransfer(frame, « data »)라고 한다.
-
frameCopy를 StructuredDeserializeWithTransfer(serializedFrame, frame의 관련 렐름)이라고 한다.
-
processedFrame을 frameCopy의 기본 인코딩된 프레임이라고 한다.
-
병렬로, processedFrame을 transformer.
[[frameSource]].[[processedFramesQueue]]에 enqueue한다. -
undefined로 해결된 promise를 반환한다.
송신자 측에서는 readEncodedData의 일부로, 인코더가 생성한 프레임이 enqueued되어야 하며, 그 대상은 인코더의 출력 순서대로
transformer.[[readable]]이다.
writeEncodedData가 변환이
프레임 순서를 바꿀 수 없도록 보장하므로, 인코더의 출력 순서는 패킷화기가 RTP 패킷을 생성하고
RTP 패킷 시퀀스 번호를 할당할 때 따르는 순서이기도 하다.
패킷화기는
변환된 데이터가 여전히 원래 형식을 준수할 것을 기대할 수 있다. 예를 들어 Annex B
시작 코드로 구분된 NAL 유닛의 연속이 이에 해당한다.
수신자 측에서는 readEncodedData의 일부로, 역패킷화기가 생성한 프레임이
동일한 인코더의 출력 순서대로
transformer.[[readable]]에
enqueued되어야 한다.
순서가 지켜지도록 하기 위해 역패킷화기는 일반적으로 RTP
패킷 시퀀스 번호를 사용하여
필요한 경우 RTP 패킷의 순서를 재정렬한 뒤, 프레임을 transformer.[[readable]]에
enqueuing한다.
writeEncodedData가 변환이
프레임 순서를 바꿀 수 없도록 보장하므로, 이는 디코더가 기대하는 순서가
된다.
2.1.2. RTCRtpTransform 공통 처리
RTCRtpTransform은 private 슬롯을 가진다:
-
[[owner]]: 타입은RTCRtpSender또는RTCRtpReceiver이며, null로 초기화된다.
각 RTCRtpTransform은 연결 알고리즘과 연결 해제 알고리즘을 가지며, 둘 다 기본적으로 비어 있다.
2.2. 확장 속성
transform getter 단계는
this.[[transform]]을 반환하는 것이다. setter 단계는 다음과 같다:
-
transform을 setter의 인수라고 한다.
-
transceiver를 this와 관련된
RTCRtpTransceiver라고 한다. -
transform.
[[useSFrame]]이 true이면, 다음 단계를 실행한다:-
transceiver.
[[useSFrame]]이 false이면,InvalidModificationError를 throw하고 이 단계를 중단한다. -
그렇지 않고 transceiver.
[[useSFrame]]이 undefined이면, 다음 단계를 실행한다:-
transceiver.
[[useSFrame]]을 true로 설정한다. -
transceiver에 대해 SFrame RTP 패킷화를 활성화한다.
-
-
-
그렇지 않으면, 다음 단계를 실행한다:
-
transceiver.
[[useSFrame]]이 true이면,InvalidModificationError를 throw하고 이 단계를 중단한다. -
transceiver.
[[useSFrame]]을 false로 설정한다.
-
-
transform이 null이 아니고 transform.
[[owner]]가 null이 아니면,InvalidStateError를 throw하고 이 단계를 중단한다. -
transform.
[[owner]]를 this로 설정한다. -
oldTransform을 this.
[[transform]]이라고 한다. -
oldTransform이 null이 아니면, oldTransform의 연결 해제 알고리즘을 실행한다.
-
this.
[[transform]]을 transform으로 설정한다. -
transform이 null이면, 다음 단계를 실행한다:
-
frameSource를 this.
[[frameSource]]라고 한다. -
병렬로, frameSource.[[transformFrameAlgorithm]]을 통과 알고리즘으로 설정한다.
-
이 알고리즘은 변환이 동적으로 업데이트될 수 있도록 정의된다. 이전 변환에서 새 변환으로 전환이 어느 프레임에서 발생할지에 대한 보장은 없다.
웹 애플리케이션이 RTCRtpSender
생성 시점에
동기적으로 transform을 설정하면(예를 들어 addTrack을 호출할 때), transform은 RTCRtpSender의
인코더가 생성한 첫 번째 프레임을 받게 된다.
마찬가지로, 웹 애플리케이션이 RTCRtpReceiver
생성 시점에
동기적으로 transform을 설정하면(예를 들어 addTrack을 호출할 때 또는 track 이벤트 핸들러에서), transform은
RTCRtpReceiver의
패킷화기가 생성한 첫 번째 완전한 프레임을 받게 된다.
3. SFrame 변환
이 절에서 제시하는 API는 애플리케이션이 [RFC9605]에 정의된 특정 암호 스위트를 사용하여 SFrame 데이터를 처리할 수 있게 한다.
// List of supported cipher suites, as defined in [[RFC9605]] section 4.5 and in https://datatracker.ietf.org/doc/draft-barnes-sframe-iana-256/.enum {SFrameCipherSuite ,"AES_128_CTR_HMAC_SHA256_80" ,"AES_128_CTR_HMAC_SHA256_64" ,"AES_128_CTR_HMAC_SHA256_32" ,"AES_128_GCM_SHA256_128" ,"AES_256_GCM_SHA512_128" ,"AES_256_CTR_HMAC_SHA512_80" ,"AES_256_CTR_HMAC_SHA512_64" };"AES_256_CTR_HMAC_SHA512_32" dictionary {SFrameTransformOptions required SFrameCipherSuite ; };cipherSuite enum {SFrameType ,"per-frame" };"per-packet" dictionary :RTCRtpSFrameEncrypterOptions SFrameTransformOptions {SFrameType = "per-frame"; };type typedef [EnforceRange ]unsigned long long ;SmallCryptoKeyID typedef (SmallCryptoKeyID or bigint );CryptoKeyID interface mixin {SFrameEncrypterManager Promise <undefined >setEncryptionKey (CryptoKey ,key CryptoKeyID ); };keyId interface mixin {SFrameDecrypterManager Promise <undefined >addDecryptionKey (CryptoKey ,key CryptoKeyID );keyId Promise <undefined >removeDecryptionKey (CryptoKeyID );keyId attribute EventHandler ; }; [onerror Exposed =Window ]interface {RTCRtpSFrameEncrypter constructor (RTCRtpSFrameEncrypterOptions ); };options RTCRtpSFrameEncrypter includes SFrameEncrypterManager ; [Exposed =Window ]interface :RTCRtpSFrameDecrypter EventTarget {constructor (SFrameTransformOptions ); };options RTCRtpSFrameDecrypter includes SFrameDecrypterManager ; [Exposed =(Window ,DedicatedWorker )]interface {SFrameEncrypterStream constructor (SFrameTransformOptions ); };options SFrameEncrypterStream includes GenericTransformStream ;SFrameEncrypterStream includes SFrameEncrypterManager ; [Exposed =(Window ,DedicatedWorker )]interface :SFrameDecrypterStream EventTarget {constructor (SFrameTransformOptions ); };options SFrameDecrypterStream includes GenericTransformStream ;SFrameDecrypterStream includes SFrameDecrypterManager ;enum {SFrameTransformErrorEventType ,"authentication" ,"keyID" }; ["syntax" Exposed =(Window ,DedicatedWorker )]interface :SFrameTransformErrorEvent Event {(constructor DOMString ,type SFrameTransformErrorEventInit );eventInitDict readonly attribute SFrameTransformErrorEventType ;errorType readonly attribute CryptoKeyID ?;keyID readonly attribute any ; };frame dictionary :SFrameTransformErrorEventInit EventInit {required SFrameTransformErrorEventType ;errorType required any ;frame CryptoKeyID ?; };keyID
new RTCRtpSFrameEncrypter(options)
생성자 단계는 다음과 같다:
-
options를 메서드의 첫 번째 인자로 둔다.
-
this와 options로 SFrame 초기화 알고리즘을 실행한다.
-
this.
[[role]]을 'encrypt'로 설정한다. -
this.
[[useSFrame]]을 true로 설정한다.
new RTCRtpSFrameDecrypter(options)
생성자 단계는 다음과 같다:
-
options를 메서드의 첫 번째 인자로 둔다.
-
this와 options로 SFrame 초기화 알고리즘을 실행한다.
-
this.
[[role]]을 'decrypt'로 설정한다. -
this.
[[useSFrame]]을 true로 설정한다.
new SFrameEncrypterStream(options)
생성자 단계는 다음과 같다:
-
options를 메서드의 첫 번째 인자로 둔다.
-
this와 options로 SFrame 초기화 알고리즘을 실행한다.
-
this.
[[role]]을 'encrypt'로 설정한다.
new SFrameDecrypterStream(options)
생성자 단계는 다음과 같다:
-
options를 메서드의 첫 번째 인자로 둔다.
-
this와 options로 SFrame 초기화 알고리즘을 실행한다.
-
this.
[[role]]을 'decrypt'로 설정한다.
3.1. 알고리즘
this와 options가 주어진 SFrame 초기화 알고리즘은 다음 단계를 실행한다:
-
transformAlgorithm을 frame을 입력으로 받아 this와 frame으로 SFrame 변환 알고리즘을 실행하는 알고리즘으로 둔다.
-
options["
type"]가 존재하면, 다음 단계를 실행한다:-
options["
type"]가 'per-frame'이면, [RTP-SFRAME-PAYLOAD]에 정의된 프레임별 전송을 사용한다. -
그렇지 않으면, [RTP-SFRAME-PAYLOAD]에 정의된 패킷별 전송을 사용한다.
-
-
this.
[[transform]]을 새TransformStream으로 설정한다. -
설정한다. this.
[[transform]]을 transformAlgorithm이 transformAlgorithm으로 설정되도록 설정한다. -
this.
[[cipherSuite]]를 options["cipherSuite"]로 설정한다. -
this.
[[readable]]을 this.[[transform]].[[readable]]로 설정한다. -
this.
[[writable]]을 this.[[transform]].[[writable]]로 설정한다.
this와 frame이 주어진 SFrame 변환 알고리즘은 다음 단계를 실행한다:
-
role을 this.
[[role]]이라고 한다. -
this.
[[owner]]가RTCRtpSender이면, role을 'encrypt'로 설정한다. -
this.
[[owner]]가RTCRtpReceiver이면, role을 'decrypt'로 설정한다. -
data를 undefined라고 한다.
-
frame이
BufferSource이면, data를 frame으로 설정한다. -
frame이
RTCEncodedAudioFrame이면, data를 frame.data로 설정한다 -
frame이
RTCEncodedVideoFrame이면, data를 frame.data로 설정한다 -
data가 undefined이면, 이 단계를 중단한다.
-
buffer를 data, this.
[[cipherSuite]]및 role을 매개변수로 하여 SFrame 알고리즘을 실행한 결과라고 한다. 이 알고리즘은 [RFC9605]에 정의되어 있으며ArrayBuffer를 반환한다. -
SFrame 알고리즘이 오류와 함께 갑자기 종료되면, 다음 하위 단계를 실행하도록 태스크를 큐에 넣는다:
-
복호화 측의 처리가 data가 SFrame 형식을 따르지 않아서 실패하면, this에서
error라는 이름의 이벤트를 발생시킨다. 이때SFrameTransformErrorEvent인터페이스를 사용하고, 그errorType속성은syntax로 설정하며, 그frame속성은 frame으로 설정한다. -
복호화 측의 처리가 data에서 파싱된 키 식별자를 알 수 없어서 실패하면, this에서
error라는 이름의 이벤트를 발생시킨다. 이때SFrameTransformErrorEvent인터페이스를 사용하고, 그errorType속성은keyID로 설정하며, 그frame속성은 frame으로 설정하고, 그keyID속성은 SFrame 헤더에서 파싱된 keyID 값으로 설정한다. -
복호화 측의 처리가 인증 태그 검증 때문에 실패하면, this에서
error라는 이름의 이벤트를 발생시킨다. 이때SFrameTransformErrorEvent인터페이스를 사용하고, 그errorType속성은authentication으로 설정하며, 그frame속성은 frame으로 설정한다. -
이 단계를 중단한다.
-
-
frame이
BufferSource이면, frame을 buffer로 설정한다. -
frame이
RTCEncodedAudioFrame이면, frame.data를 buffer로 설정한다. -
frame이
RTCEncodedVideoFrame이면, frame.data를 buffer로 설정한다. -
frame을 this.
[[transform]]에 Enqueue한다.
3.2. 메서드
setEncryptionKey(key, keyId)
메서드 단계는 다음과 같다:
-
promise를 새 promise라고 한다.
-
keyId가 0 이상 264-1 이하의 정수로 표현될 수 없는
bigint이면, promise를RangeError예외로 거부하고 이 단계를 중단한다. -
병렬로, 다음 단계를 실행한다:
-
[RFC9605]에 정의된 대로 SFrame 변환 암호화 알고리즘의 키 자료를 key와 keyId로 설정한다.
-
키 자료 설정이 실패하면, promise를
InvalidModificationError예외로 거부하도록 태스크를 큐에 넣고 이 단계를 중단한다. -
promise를 undefined로 해결하도록 태스크를 큐에 넣는다.
-
-
promise를 반환한다.
addDecryptionKey(key, keyId)
메서드 단계는 다음과 같다:
-
promise를 새 promise라고 한다.
-
keyId가 0 이상 264-1 이하의 정수로 표현될 수 없는
bigint이면, promise를RangeError예외로 거부하고 이 단계를 중단한다. -
병렬로, 다음 단계를 실행한다:
-
keyStore를 [RFC9605]에 정의된 SFrame 변환 알고리즘에 사용되는 키 저장소라고 한다.
-
keyStore[keyId]를 key로 설정한다.
-
키 자료 설정이 실패하면, promise를
InvalidModificationError예외로 거부하도록 태스크를 큐에 넣고 이 단계를 중단한다. -
promise를 undefined로 해결하도록 태스크를 큐에 넣는다.
-
-
promise를 반환한다.
removeDecryptionKey(keyId)
메서드 단계는 다음과 같다:
-
promise를 새 promise라고 한다.
-
keyId가 0 이상 264-1 이하의 정수로 표현될 수 없는
bigint이면, promise를RangeError예외로 거부하고 이 단계를 중단한다. -
병렬로, 다음 단계를 실행한다:
-
keyStore를 [RFC9605]에 정의된 SFrame 변환 알고리즘에 사용되는 키 저장소라고 한다.
-
keyStore[keyId]를 제거한다.
-
promise를 undefined로 해결하도록 태스크를 큐에 넣는다.
-
-
promise를 반환한다.
4. 스크립트 변환
이 절에서 캡처 시스템은 미디어가 공급되는 시스템을 의미하고, 송신자 시스템은 RTCEncodedFrameMetadata
데이터가 채워지는 수신자 시스템으로 RTP 및 RTCP 패킷을 보내는 시스템을 의미한다.
4.1. RTCEncodedFrameMetadata 딕셔너리
dictionary RTCEncodedFrameMetadata {unsigned long synchronizationSource ;octet payloadType ;sequence <unsigned long >contributingSources ;unsigned long rtpTimestamp ;DOMHighResTimeStamp receiveTime ;DOMHighResTimeStamp captureTime ;DOMHighResTimeStamp senderCaptureTimeOffset ;DOMString mimeType ; };
4.1.1. 멤버
-
synchronizationSource, 타입은 unsigned longunsigned long -
동기화 소스(ssrc) 식별자는 [RFC3550]에 따른 unsigned 정수 값이며, 인코딩된 프레임 객체가 설명하는 RTP 패킷 스트림을 식별하는 데 사용된다.
-
payloadType, 타입은 octetoctet -
페이로드 타입은 [RFC3550]에 따른 0에서 127까지 범위의 unsigned 정수 값이며, RTP 페이로드의 형식을 설명하는 데 사용된다.
-
contributingSources, 타입은sequence<unsigned long>sequence<unsigned long> -
[RFC3550]에 정의된 기여 소스 목록(csrc 목록).
-
rtpTimestamp, 타입은 unsigned longunsigned long -
RTP 타임스탬프 식별자는 [RFC3550]에 따른 unsigned 정수 값이며, RTP 데이터 패킷의 첫 번째 옥텟의 샘플링 시점을 반영한다.
-
receiveTime, 타입은 DOMHighResTimeStampDOMHighResTimeStamp -
RTCRtpReceiver에서 오는 프레임의 경우, 이 미디어 프레임을 생성하는 데 사용된 마지막 수신 패킷의 타임스탬프를 나타낸다. 이 타임스탬프는
Performance.timeOrigin을 기준으로 한다. -
captureTime, 타입은 DOMHighResTimeStampDOMHighResTimeStamp -
캡처 시스템의 시계에서 이 프레임의 캡처 시간. 이 멤버를 채울 때 사용자 에이전트는 프레임의
[[captureTime]]슬롯 값을 반환해야 하며, 그 값은Performance.timeOrigin을 기준으로 하도록 이동되어야 한다. -
senderCaptureTimeOffset, 타입은 DOMHighResTimeStampDOMHighResTimeStamp -
senderCaptureTimeOffset은 동일한 프레임에 대해, 송신자 시스템이 자신의 NTP 시계와captureTime이 유래한 캡처 시스템의 NTP 시계 사이의 오프셋을 추정한 값이다. 이 멤버를 채울 때 사용자 에이전트는 프레임의[[senderCaptureTimeOffset]]슬롯 값을 반환해야 한다. -
mimeType, 타입은 DOMStringDOMString -
IANA 미디어 타입 레지스트리 [IANA-MEDIA-TYPES]에 정의된 코덱 MIME 미디어 타입/서브타입. 예: audio/opus 또는 video/VP8.
4.2.
RTCEncodedVideoFrameMetadata
딕셔너리
dictionary RTCEncodedVideoFrameMetadata :RTCEncodedFrameMetadata {unsigned long long frameId ;sequence <unsigned long long >dependencies ;unsigned short ;width unsigned short ;height unsigned long ;spatialIndex unsigned long ;temporalIndex long long timestamp ; // microseconds };
4.2.1. 멤버
-
frameId, 타입은 unsigned long longunsigned long long -
인코딩된 프레임의 식별자로, 디코드 순서에서 단조 증가한다. 하위 16비트는 존재하는 경우 [AV1-RTP-SPEC] 부록 A에 정의된 AV1 Dependency Descriptor Header Extension의 frame_number와 일치한다. Dependency Descriptor Header Extension이 존재하는 경우에만 수신된 프레임에 존재한다.
-
dependencies, 타입은sequence<unsigned long long>sequence<unsigned long long> -
이 프레임이 참조하는 프레임들의 frameId 목록. [AV1-RTP-SPEC] 부록 A에 정의된 AV1 Dependency Descriptor Header Extension이 존재하는 경우에만 수신된 프레임에 존재한다.
-
timestamp, 타입은 long longlong long -
원시 프레임의 미디어 표시 타임스탬프(PTS)이며, 단위는 마이크로초이고 이 프레임에 대응하는 원시 프레임의
timestamp와 일치한다.
4.3.
RTCEncodedVideoFrame 인터페이스
dictionary {RTCEncodedVideoFrameOptions RTCEncodedVideoFrameMetadata ; }; // New interfaces to define RTC specific encoded video and audio frames used by RTCRtpScriptTransform. [metadata Exposed =(Window ,DedicatedWorker ),Serializable ]interface RTCEncodedVideoFrame {(constructor RTCEncodedVideoFrame ,originalFrame optional RTCEncodedVideoFrameOptions = {});options readonly attribute EncodedVideoChunkType type ;attribute ArrayBuffer data ;RTCEncodedVideoFrameMetadata getMetadata (); };
4.3.1. 생성자
-
constructor() -
주어진 originalFrame 및 options.
[metadata]에서 새로운RTCEncodedVideoFrame을 생성한다. 새로 생성된 프레임은 originalFrame과 완전히 독립적이며, 그[[data]]는 originalFrame.[[data]]의 깊은 복사본이다. 새 프레임의[[metadata]]는 originalFrame.[[metadata]]의 깊은 복사본이며, 필드는 options.[metadata]에 존재하는 필드의 깊은 복사본으로 대체된다.호출될 때 다음 단계를 실행한다:
-
this.
[[type]]을 originalFrame.[[type]]으로 설정한다. -
this.
[[data]]를 [CloneArrayBuffer](originalFrame.[[data]], 0, originalFrame.[[data]].[[ArrayBufferByteLength]])의 결과라고 한다. -
[[metadata]]가 이 새로 생성된 프레임과 관련된 메타데이터를 나타낸다고 한다.-
originalFrame.
[[getMetadata()]]의 각 {[[key]],[[value]]} 쌍에 대해,[[metadata]].[[key]]를[[value]]의 깊은 복사본으로 설정한다. -
options.
[metadata]의 각 {[[key]],[[value]]} 쌍에 대해,[[metadata]].[[key]]를[[value]]의 깊은 복사본으로 설정한다.
-
-
4.3.2. 멤버
-
type, 타입은 EncodedVideoChunkType, readonlyEncodedVideoChunkType -
type 속성을 통해 애플리케이션은 프레임이 키 프레임인지 델타 프레임인지 확인할 수 있다. 가져올 때는 this.
[[type]]을 반환해야 한다. -
data, 타입은 ArrayBufferArrayBuffer -
인코딩된 프레임 데이터. 데이터의 형식은 프레임을 인코딩/디코딩하는 데 사용되는 비디오 코덱에 따라 달라지며, 이는
mimeType을 보면 확인할 수 있다. SVC의 경우, 각 공간 계층은 별도로 변환된다. 가져올 때는 this.[[data]]를 반환해야 한다. 설정할 때는 this.[[data]]를 새 값으로 설정해야 한다.패킷화기가 특정 요소, 예를 들어 AV1 temporal delimiter OBU를 버릴 수 있으므로, 수신 측 변환의 입력은 송신 측 변환의 출력과 다를 수 있다.
다음 표는 여러 예를 제공한다:
mimeType 데이터 형식 video/VP8 데이터는 section 9.1 of [RFC6386]에 정의된 "uncompressed data chunk"로 시작하고, 그 뒤에 나머지 프레임 데이터가 이어진다. VP8 payload descriptor에는 접근할 수 없다. video/VP9 데이터는 [VP9]의 Section 6에 설명된 프레임이다. VP9 payload descriptor에는 접근할 수 없다. video/H264 데이터는 [ITU-T-REC-H.264] Annex B에 정의된 Annex B 형식의 NAL 유닛 연속이다. video/AV1 데이터는 [AV1]의 Section 5에 설명된 low-overhead bitstream format을 준수하는 OBU의 연속이다. AV1 aggregation header에는 접근할 수 없다.
4.3.3. 메서드
-
getMetadata() -
프레임과 관련된 메타데이터를 반환한다.
4.3.4. 직렬화
RTCEncodedVideoFrame
객체는 직렬화 가능 객체이다.
value, serialized, forStorage가 주어진
이 객체들의 직렬화 단계는 다음과 같다:
-
forStorage가 true이면,
DataCloneError를 throw한다. -
serialized.
[[type]]을 value.[[type]]의 값으로 설정한다. -
serialized.
[[metadata]]를 value 메타데이터의 내부 표현으로 설정한다. -
serialized.
[[data]]를 value.[[data]]의 하위 직렬화로 설정한다.
serialized, value 및 realm이 주어진 이 객체들의 역직렬화 단계는 다음과 같다:
-
value.
[[type]]을 serialized.[[type]]으로 설정한다. -
value의 메타데이터를 serialized.
[[metadata]]의 플랫폼 객체 표현으로 설정한다. -
value.
[[data]]를 serialized.[[data]]의 하위 역직렬화로 설정한다.
직렬화된 RTCEncodedVideoFrame의 내부 형식은 관찰할 수 없다;
이는 주로 writeEncodedData 알고리즘 및
structuredClone()
작업에서 프레임 복제와 함께 사용할 수 있도록 정의된다.
따라서 구현은 가장 잘 작동하는 어떤 방법이든 자유롭게 선택할 수 있다.
4.4.
RTCEncodedAudioFrameMetadata
딕셔너리
dictionary RTCEncodedAudioFrameMetadata :RTCEncodedFrameMetadata {short sequenceNumber ;double audioLevel ; };
4.4.1. 멤버
-
sequenceNumber, 타입은 shortshort -
[RFC3550]에 정의된 RTP 시퀀스 번호. 들어오는 오디오 프레임에만 존재한다.
두 시퀀스 번호를 비교하려면 [RFC1982]에 설명된 일련 번호 산술이 필요하다.
-
audioLevel, 타입은 doubledouble -
이 프레임의 오디오 레벨. 값은 0..1(선형) 사이이며, 1.0은 0 dBov를, 0은 무음을, 0.5는 0 dBov에서 음압 레벨이 대략 6 dBSPL 변화한 것을 나타낸다.
프레임이 원격에서 공급된 트랙에서 온 경우, 이 값은 [RFC6464]에 정의된 레벨 값에서 변환되어야 한다. 프레임의 수신 패킷에 [RFC6464] 헤더 확장이 존재하지 않으면, 이 값은 없어야 한다. 이 RFC는 오디오 레벨을 0에서 127까지의 정수 값으로 정의하며, 시스템이 인코딩할 수 있는 가장 큰 신호를 기준으로 한 음의 데시벨 단위의 오디오 레벨을 나타낸다. 따라서 0은 시스템이 인코딩할 수 있는 가장 큰 신호를 나타내고, 127은 무음을 나타낸다. 이 값을 선형 0..1 범위로 변환하려면, 값 127은 0으로 변환되고, 그 밖의 모든 값은 다음 식을 사용하여 변환된다:
10^(-rfc_level/20).프레임이 로컬에서 공급된 트랙에서 온 경우, 레벨은 소스에서 직접 가져와야 하며, 협상된 경우 [RFC6464] 헤더 확장 값을 생성하기 위한 입력으로 사용되어야 한다.
4.5.
RTCEncodedAudioFrame 인터페이스
dictionary {RTCEncodedAudioFrameOptions RTCEncodedAudioFrameMetadata ; }; [metadata Exposed =(Window ,DedicatedWorker ),Serializable ]interface RTCEncodedAudioFrame {(constructor RTCEncodedAudioFrame ,originalFrame optional RTCEncodedAudioFrameOptions = {});options attribute ArrayBuffer data ;RTCEncodedAudioFrameMetadata getMetadata (); };
4.5.1. 생성자
-
constructor() -
주어진 originalFrame 및 options.
[metadata]에서 새로운RTCEncodedAudioFrame을 생성한다. 새로 생성된 프레임은 originalFrame과 완전히 독립적이며, 그[[data]]는 originalFrame.[[data]]의 깊은 복사본이다. 새 프레임의[[metadata]]는 originalFrame.[[metadata]]의 깊은 복사본이며, 필드는 options.[metadata]에 존재하는 필드의 깊은 복사본으로 대체된다.호출될 때 다음 단계를 실행한다:
-
this.
[[data]]를 [CloneArrayBuffer](originalFrame.[[data]], 0, originalFrame.[[data]].[[ArrayBufferByteLength]])의 결과라고 한다. -
[[metadata]]가 이 새로 생성된 프레임과 관련된 메타데이터를 나타낸다고 한다.-
originalFrame.
[[getMetadata()]]의 각 {[[key]],[[value]]} 쌍에 대해,[[metadata]].[[key]]를[[value]]의 깊은 복사본으로 설정한다. -
options.
[metadata]의 각 {[[key]],[[value]]} 쌍에 대해,[[metadata]].[[key]]를[[value]]의 깊은 복사본으로 설정한다.
-
-
4.5.2. 멤버
-
data, 타입은 ArrayBufferArrayBuffer -
인코딩된 프레임 데이터. 데이터의 형식은 프레임을 인코딩/디코딩하는 데 사용되는 오디오 코덱에 따라 달라지며, 이는
mimeType을 보면 확인할 수 있다. 가져올 때는 this.[[data]]를 반환해야 한다. 설정할 때는 this.[[data]]를 새 값으로 설정해야 한다. 다음 표는 여러 예를 제공한다:mimeType 데이터 형식 audio/opus 데이터는 section 3 of [RFC6716]에 설명된 Opus 패킷이다. audio/PCMU 데이터는 임의 길이의 바이트 시퀀스이며, 각 바이트는 [ITU-G.711]의 표 2a 및 2b에 정의된 u-law 인코딩 PCM 샘플이다. audio/PCMA 데이터는 임의 길이의 바이트 시퀀스이며, 각 바이트는 [ITU-G.711]의 표 1a 및 1b에 정의된 A-law 인코딩 PCM 샘플이다. audio/G722 데이터는 [ITU-G.722]에 설명된 G.722 오디오이다. audio/RED 데이터는 section 3 of [RFC2198]에 설명된 중복 오디오 데이터이다. audio/CN 데이터는 section 3 of [RFC3389]에 설명된 Comfort Noise이다.
4.5.3. 메서드
-
getMetadata() -
프레임과 관련된 메타데이터를 반환한다.
4.5.4. 직렬화
RTCEncodedAudioFrame
객체는 직렬화 가능 객체이다.
value,
serialized 및 forStorage가 주어진
이 객체들의 직렬화 단계는 다음과 같다:
-
forStorage가 true이면,
DataCloneError를 throw한다. -
serialized.
[[metadata]]를 value 메타데이터의 내부 표현으로 설정한다. -
serialized.
[[data]]를 value.[[data]]의 하위 직렬화로 설정한다.
serialized, value 및 realm이 주어진 이 객체들의 역직렬화 단계는 다음과 같다:
-
value의 메타데이터를 serialized.
[[metadata]]의 플랫폼 객체 표현으로 설정한다 -
value.
[[data]]를 serialized.[[data]]의 하위 역직렬화로 설정한다.
5.
RTCRtpScriptTransform 인터페이스
enum {RTCRtpScriptTransformType };"sframe" dictionary {WorkerAndParameters required Worker ;worker RTCRtpScriptTransformType ; };type typedef (Worker or WorkerAndParameters ); [WorkerOrWorkerAndParameters Exposed =Window ]interface RTCRtpScriptTransform {constructor (WorkerOrWorkerAndParameters ,workerOrWorkerAndParameters optional any ,options optional sequence <object >); };transfer
5.1. 내부 슬롯
RTCRtpScriptTransform
객체는 다음 내부 슬롯을 가진다:
| 내부 슬롯 | 설명(비규범적) |
|---|---|
[[worker]]
| 생성자에 제공된 Worker.
|
5.2. 생성자
new RTCRtpScriptTransform(workerOrWorkerAndParameters, options, transfer)
생성자 단계는 다음과 같다:
-
worker를 undefined라고 한다.
-
useSFrame을 undefined라고 한다.
-
workerOrWorkerAndParameters가
Worker객체이면, worker를 workerOrWorkerAndParameters로 설정하고 useSFrame을 false로 설정한다. -
그렇지 않으면, 다음 하위 단계를 실행한다:
-
worker를 workerOrWorkerAndParameters["worker"]로 설정한다.
-
workerOrWorkerAndParameters["type"]이 "sframe"이면 useSFrame을 true로, 그렇지 않으면 false로 설정한다.
-
-
this의 내부 슬롯을 다음과 같이 초기화한다:
[[worker]]-
worker
-
this.
[[useSFrame]]을 useSFrame으로 초기화한다. -
serializedOptions를 StructuredSerializeWithTransfer(options, transfer)의 결과라고 한다.
-
worker의
WorkerGlobalScope와 함께 DOM 조작 태스크 소스에서 전역 태스크를 큐에 넣어 다음 단계를 실행한다:-
transformerOptions를 StructuredDeserializeWithTransfer(serializedOptions, 현재 Realm)의 결과라고 한다.
-
transformer를 transformerOptions로
RTCRtpScriptTransformer를 생성한 결과라고 한다. -
transformer의 관련 전역 객체에서,
transformer가 transformer로 설정된RTCTransformEvent를 사용하여,rtctransform이라는 이름의 이벤트를 발생시킨다.
-
// FIXME: 오류 처리를 설명할 것(RTCRtpScriptTransform 생성 시점에 worker closing flag가 true인 경우, 그리고 transform이 데이터를 처리하는 동안 worker가 종료되는 경우).
5.3. 알고리즘
각 RTCRtpScriptTransform은
rtcObject가 주어졌을 때 다음 연결 알고리즘을 가진다:
-
transform을 연결 알고리즘을 소유하는
RTCRtpScriptTransform객체라고 한다. -
frameSource를 rtcObject의
[[frameSource]]라고 한다. -
workerGlobalScope를 transform.
[[worker]]의WorkerGlobalScope라고 한다. -
workerGlobalScope와 함께 DOM 조작 태스크 소스에서 전역 태스크를 큐에 넣어 다음 단계를 실행한다:
-
transformer를 transform과 관련된
RTCRtpScriptTransformer객체라고 한다. -
transformer.
[[frameSource]]를 frameSource로 설정한다.
-
-
병렬로, frameSource.[[transformFrameAlgorithm]]을 다음 단계로 설정한다. 이 단계는 인코딩된 프레임 frame을 입력으로 받는다:
-
workerGlobalScope와 함께 DOM 조작 태스크 소스에서 전역 태스크를 큐에 넣어 다음 단계를 실행한다:
-
transformer를 transform과 관련된
RTCRtpScriptTransformer객체라고 한다. -
jsFrame을 frame이 비디오 프레임이면 frame에서 만든 새로운
RTCEncodedVideoFrame이라고 하고, 그렇지 않으면 frame에서 만든 새로운RTCEncodedAudioFrame이라고 한다. -
transformer와 jsFrame으로 readEncodedData를 호출한다.
-
-
frameSource.[[processedFramesQueue]]가 비어 있지 않게 될 때까지 기다린다.
-
frameSource.[[processedFramesQueue]]에서 dequeueing한 결과를 반환한다.
-
각 RTCRtpScriptTransform은
다음 연결 해제 알고리즘을 가진다:
-
transform을 연결 해제 알고리즘을 소유하는
RTCRtpScriptTransform객체라고 한다. -
transform.
[[worker]]의WorkerGlobalScope와 함께 DOM 조작 태스크 소스에서 전역 태스크를 큐에 넣어 다음 단계를 실행한다:-
transformer를 transform과 관련된
RTCRtpScriptTransformer객체라고 한다. -
transformer.
[[readable]]을 cancel한다. -
transformer.
[[writable]]을 abort한다.
-
6.
RTCRtpScriptTransformer 인터페이스
[Exposed =DedicatedWorker ]interface RTCRtpScriptTransformer :EventTarget { // Attributes and methods related to the transformer sourcereadonly attribute ReadableStream readable ;Promise <undefined >generateKeyFrame (optional DOMString );rid Promise <undefined >sendKeyFrameRequest (); // Attributes and methods related to the transformer sinkreadonly attribute WritableStream writable ;attribute EventHandler onkeyframerequest ; // Attributes for configuring the Javascript codereadonly attribute any options ; };
6.1. 내부 슬롯
RTCRtpScriptTransformer
객체는 다음 내부 슬롯을 가진다:
| 내부 슬롯 | 설명(비규범적) |
|---|---|
[[frameSource]]
| 인코더, 역패킷화기, 또는 undefined. |
[[options]]
| 선택적 Object,
또는 null.
|
[[readable]]
| ReadableStream.
|
[[writable]]
| WritableStream.
|
[[lastReceivedFrameCounter]]
| 수신된 프레임의 수. |
[[lastEnqueuedFrameCounter]]
| 큐에 넣은 프레임의 수. |
RTCRtpScriptTransformer를
생성하려면
다음 단계를 수행한다:
-
transformer를 다음을 가진
RTCRtpScriptTransformer새 객체라고 한다: -
transformer.
[[readable]]을 설정한다.this가 매개변수로 주어진 readEncodedData 알고리즘은 인코딩된 프레임을 여기에 제공한다.
-
writeAlgorithm을 frame이 주어졌을 때 this를 매개변수로, frame을 입력으로 하여 writeEncodedData를 실행하는 동작이라고 한다.
-
transformer.
[[writable]]을 그 writeAlgorithm이 writeAlgorithm로 설정되고, 그 highWaterMark가Infinity로 설정되도록 설정한다.highWaterMark는 역압을 명시적으로 비활성화하기 위해 Infinity로 설정된다.
-
transformer를 반환한다.
6.2. 메서드
generateKeyFrame(rid)
메서드 단계는 다음과 같다:
-
promise를 새 promise라고 한다.
-
promise, this.
[[frameSource]]및 rid로 키 프레임 생성 알고리즘을 실행한다. -
promise를 반환한다.
sendKeyFrameRequest() 메서드
단계는 다음과 같다:
-
promise를 새 promise라고 한다.
-
promise 및 this.
[[frameSource]]로 키 프레임 요청 전송 알고리즘을 실행한다. -
promise를 반환한다.
6.3. 속성
options getter 단계는 다음과 같다:
-
this.
[[options]]을 반환한다.
readable getter 단계는 다음과 같다:
-
this.
[[readable]]을 반환한다.
writable getter 단계는 다음과 같다:
-
this.
[[writable]]을 반환한다.
onbandwidthestimate
EventHandler는 bandwidthestimate 타입을 가진다.
onkeyframerequest
EventHandler는 keyframerequest 타입을 가진다.
6.4. 이벤트
[Exposed =DedicatedWorker ]interface :RTCTransformEvent Event {readonly attribute RTCRtpScriptTransformer ; };transformer partial interface DedicatedWorkerGlobalScope {attribute EventHandler ; }; [onrtctransform Exposed =DedicatedWorker ]interface :KeyFrameRequestEvent Event {(constructor DOMString ,type optional DOMString );rid readonly attribute DOMString ?; };rid
다음 이벤트는 RTCRtpScriptTransformer에서
발생한다:
-
KeyFrameRequestEvent타입의 keyframerequest - sink가 키 프레임이 요청되었다고 판단할 때 발생한다.
KeyFrameRequestEvent
타입의 이벤트를 생성하는 단계는 다음과 같다:
관련 RTCRtpScriptTransformer
transformer의 인코더가
예를 들어 들어오는 RTCP Picture Loss Indication(PLI)
또는 Full Intra Refresh(FIR)에서 키프레임 요청을 받으면,
다음 단계를 수행하도록 태스크를 큐에 넣는다:
-
rid를 적절한 계층의 RID로 설정하거나, 요청이 특정 계층에 대한 것이 아니면 undefined로 설정한다.
-
transformer에서
keyframerequest라는 이름의 이벤트를 발생시킨다. 이때KeyFrameRequestEvent를 사용하고, 그cancelable속성은 "true"로 초기화하며,rid는 rid로 설정한다. -
이벤트의 canceled flag가 true이면, 이 단계를 중단한다.
-
새 promise, transformer.
[[frameSource]]및 rid로 키 프레임 생성 알고리즘을 실행한다.
6.5. KeyFrame 알고리즘
promise, frameSource 및 rid가 주어진 키 프레임 생성 알고리즘은 다음 단계를 실행하여 정의된다:
-
frameSource가 인코더가 아니면, promise를
InvalidStateError로 거부하고, 이 단계를 중단한다. -
encoder를 frameSource라고 한다.
-
encoder가 비디오
RTCRtpSender에 속하지 않으면, promise를InvalidStateError로 거부하고, 이 단계를 중단한다. -
rid가 정의되어 있지만 [RFC8851]의 Section 10에 지정된 문법 요구 사항을 준수하지 않으면, promise를
TypeError로 거부하고 이 단계를 중단한다. -
병렬로, 다음 단계를 실행한다:
-
layers를 이 encoder에 대한 계층의 새 목록이라고 하며, 협상된 encoding 인덱스순으로 정렬한다.
-
layers에서
active가 아니거나, 해당RTCRtpSender트랙이 종료된 모든 계층을 제거한다. -
rid가 undefined가 아니면, layers에서 RID가 rid가 아닌 모든 계층을 제거한다.
참고: rid가 전달되지 않으면, 모든 활성 계층에 대해 키프레임이 생성된다.
-
layers가 이제 비어 있으면, promise를
NotFoundError로 거부하도록 태스크를 큐에 넣고 이 단계를 중단한다. -
encoder.
[[pendingKeyFrameTasks]]에 있는 어떤 태스크의[[layers]]에서든 이미 발견된 모든 계층을 layers에서 제거한다. -
task.
[[layers]]가 layers로 설정되고 task.[[promise]]가 promise로 설정된, task라는 pending key frame task를 생성한다. -
encoder.
[[pendingKeyFrameTasks]]가 undefined이면, encoder.[[pendingKeyFrameTasks]]를 빈 set으로 초기화한다. -
task를 encoder.
[[pendingKeyFrameTasks]]에 추가한다. -
layers의 각 layer(있는 경우)에 대해, 그 layer에 다음으로 제공되는 비디오 프레임에 대한 키 프레임을 생성하도록 encoder에 지시한다.
-
RTCRtpScriptTransformer
transformer와 관련된 모든 인코더에
대해, 사용자 에이전트는 어떤 frame이든 transformer.[[readable]]에
enqueued되기 직전에 다음 단계를 실행해야 한다:
-
encoder를 transformer.
[[frameSource]]라고 한다. -
encoder.
[[pendingKeyFrameTasks]]가 undefined이면, 이 단계를 중단한다. -
frame이 비디오
"key"프레임이 아니면, 이 단계를 중단한다. -
encoder.
[[pendingKeyFrameTasks]]의 각 task에 대해 다음 단계를 실행한다:
RTCRtpScriptTransformer의
readable에 해당 키 프레임을 큐에 넣기 직전에 promise를 해결함으로써,
promise의 resolution callback은 항상 해당 키 프레임이 노출되기 바로 전에 실행된다.
promise가 여러 계층과 관련된 경우, 모든 계층에 대해 키 프레임이 큐에 들어간 뒤에
한 번 해결된다.
promise 및 frameSource가 주어진 키 프레임 요청 전송 알고리즘은 다음 단계를 실행하여 정의된다:
-
frameSource가 역패킷화기가 아니면, promise를
InvalidStateError로 거부하고, 이 단계를 중단한다. -
depacketizer를 frameSource라고 한다.
-
depacketizer가 비디오
RTCRtpReceiver에 속하지 않으면, promise를InvalidStateError로 거부하고, 이 단계를 중단한다. -
병렬로, 다음 단계를 실행한다:
-
depacketizer의 receiver가 Full Intra Request(FIR)를 보내는 것이 적절하지 않다고 판단되면, promise를 undefined로 해결하고 이 단계를 중단한다. [RFC5104] 4.3.1절은 Full Intra Request를 보내는 것이 어떻게 그리고 언제 적절한지에 대한 지침을 제공한다.
-
[RFC5104] 4.3.1절에 정의된 대로 Full Intra Request(FIR) 패킷을 생성하고 depacketizer의 receiver를 통해 보낸다.
-
promise를 undefined로 해결하도록 태스크를 큐에 넣는다.
-
7. 개인정보 보호 및 보안 고려 사항
이 API는 Javascript가 미디어 스트림의 콘텐츠에 접근할 수 있게 한다. 이는 Canvas 및 WebAudio 같은 다른 소스에서도 가능하다.
그러나 [WEBRTC-IDENTITY]에 지정된 것처럼 격리된 스트림이나 다른 출처로 오염된 스트림은 이 API로 접근할 수 없다. 그렇게 하면 격리 규칙을 깨뜨리기 때문이다.
이 API는 그 밖에는 사용할 수 없는 일부 타이밍 정보 측면에 대한 접근을 허용하므로, 일부 fingerprinting surface를 허용한다.
이 API는 인코딩된 미디어에 대한 접근을 제공한다. 이는 JS 애플리케이션이 packetizer나 decoder 같은 내부 구성 요소에 전달되는 내용을 완전히 제어하게 됨을 의미한다. 이로 인해 이러한 구성 요소 내부에서 데이터가 처리되는 방식에 대한 감사에 추가적인 주의가 필요할 수 있다.
예를 들어 packetizer는 신뢰할 수 있는 인코더에서 온 데이터만 볼 것으로 기대할 수 있으며, 신뢰할 수 없는 소스에서 온 데이터를 받는 경우에 대해 감사되지 않았을 수 있다.
8. 예제
explainer 문서를 참고한다.