WebCodecs

W3C 작업 초안,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2025/WD-webcodecs-20250708/
최신 공개 버전:
https://www.w3.org/TR/webcodecs/
편집자 초안:
https://w3c.github.io/webcodecs/
이전 버전:
히스토리:
https://www.w3.org/standards/history/webcodecs/
피드백:
GitHub
명세 내 인라인
편집자:
Paul Adenot (Mozilla)
Eugene Zemtsov (Google LLC)
이전 편집자:
Bernard Aboba (Microsoft Corporation)
Chris Cunningham (Google Inc.)
참여:
Git 저장소.
이슈 등록.
버전 히스토리:
https://github.com/w3c/webcodecs/commits

요약

이 명세는 오디오, 비디오 및 이미지의 인코딩과 디코딩을 위한 코덱 인터페이스를 정의합니다.

이 명세는 특정 코덱이나 인코딩/디코딩 방법을 지정하거나 요구하지 않습니다. 이 명세의 목적은 기존 코덱 기술의 구현체에 대한 JavaScript 인터페이스를 제공하는 것입니다. 구현자는 어떤 조합의 코덱도 지원하거나 전혀 지원하지 않아도 됩니다.

이 문서의 상태

이 섹션은 문서가 발행된 시점의 상태를 설명합니다. 현재 W3C 발행물과 이 기술 보고서의 최신 개정본 목록은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.

이 명세에 대한 피드백과 의견을 환영합니다. GitHub 이슈가 이 명세에 대한 논의에 선호됩니다. 또는 Media Working Group의 메일링 리스트 public-media-wg@w3.org (아카이브)로 의견을 보낼 수 있습니다. 이 초안은 워킹 그룹에서 논의가 남아 있는 일부 보류 중인 이슈를 강조합니다. 이러한 이슈의 결과에 대한 결정은 아직 내려지지 않았으며, 유효성 여부도 확정되지 않았습니다.

이 문서는 Media Working Group에서 권고안 트랙을 사용하여 작업 초안으로 발행되었습니다. 이 문서는 W3C 권고안이 되는 것을 목표로 합니다.

작업 초안으로 발행되었다고 해서 W3C 및 회원의 지지를 의미하지는 않습니다.

이 문서는 초안이며 언제든지 업데이트, 대체 또는 폐기될 수 있습니다. 진행 중인 작업 외의 문서로 인용하는 것은 적절하지 않습니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 그룹 산출물과 관련하여 공개된 특허 공개 목록을 유지합니다. 해당 페이지에는 특허 공개 방법도 안내되어 있습니다. 특정 특허에 필수 청구항이 포함되어 있다고 실제로 아는 개인은 W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.

이 문서는 2023년 11월 3일 W3C 프로세스 문서에 따라 관리됩니다.

1. 정의

Codec

일반적으로 AudioDecoder, AudioEncoder, VideoDecoder, 또는 VideoEncoder의 인스턴스를 지칭합니다.

Key Chunk

디코딩을 위해 다른 프레임에 의존하지 않는 인코딩된 청크. 일반적으로 "키 프레임"이라고도 불립니다.

Internal Pending Output

현재 기본 코덱 구현의 내부 파이프라인에 존재하는 VideoFrame과 같은 코덱 출력물. 기본 코덱 구현은 새로운 입력이 제공될 때만 새로운 출력을 내보낼 수 있습니다(MAY). 기본 코덱 구현은 flush에 응답하여 모든 출력을 반드시 내보내야 합니다(MUST).

Codec System Resources

코덱 구성 또는 AudioDataVideoFrame 객체 생성의 일부로 User Agent가 할당할 수 있는(MAY) CPU 메모리, GPU 메모리, 특정 디코딩/인코딩 하드웨어에 대한 독점 핸들 등의 자원. 이러한 자원은 빠르게 소진될 수 있으며(MAY) 더 이상 사용하지 않을 때 즉시 반드시 해제해야 합니다(SHOULD).

Temporal Layer

타임스탬프 간격이 특정 프레임레이트를 생성하는 EncodedVideoChunk들의 그룹. scalabilityMode 참조.

Progressive Image

인코딩된 데이터가 완전히 버퍼링되지 않은 상태에서도 더 낮은 수준의 디테일이 먼저 제공되며, 여러 수준의 디테일로 디코딩이 가능한 이미지를 의미합니다.

Progressive Image Frame Generation

Progressive Image 디코딩 출력에 대한 세대 식별자. 각 세대는 디코딩된 출력에 추가적인 디테일을 더합니다. 프레임의 세대를 계산하는 메커니즘은 구현자 정의입니다.

Primary Image Track

주어진 이미지 파일에서 기본 트랙으로 표시된 이미지 트랙. 기본 트랙을 표시하는 메커니즘은 포맷에 따라 정의됩니다.

RGB Format

어떤 순서나 레이아웃(인터리브 또는 플래너)이든 상관없이 빨강, 초록, 파랑 색상 채널을 포함하고, 알파 채널의 존재 여부와 관계없이 VideoPixelFormat을 의미합니다.

sRGB Color Space

VideoColorSpace 객체로, 다음과 같이 초기화됩니다:

  1. [[primaries]] 값은 bt709,

  2. [[transfer]] 값은 iec61966-2-1,

  3. [[matrix]] 값은 rgb,

  4. [[full range]] 값은 true

Display P3 Color Space

VideoColorSpace 객체로, 다음과 같이 초기화됩니다:

  1. [[primaries]] 값은 smpte432,

  2. [[transfer]] 값은 iec61966-2-1,

  3. [[matrix]] 값은 rgb,

  4. [[full range]] 값은 true

REC709 Color Space

VideoColorSpace 객체로, 다음과 같이 초기화됩니다:

  1. [[primaries]] 값은 bt709,

  2. [[transfer]] 값은 bt709,

  3. [[matrix]] 값은 bt709,

  4. [[full range]] 값은 false

Codec Saturation

기본 코덱 구현에서 활성 디코딩 또는 인코딩 요청의 수가 구현별 최대치에 도달하여 일시적으로 더 많은 작업을 수락할 수 없는 상태. 최대치는 1보다 큰 임의의 값(무한대 포함)이 될 수 있습니다. 포화 상태에서는 decode() 또는 encode()에 대한 추가 호출이 control message queue에 버퍼링되며, 각각 decodeQueuSizeencodeQueueSize 속성이 증가합니다. 코덱 구현은 현재 작업이 충분히 진행되면 포화 상태에서 벗어납니다.

2. 코덱 처리 모델

2.1. 배경

이 섹션은 규범적이지 않습니다.

이 명세에서 정의된 코덱 인터페이스는 이전 작업이 아직 대기 중인 동안에도 새로운 코덱 작업을 예약할 수 있도록 설계되었습니다. 예를 들어, 웹 저자는 이전 decode()가 완료될 때까지 기다리지 않고 decode()를 호출할 수 있습니다. 이는 기본 코덱 작업을 별도의 병렬 큐로 오프로드하여 병렬 실행함으로써 달성됩니다.

이 섹션은 웹 저자 관점에서 보이는 스레딩 동작을 설명합니다. 구현자는 외부적으로 보이는 블로킹 및 순서 동작이 아래와 같이 유지되는 한 더 많은 스레드를 사용할 수 있습니다.

2.2. 제어 메시지

제어 메시지codec 인스턴스(예: encode())에서 메서드 호출에 해당하는 일련의 단계를 정의합니다.

제어 메시지 큐로, 제어 메시지들의 집합입니다. 각 codec 인스턴스는 내부 슬롯 [[control message queue]]에 제어 메시지 큐를 저장합니다.

제어 메시지 큐잉큐에 삽입하는 것을 의미하며, codec[[control message queue]]에 메시지를 추가합니다. 코덱 메서드를 호출하면 일반적으로 작업을 예약하기 위해 제어 메시지가 큐에 추가됩니다.

제어 메시지 실행은 메시지를 큐에 넣은 메서드가 지정한 일련의 단계를 수행하는 것을 의미합니다.

특정 제어 메시지의 단계는 제어 메시지 큐의 이후 메시지 처리를 차단할 수 있습니다. 각 codec 인스턴스는 [[message queue blocked]]라는 불리언 내부 슬롯을 가지며, 차단이 발생하면 true로 설정됩니다. 차단 메시지는 [[message queue blocked]]false로 설정하고 제어 메시지 큐 처리 단계를 다시 실행함으로써 종료됩니다.

모든 제어 메시지는 "processed" 또는 "not processed" 중 하나를 반환합니다. "processed"를 반환하면 메시지 단계가 실행 중(또는 완료됨)을 의미하며, 해당 메시지는 제어 메시지 큐에서 제거될 수 있습니다. "not processed"는 해당 메시지를 현재 처리하면 안 되며, 제어 메시지 큐에 남겨두고 나중에 다시 시도해야 함을 의미합니다.

제어 메시지 큐 처리 단계는 다음과 같습니다:

  1. [[message queue blocked]]false이고 [[control message queue]]가 비어 있지 않은 동안:

    1. front message[[control message queue]]의 첫 번째 메시지로 설정합니다.

    2. outcome제어 메시지 단계를 실행한 결과로 설정합니다.

    3. outcome"not processed"와 같으면 break 합니다.

    4. 그 외의 경우 front message[[control message queue]]에서 제거합니다.

2.3. 코덱 작업 병렬 큐

codec 인스턴스는 [[codec work queue]]라는 내부 슬롯을 가지며, 병렬 큐입니다.

codec 인스턴스는 [[codec implementation]]이라는 내부 슬롯을 가지며, 이는 기본 플랫폼 인코더 또는 디코더를 참조합니다. 최초 할당을 제외하고, [[codec implementation]]을 참조하는 단계는 [[codec work queue]]에 큐잉됩니다.

codec 인스턴스는 고유한 코덱 작업 소스를 가집니다. 작업 큐잉[[codec work queue]]에서 이벤트 루프로 이동할 때 코덱 작업 소스를 사용합니다.

3. AudioDecoder 인터페이스

[Exposed=(Window,DedicatedWorker), SecureContext]
        interface AudioDecoder : EventTarget {
          constructor(AudioDecoderInit init);
        
          readonly attribute CodecState state;
          readonly attribute unsigned long decodeQueueSize;
          attribute EventHandler ondequeue;
        
          undefined configure(AudioDecoderConfig config);
          undefined decode(EncodedAudioChunk chunk);
          Promise<undefined> flush();
          undefined reset();
          undefined close();
        
          static Promise<AudioDecoderSupport> isConfigSupported(AudioDecoderConfig config);
        };
        
        dictionary AudioDecoderInit {
          required AudioDataOutputCallback output;
          required WebCodecsErrorCallback error;
        };
        
        callback AudioDataOutputCallback = undefined(AudioData output);
        

3.1. 내부 슬롯

[[control message queue]]

제어 메시지codec 인스턴스에서 수행하기 위해 사용합니다. [[control message queue]] 참조.

[[message queue blocked]]

[[control message queue]]의 처리가 대기 중인 제어 메시지로 인해 차단될 때를 나타내는 불리언 값입니다. [[message queue blocked]] 참조.

[[codec implementation]]

User Agent가 제공하는 기본 디코더 구현. [[codec implementation]] 참조.

[[codec work queue]]

[[codec implementation]]을 참조하는 병렬 단계를 실행하는 데 사용되는 병렬 큐입니다. [[codec work queue]] 참조.

[[codec saturated]]

[[codec implementation]]이 추가 디코딩 작업을 수락할 수 없을 때를 나타내는 불리언 값입니다.

[[output callback]]

디코딩된 출력에 대해 생성 시 제공된 콜백입니다.

[[error callback]]

디코딩 오류에 대해 생성 시 제공된 콜백입니다.

[[key chunk required]]

다음에 decode()에 전달되는 청크가 key chunk를 반드시 설명해야 함(MUST)을 나타내는 불리언 값입니다. [[type]]에 의해 표시됩니다.

[[state]]

AudioDecoder의 현재 CodecState 값입니다.

[[decodeQueueSize]]

대기 중인 디코드 요청의 수입니다. 이 값은 기본 코덱이 새로운 입력을 받을 준비가 되면 감소합니다.

[[pending flush promises]]

flush() 호출로 반환된 미해결 promise들의 목록입니다.

[[dequeue event scheduled]]

dequeue 이벤트가 이미 예약되어 있는지 여부를 나타내는 불리언 값입니다. 이벤트 스팸을 방지하는 데 사용됩니다.

3.2. 생성자

AudioDecoder(init)
  1. d를 새로운 AudioDecoder 객체로 설정합니다.

  2. [[control message queue]]에 새로운 를 할당합니다.

  3. [[message queue blocked]]false를 할당합니다.

  4. [[codec implementation]]null을 할당합니다.

  5. [[codec work queue]]에 새로운 병렬 큐를 시작한 결과를 할당합니다.

  6. [[codec saturated]]false를 할당합니다.

  7. init.output을 [[output callback]]에 할당합니다.

  8. init.error를 [[error callback]]에 할당합니다.

  9. [[key chunk required]]true를 할당합니다.

  10. [[state]]"unconfigured"를 할당합니다.

  11. [[decodeQueueSize]]0을 할당합니다.

  12. [[pending flush promises]]에 새로운 리스트를 할당합니다.

  13. [[dequeue event scheduled]]false를 할당합니다.

  14. d를 반환합니다.

3.3. 속성

state, 타입 CodecState, 읽기 전용

[[state]]의 값을 반환합니다.

decodeQueueSize, 타입 unsigned long, 읽기 전용

[[decodeQueueSize]]의 값을 반환합니다.

ondequeue, 타입 EventHandler

이벤트 핸들러 IDL 속성이며, 이벤트 핸들러 이벤트 타입dequeue입니다.

3.4. 이벤트 요약

dequeue

AudioDecoder에서 decodeQueueSize가 감소할 때 발생합니다.

3.5. 메서드

configure(config)
오디오 디코더를 config에 따라 청크를 디코딩하도록 구성하는 제어 메시지를 큐에 추가합니다.

참고: 이 메서드는 User Agent가 config를 지원하지 않을 경우 NotSupportedError를 발생시킵니다. 작성자는 먼저 configisConfigSupported()를 호출하여 지원 여부를 확인하는 것이 좋습니다. User Agent는 특정 코덱 타입이나 구성에 대해 반드시 지원할 필요는 없습니다.

호출 시 다음 단계를 실행합니다:

  1. config유효한 AudioDecoderConfig가 아니면 TypeError를 throw합니다.

  2. [[state]]“closed”이면 InvalidStateError를 throw합니다.

  3. [[state]]"configured"로 설정합니다.

  4. [[key chunk required]]true로 설정합니다.

  5. 디코더를 config로 구성하는 제어 메시지를 큐에 추가합니다.

  6. 제어 메시지 큐를 처리합니다.

디코더를 구성하는 제어 메시지 실행은 다음 단계를 의미합니다:

  1. [[message queue blocked]]true를 할당합니다.

  2. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. supportedconfig구성 지원 확인 알고리즘을 실행한 결과로 설정합니다.

    2. supportedfalse이면, 작업을 큐에 추가하여 AudioDecoder 닫기 알고리즘을 NotSupportedError와 함께 실행하고, 이 단계들을 중단합니다.

    3. 필요하다면 [[codec implementation]]config를 지원하는 구현체를 할당합니다.

    4. [[codec implementation]]config로 구성합니다.

    5. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. [[message queue blocked]]false를 할당합니다.

      2. 작업을 큐에 추가하여 제어 메시지 큐를 처리합니다.

  3. "processed"를 반환합니다.

decode(chunk)
주어진 chunk를 디코딩하는 제어 메시지를 큐에 추가합니다.

호출 시 다음 단계를 실행합니다:

  1. [[state]]"configured"가 아니면 InvalidStateError를 throw합니다.

  2. [[key chunk required]]true인 경우:

    1. chunk.[[type]]key가 아니면 DataError를 throw합니다.

    2. 구현자는 chunk[[internal data]]를 검사하여 실제 key chunk인지 확인해야 합니다. 불일치가 감지되면 DataError를 throw합니다.

    3. 그렇지 않으면 [[key chunk required]]false를 할당합니다.

  3. [[decodeQueueSize]]를 증가시킵니다.

  4. chunk를 디코딩하는 제어 메시지를 큐에 추가합니다.

  5. 제어 메시지 큐를 처리합니다.

chunk를 디코딩하는 제어 메시지 실행은 다음 단계를 의미합니다:

  1. [[codec saturated]]true이면 "not processed"를 반환합니다.

  2. 청크 디코딩으로 [[codec implementation]]포화 상태가 되면, [[codec saturated]]true를 할당합니다.

  3. [[decodeQueueSize]]를 감소시키고, Dequeue 이벤트 예약 알고리즘을 실행합니다.

  4. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. [[codec implementation]]을 사용해 청크를 디코딩 시도합니다.

    2. 디코딩 중 오류가 발생하면 작업을 큐에 추가하여 AudioDecoder 닫기 알고리즘을 EncodingError와 함께 실행하고 반환합니다.

    3. [[codec saturated]]true이고 [[codec implementation]]이 더 이상 포화 상태가 아니면, 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. [[codec saturated]]false를 할당합니다.

      2. 제어 메시지 큐를 처리합니다.

    4. decoded outputs[[codec implementation]]에서 발생한 디코딩된 오디오 데이터 출력의 리스트로 설정합니다.

    5. decoded outputs가 비어 있지 않으면 작업을 큐에 추가하여 Output AudioData 알고리즘을 decoded outputs와 함께 실행합니다.

  5. "processed"를 반환합니다.

flush()
제어 메시지제어 메시지 큐의 모든 메시지를 완료하고 모든 출력을 내보냅니다.

호출 시 다음 단계를 실행합니다:

  1. [[state]]"configured"가 아니면 거부된 promiseInvalidStateError DOMException과 함께 반환합니다.

  2. [[key chunk required]]true로 설정합니다.

  3. promise를 새 Promise로 설정합니다.

  4. promise[[pending flush promises]]에 추가합니다.

  5. promise와 함께 코덱을 flush하는 제어 메시지를 큐에 추가합니다.

  6. 제어 메시지 큐를 처리합니다.

  7. promise를 반환합니다.

코덱을 flush하는 제어 메시지 실행promise와 함께 다음 단계를 의미합니다:

  1. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. [[codec implementation]]에 모든 내부 대기 출력을 내보내도록 신호를 보냅니다.

    2. decoded outputs[[codec implementation]]에서 발생한 디코딩된 오디오 데이터 출력의 리스트로 설정합니다.

    3. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. decoded outputs가 비어 있지 않으면 Output AudioData 알고리즘을 decoded outputs와 함께 실행합니다.

      2. promise[[pending flush promises]]에서 제거합니다.

      3. promise를 resolve합니다.

  2. "processed"를 반환합니다.

reset()
모든 상태(구성 포함), 제어 메시지제어 메시지 큐의 모든 메시지, 모든 대기 콜백을 즉시 초기화합니다.

호출 시 Reset AudioDecoder 알고리즘을 AbortError DOMException과 함께 실행합니다.

close()
모든 대기 작업을 즉시 중단하고 시스템 리소스를 해제합니다. close는 최종적입니다.

호출 시 Close AudioDecoder 알고리즘을 AbortError DOMException과 함께 실행합니다.

isConfigSupported(config)
제공된 config가 User Agent에서 지원되는지 여부를 나타내는 promise를 반환합니다.

참고: 반환된 AudioDecoderSupport config에는 User Agent가 인식한 딕셔너리 멤버만 포함됩니다. 인식하지 못한 딕셔너리 멤버는 무시됩니다. 작성자는 반환된 config와 제공한 config를 비교하여 인식하지 못한 멤버를 감지할 수 있습니다.

호출 시 다음 단계를 실행합니다:

  1. config유효한 AudioDecoderConfig가 아니면 거부된 promiseTypeError와 함께 반환합니다.

  2. p를 새 Promise로 설정합니다.

  3. checkSupportQueue를 새 parallel queue로 시작한 결과로 설정합니다.

  4. checkSupportQueue에 다음 단계를 큐에 추가합니다:

    1. supportedconfig구성 지원 확인 알고리즘을 실행한 결과로 설정합니다.

    2. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. decoderSupport를 새로 생성한 AudioDecoderSupport로 설정하고, 다음과 같이 초기화합니다:

        1. configconfigClone Configuration 알고리즘을 실행한 결과로 설정합니다.

        2. supportedsupported로 설정합니다.

      2. pdecoderSupport로 resolve합니다.

  5. p를 반환합니다.

3.6. 알고리즘

Dequeue 이벤트 예약
  1. [[dequeue event scheduled]]true이면 반환합니다.

  2. [[dequeue event scheduled]]true를 할당합니다.

  3. 작업을 큐에 추가하여 다음 단계를 실행합니다:

    1. this에서 dequeue라는 단순 이벤트를 발생시킵니다.

    2. [[dequeue event scheduled]]false를 할당합니다.

AudioData 출력 (outputs와 함께)
다음 단계를 실행합니다:
  1. outputs의 각 output에 대해:

    1. data를 다음과 같이 초기화된 AudioData로 설정합니다:

      1. [[Detached]]false를 할당합니다.

      2. resourceoutput이 설명하는 미디어 리소스로 설정합니다.

      3. resourceReferenceresource에 대한 참조로 설정합니다.

      4. [[resource reference]]resourceReference를 할당합니다.

      5. timestampoutput과 연관된 EncodedAudioChunk[[timestamp]]로 설정합니다.

      6. [[timestamp]]timestamp를 할당합니다.

      7. output이 인식된 AudioSampleFormat을 사용하면, 해당 포맷을 [[format]]에 할당합니다. 그렇지 않으면 [[format]]null을 할당합니다.

      8. [[sample rate]], [[number of frames]], [[number of channels]]output에 따라 값을 할당합니다.

    2. [[output callback]]data와 함께 호출합니다.

AudioDecoder 리셋 (exception과 함께)
다음 단계를 실행합니다:
  1. [[state]]"closed"이면 InvalidStateError를 throw합니다.

  2. [[state]]"unconfigured"로 설정합니다.

  3. [[codec implementation]]에 이전 구성에 대한 출력 생성을 중단하도록 신호를 보냅니다.

  4. [[control message queue]]에서 모든 제어 메시지를 제거합니다.

  5. [[decodeQueueSize]]가 0보다 크면:

    1. [[decodeQueueSize]]를 0으로 설정합니다.

    2. Dequeue 이벤트 예약 알고리즘을 실행합니다.

  6. [[pending flush promises]]의 각 promise에 대해:

    1. promiseexception으로 reject합니다.

    2. [[pending flush promises]]에서 promise를 제거합니다.

AudioDecoder 닫기 (exception과 함께)
다음 단계를 실행합니다:
  1. AudioDecoder 리셋 알고리즘을 exception과 함께 실행합니다.

  2. [[state]]"closed"로 설정합니다.

  3. [[codec implementation]]를 비우고 관련 시스템 리소스를 해제합니다.

  4. exceptionAbortError DOMException이 아니면, [[error callback]]exception과 함께 호출합니다.

4. VideoDecoder 인터페이스

[Exposed=(Window,DedicatedWorker), SecureContext]
interface VideoDecoder : EventTarget {
  constructor(VideoDecoderInit init);

  readonly attribute CodecState state;
  readonly attribute unsigned long decodeQueueSize;
  attribute EventHandler ondequeue;

  undefined configure(VideoDecoderConfig config);
  undefined decode(EncodedVideoChunk chunk);
  Promise<undefined> flush();
  undefined reset();
  undefined close();

  static Promise<VideoDecoderSupport> isConfigSupported(VideoDecoderConfig config);
};

dictionary VideoDecoderInit {
  required VideoFrameOutputCallback output;
  required WebCodecsErrorCallback error;
};

callback VideoFrameOutputCallback = undefined(VideoFrame output);

4.1. 내부 슬롯

[[control message queue]]

codec 인스턴스에서 수행될 형태의 제어 메시지입니다. [[control message queue]]를 참조하세요.

[[message queue blocked]]

[[control message queue]]의 처리가 대기 중인 제어 메시지에 의해 차단될 때를 나타내는 불리언입니다. [[message queue blocked]]를 참조하세요.

[[codec implementation]]

User Agent가 제공하는 기본 디코더 구현입니다. [[codec implementation]]를 참조하세요.

[[codec work queue]]

[[codec implementation]]을 참조하는 병렬 단계를 실행하는 데 사용되는 parallel queue입니다. [[codec work queue]]를 참조하세요.

[[codec saturated]]

[[codec implementation]]이 추가 디코딩 작업을 수락할 수 없을 때를 나타내는 불리언입니다.

[[output callback]]

디코딩된 출력에 대해 생성 시 제공된 콜백입니다.

[[error callback]]

디코딩 오류에 대해 생성 시 제공된 콜백입니다.

[[active decoder config]]

현재 적용 중인 VideoDecoderConfig입니다.

[[key chunk required]]

다음 decode()에 전달되는 청크가 type에 따라 key chunk를 반드시 설명해야 함을 나타내는 불리언입니다.

[[state]]

VideoDecoder의 현재 CodecState입니다.

[[decodeQueueSize]]

대기 중인 디코드 요청의 수입니다. 이 값은 기본 코덱이 새 입력을 받을 준비가 되면 감소합니다.

[[pending flush promises]]

flush() 호출로 반환된 미해결 promise의 리스트입니다.

[[dequeue event scheduled]]

dequeue 이벤트가 이미 예약되어 있는지 여부를 나타내는 불리언입니다. 이벤트 스팸 방지에 사용됩니다.

4.2. 생성자

VideoDecoder(init)
  1. d를 새로운 VideoDecoder 객체로 설정합니다.

  2. [[control message queue]]에 새로운 를 할당합니다.

  3. [[message queue blocked]]false를 할당합니다.

  4. [[codec implementation]]null을 할당합니다.

  5. [[codec work queue]]에 새로운 parallel queue를 시작한 결과를 할당합니다.

  6. [[codec saturated]]false를 할당합니다.

  7. init.output을 [[output callback]]에 할당합니다.

  8. init.error를 [[error callback]]에 할당합니다.

  9. [[active decoder config]]null을 할당합니다.

  10. [[key chunk required]]true를 할당합니다.

  11. [[state]]"unconfigured"를 할당합니다.

  12. [[decodeQueueSize]]0을 할당합니다.

  13. [[pending flush promises]]에 새로운 리스트를 할당합니다.

  14. [[dequeue event scheduled]]false를 할당합니다.

  15. d를 반환합니다.

4.3. 속성

state, of type CodecState, readonly

[[state]]의 값을 반환합니다.

decodeQueueSize, of type unsigned long, readonly

[[decodeQueueSize]]의 값을 반환합니다.

ondequeue, of type EventHandler

dequeue 이벤트 타입을 갖는 이벤트 핸들러 IDL 속성입니다.

4.4. 이벤트 요약

dequeue

VideoDecoder에서 decodeQueueSize가 감소할 때 발생합니다.

4.5. 메서드

configure(config)
제어 메시지를 큐에 추가하여 config에 따라 비디오 디코더를 설정하고 청크를 디코딩합니다.

참고: 이 메서드는 User Agent가 config를 지원하지 않을 경우 NotSupportedError를 발생시킵니다. 작성자는 먼저 configisConfigSupported()를 호출하여 지원 여부를 확인하는 것이 좋습니다. User Agent는 특정 코덱 타입이나 설정을 반드시 지원할 필요는 없습니다.

호출 시 다음 단계를 실행합니다:

  1. config유효한 VideoDecoderConfig가 아니면 TypeError를 throw합니다.

  2. [[state]]“closed”이면 InvalidStateError를 throw합니다.

  3. [[state]]"configured"로 설정합니다.

  4. [[key chunk required]]true로 설정합니다.

  5. 제어 메시지를 큐에 추가하여 config로 디코더를 설정합니다.

  6. 제어 메시지 큐를 처리합니다.

제어 메시지 실행은 디코더를 설정하기 위해 다음 단계를 수행합니다:

  1. [[message queue blocked]]true를 할당합니다.

  2. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. supportedconfigCheck Configuration Support 알고리즘을 실행한 결과로 설정합니다.

    2. supportedfalse이면, 작업을 큐에 추가하여 Close VideoDecoder 알고리즘을 NotSupportedError와 함께 실행하고, 이 단계를 중단합니다.

    3. 필요하다면 [[codec implementation]]config를 지원하는 구현체를 할당합니다.

    4. [[codec implementation]]config로 설정합니다.

    5. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. [[message queue blocked]]false를 할당합니다.

      2. 작업을 큐에 추가하여 제어 메시지 큐를 처리합니다.

  3. "processed"를 반환합니다.

decode(chunk)
제어 메시지를 큐에 추가하여 주어진 chunk를 디코딩합니다.

참고: 출력된 VideoFrame이 더 이상 필요하지 않을 때 즉시 close()를 호출하는 것이 좋습니다. 미디어 리소스VideoDecoder가 소유하며, 이를 해제하지 않거나 가비지 컬렉션을 기다릴 경우 디코딩이 지연될 수 있습니다.

참고: VideoDecoder는 프레임이 표시 순서대로 출력되도록 요구합니다. 일부 [[codec implementation]]에서는 User Agent가 출력 순서를 재정렬해야 할 수 있습니다.

호출 시 다음 단계를 실행합니다:

  1. [[state]]"configured"가 아니면 InvalidStateError를 throw합니다.

  2. [[key chunk required]]true인 경우:

    1. chunk.typekey가 아니면 DataError를 throw합니다.

    2. 구현자는 권장되는 방식으로 chunk[[internal data]]를 검사하여 실제 key chunk인지 확인해야 합니다. 불일치가 발견되면 DataError를 throw합니다.

    3. 그렇지 않으면 false[[key chunk required]]에 할당합니다.

  3. [[decodeQueueSize]]를 증가시킵니다.

  4. 제어 메시지를 큐에 추가하여 chunk를 디코딩합니다.

  5. 제어 메시지 큐를 처리합니다.

제어 메시지 실행chunk를 디코딩하기 위해 다음 단계를 수행합니다:

  1. [[codec saturated]]true이면 "not processed"를 반환합니다.

  2. 청크 디코딩으로 [[codec implementation]]saturated 상태가 되면, [[codec saturated]]true를 할당합니다.

  3. [[decodeQueueSize]]를 감소시키고, Schedule Dequeue Event 알고리즘을 실행합니다.

  4. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. [[codec implementation]]를 사용하여 청크를 디코딩 시도합니다.

    2. 디코딩 중 오류가 발생하면, 작업을 큐에 추가하여 Close VideoDecoder 알고리즘을 EncodingError와 함께 실행하고 반환합니다.

    3. [[codec saturated]]true이고 [[codec implementation]]이 더 이상 saturated 상태가 아니면, 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. [[codec saturated]]false를 할당합니다.

      2. 제어 메시지 큐를 처리합니다.

    4. decoded outputs[[codec implementation]]에서 표시 순서대로 출력된 디코딩된 비디오 데이터의 리스트로 설정합니다.

    5. decoded outputs가 비어 있지 않으면, 작업을 큐에 추가하여 Output VideoFrame 알고리즘을 decoded outputs로 실행합니다.

  5. "processed"를 반환합니다.

flush()
제어 메시지제어 메시지 큐에서 모두 완료하고, 모든 출력을 방출합니다.

호출 시 다음 단계를 실행합니다:

  1. [[state]]"configured"가 아니면 거부된 promiseInvalidStateError DOMException과 함께 반환합니다.

  2. [[key chunk required]]true로 설정합니다.

  3. promise를 새 Promise로 생성합니다.

  4. promise[[pending flush promises]]에 추가합니다.

  5. 제어 메시지를 큐에 추가하여 promise로 코덱을 flush합니다.

  6. 제어 메시지 큐를 처리합니다.

  7. promise를 반환합니다.

제어 메시지 실행promise와 함께 코덱을 flush하기 위해 다음 단계를 수행합니다:

  1. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. [[codec implementation]]에 모든 내부 대기 출력을 방출하도록 신호를 보냅니다.

    2. decoded outputs[[codec implementation]]에서 방출된 디코딩된 비디오 데이터의 리스트로 설정합니다.

    3. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. decoded outputs가 비어 있지 않으면, Output VideoFrame 알고리즘을 decoded outputs로 실행합니다.

      2. promise[[pending flush promises]]에서 제거합니다.

      3. promise를 resolve합니다.

  2. "processed"를 반환합니다.

reset()
모든 상태(설정 포함), 제어 메시지제어 메시지 큐의 모든 메시지, 모든 대기 콜백을 즉시 초기화합니다.

호출 시 Reset VideoDecoder 알고리즘을 AbortError DOMException과 함께 실행합니다.

close()
모든 대기 작업을 즉시 중단하고 시스템 리소스를 해제합니다. close는 최종적입니다.

호출 시 Close VideoDecoder 알고리즘을 AbortError DOMException과 함께 실행합니다.

isConfigSupported(config)
제공된 config가 User Agent에서 지원되는지 여부를 나타내는 promise를 반환합니다.

참고: 반환된 VideoDecoderSupport config에는 User Agent가 인식한 딕셔너리 멤버만 포함됩니다. 인식하지 못한 멤버는 무시됩니다. 작성자는 반환된 config와 제공한 config를 비교하여 인식하지 못한 멤버를 감지할 수 있습니다.

호출 시 다음 단계를 실행합니다:

  1. config유효한 VideoDecoderConfig가 아니면 거부된 promiseTypeError와 함께 반환합니다.

  2. p를 새 Promise로 생성합니다.

  3. checkSupportQueue를 새 병렬 큐로 시작한 결과로 설정합니다.

  4. checkSupportQueue에 다음 단계를 큐에 추가합니다:

    1. supportedconfigCheck Configuration Support 알고리즘을 실행한 결과로 설정합니다.

    2. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. decoderSupport를 새로 생성한 VideoDecoderSupport로 초기화합니다:

        1. configconfigClone Configuration 알고리즘을 실행한 결과로 설정합니다.

        2. supportedsupported로 설정합니다.

      2. pdecoderSupport로 resolve합니다.

  5. p를 반환합니다.

4.6. 알고리즘

Schedule Dequeue Event
  1. [[dequeue event scheduled]]true이면 반환합니다.

  2. [[dequeue event scheduled]]true를 할당합니다.

  3. 작업을 큐에 추가하여 다음 단계를 실행합니다:

    1. dequeue라는 단순 이벤트를 this에 발생시킵니다.

    2. [[dequeue event scheduled]]false를 할당합니다.

Output VideoFrames (with outputs)
다음 단계를 실행합니다:
  1. outputs의 각 output에 대해:

    1. timestampdurationoutput에 연결된 EncodedVideoChunktimestampduration으로 설정합니다.

    2. displayAspectWidthdisplayAspectHeight를 undefined로 설정합니다.

    3. displayAspectWidthdisplayAspectHeight[[active decoder config]]존재하면, 해당 값을 각각 displayAspectWidthdisplayAspectHeight에 할당합니다.

    4. colorSpace를 코덱 구현에서 감지된 outputVideoColorSpace로 설정합니다. 감지된 VideoColorSpace가 없으면 colorSpaceundefined로 설정합니다.

      참고: 코덱 구현은 비트스트림을 분석하여 VideoColorSpace를 감지할 수 있습니다. 감지는 최선의 노력으로 이루어지며, 감지 방법은 구현자 정의 및 코덱별입니다. 작성자는 VideoDecoderConfigcolorSpace를 제공하여 감지된 VideoColorSpace를 덮어쓸 수 있습니다.

    5. colorSpace[[active decoder config]]존재하면, 해당 값을 colorSpace에 할당합니다.

    6. rotationflip의 값을 각각 rotationflip에 할당합니다.

    7. frameCreate a VideoFrame 알고리즘을 output, timestamp, duration, displayAspectWidth, displayAspectHeight, colorSpace, rotation, flip과 함께 실행한 결과로 설정합니다.

    8. [[output callback]]frame으로 호출합니다.

Reset VideoDecoder (with exception)
다음 단계를 실행합니다:
  1. state"closed"이면 InvalidStateError를 throw합니다.

  2. state"unconfigured"로 설정합니다.

  3. [[codec implementation]]에 이전 설정에 대한 출력 생성을 중단하도록 신호를 보냅니다.

  4. [[control message queue]]에서 모든 제어 메시지를 제거합니다.

  5. [[decodeQueueSize]]가 0보다 크면:

    1. [[decodeQueueSize]]를 0으로 설정합니다.

    2. Schedule Dequeue Event 알고리즘을 실행합니다.

  6. [[pending flush promises]]의 각 promise에 대해:

    1. promiseexception으로 reject합니다.

    2. promise[[pending flush promises]]에서 제거합니다.

Close VideoDecoder (with exception)
다음 단계를 실행합니다:
  1. Reset VideoDecoder 알고리즘을 exception과 함께 실행합니다.

  2. state"closed"로 설정합니다.

  3. [[codec implementation]]를 비우고 관련 시스템 리소스를 해제합니다.

  4. exceptionAbortError DOMException이 아니면, [[error callback]]exception으로 호출합니다.

5. AudioEncoder 인터페이스

[Exposed=(Window,DedicatedWorker), SecureContext]
        interface AudioEncoder : EventTarget {
          constructor(AudioEncoderInit init);
        
          readonly attribute CodecState state;
          readonly attribute unsigned long encodeQueueSize;
          attribute EventHandler ondequeue;
        
          undefined configure(AudioEncoderConfig config);
          undefined encode(AudioData data);
          Promise<undefined> flush();
          undefined reset();
          undefined close;
        
          static Promise<AudioEncoderSupport> isConfigSupported(AudioEncoderConfig config);
        };
        
        dictionary AudioEncoderInit {
          required EncodedAudioChunkOutputCallback output;
          required WebCodecsErrorCallback error;
        };
        
        callback EncodedAudioChunkOutputCallback =
            undefined (EncodedAudioChunk output,
                       optional EncodedAudioChunkMetadata metadata = {});
        

5.1. 내부 슬롯

[[control message queue]]

코덱 인스턴스에서 수행될 제어 메시지입니다. [[control message queue]]를 참조하세요.

[[message queue blocked]]

[[control message queue]]의 처리가 대기 중인 제어 메시지로 인해 차단되었는지 나타내는 불리언입니다. [[message queue blocked]]를 참조하세요.

[[codec implementation]]

User Agent가 제공하는 기본 인코더 구현입니다. [[codec implementation]]를 참조하세요.

[[codec work queue]]

[[codec implementation]]을 참조하는 병렬 단계를 실행하는 데 사용되는 병렬 큐입니다. [[codec work queue]]를 참조하세요.

[[codec saturated]]

[[codec implementation]]이 추가 인코딩 작업을 수락할 수 없는 경우를 나타내는 불리언입니다.

[[output callback]]

인코딩된 출력에 대해 생성 시 제공된 콜백입니다.

[[error callback]]

인코딩 오류에 대해 생성 시 제공된 콜백입니다.

[[active encoder config]]

현재 적용 중인 AudioEncoderConfig입니다.

[[active output config]]

가장 최근에 방출된 EncodedAudioChunk를 디코딩하는 방법을 설명하는 AudioDecoderConfig입니다.

[[state]]

AudioEncoder의 현재 CodecState입니다.

[[encodeQueueSize]]

대기 중인 인코드 요청의 수입니다. 이 수는 기본 코덱이 새 입력을 받을 준비가 되면 감소합니다.

[[pending flush promises]]

flush() 호출로 반환된 미해결 promise의 리스트입니다.

[[dequeue event scheduled]]

dequeue 이벤트가 이미 예약되어 있는지 나타내는 불리언입니다. 이벤트 스팸을 방지하기 위해 사용됩니다.

5.2. 생성자

AudioEncoder(init)
  1. e를 새로운 AudioEncoder 객체로 생성합니다.

  2. [[control message queue]]에 새로운 를 할당합니다.

  3. [[message queue blocked]]false를 할당합니다.

  4. [[codec implementation]]null을 할당합니다.

  5. [[codec work queue]]에 새로운 병렬 큐를 시작한 결과를 할당합니다.

  6. [[codec saturated]]false를 할당합니다.

  7. init.output을 [[output callback]]에 할당합니다.

  8. init.error를 [[error callback]]에 할당합니다.

  9. [[active encoder config]]null을 할당합니다.

  10. [[active output config]]null을 할당합니다.

  11. [[state]]"unconfigured"를 할당합니다>

  12. [[encodeQueueSize]]0을 할당합니다.

  13. [[pending flush promises]]에 새로운 리스트를 할당합니다.

  14. [[dequeue event scheduled]]false를 할당합니다.

  15. e를 반환합니다.

5.3. 속성

state, of type CodecState, readonly

[[state]]의 값을 반환합니다.

encodeQueueSize, of type unsigned long, readonly

[[encodeQueueSize]]의 값을 반환합니다.

ondequeue, of type EventHandler

이벤트 핸들러 IDL 속성으로, 이벤트 핸들러 이벤트 타입dequeue입니다.

5.4. 이벤트 요약

dequeue

AudioEncoder에서 encodeQueueSize가 감소할 때 발생합니다.

5.5. 메서드

configure(config)
제어 메시지를 큐에 추가하여 config에 따라 오디오 인코더를 설정하고 오디오 데이터를 인코딩합니다.

참고: 이 메서드는 User Agent가 config를 지원하지 않을 경우 NotSupportedError를 발생시킵니다. 작성자는 먼저 configisConfigSupported()를 호출하여 지원 여부를 확인하는 것이 좋습니다. User Agent는 특정 코덱 타입이나 설정을 반드시 지원할 필요는 없습니다.

호출 시 다음 단계를 실행합니다:

  1. config유효한 AudioEncoderConfig가 아니면 TypeError를 throw합니다.

  2. [[state]]"closed"이면 InvalidStateError를 throw합니다.

  3. [[state]]"configured"로 설정합니다.

  4. 제어 메시지를 큐에 추가하여 config로 인코더를 설정합니다.

  5. 제어 메시지 큐를 처리합니다.

제어 메시지 실행은 인코더를 설정하기 위해 다음 단계를 수행합니다:

  1. [[message queue blocked]]true를 할당합니다.

  2. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. supportedconfigCheck Configuration Support 알고리즘을 실행한 결과로 설정합니다.

    2. supportedfalse이면, 작업을 큐에 추가하여 Close AudioEncoder 알고리즘을 NotSupportedError와 함께 실행하고, 이 단계를 중단합니다.

    3. 필요하다면 [[codec implementation]]config를 지원하는 구현체를 할당합니다.

    4. [[codec implementation]]config로 설정합니다.

    5. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. [[message queue blocked]]false를 할당합니다.

      2. 작업을 큐에 추가하여 제어 메시지 큐를 처리합니다.

  3. "processed"를 반환합니다.

encode(data)
제어 메시지를 큐에 추가하여 주어진 data를 인코딩합니다.

호출 시 다음 단계를 실행합니다:

  1. data[[Detached]] 내부 슬롯 값이 true이면 TypeError를 throw합니다.

  2. [[state]]"configured"가 아니면 InvalidStateError를 throw합니다.

  3. dataClonedataClone AudioData 알고리즘을 실행한 결과로 설정합니다.

  4. [[encodeQueueSize]]를 증가시킵니다.

  5. 제어 메시지를 큐에 추가하여 dataClone을 인코딩합니다.

  6. 제어 메시지 큐를 처리합니다.

제어 메시지 실행은 데이터를 인코딩하기 위해 다음 단계를 수행합니다:

  1. [[codec saturated]]true이면 "not processed"를 반환합니다.

  2. 데이터 인코딩으로 [[codec implementation]]saturated 상태가 되면, [[codec saturated]]true를 할당합니다.

  3. [[encodeQueueSize]]를 감소시키고, Schedule Dequeue Event 알고리즘을 실행합니다.

  4. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. [[codec implementation]]를 사용하여 dataClone이 설명하는 미디어 리소스를 인코딩 시도합니다.

    2. 인코딩 중 오류가 발생하면, 작업을 큐에 추가하여 Close AudioEncoder 알고리즘을 EncodingError와 함께 실행하고 반환합니다.

    3. [[codec saturated]]true이고 [[codec implementation]]이 더 이상 saturated 상태가 아니면, 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. [[codec saturated]]false를 할당합니다.

      2. 제어 메시지 큐를 처리합니다.

    4. encoded outputs[[codec implementation]]에서 방출된 인코딩된 오디오 데이터의 리스트로 설정합니다.

    5. encoded outputs가 비어 있지 않으면, 작업을 큐에 추가하여 Output EncodedAudioChunks 알고리즘을 encoded outputs로 실행합니다.

  5. "processed"를 반환합니다.

flush()
제어 메시지제어 메시지 큐에서 모두 완료하고, 모든 출력을 방출합니다.

호출 시 다음 단계를 실행합니다:

  1. [[state]]"configured"가 아니면 거부된 promiseInvalidStateError DOMException과 함께 반환합니다.

  2. promise를 새 Promise로 생성합니다.

  3. promise[[pending flush promises]]에 추가합니다.

  4. 제어 메시지를 큐에 추가하여 promise로 코덱을 flush합니다.

  5. 제어 메시지 큐를 처리합니다.

  6. promise를 반환합니다.

제어 메시지 실행promise와 함께 코덱을 flush하기 위해 다음 단계를 수행합니다:

  1. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. [[codec implementation]]에 모든 내부 대기 출력을 방출하도록 신호를 보냅니다.

    2. encoded outputs[[codec implementation]]에서 방출된 인코딩된 오디오 데이터의 리스트로 설정합니다.

    3. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. encoded outputs가 비어 있지 않으면, Output EncodedAudioChunks 알고리즘을 encoded outputs로 실행합니다.

      2. promise[[pending flush promises]]에서 제거합니다.

      3. promise를 resolve합니다.

  2. "processed"를 반환합니다.

reset()
모든 상태(설정 포함), 제어 메시지제어 메시지 큐의 모든 메시지, 모든 대기 콜백을 즉시 초기화합니다.

호출 시 Reset AudioEncoder 알고리즘을 AbortError DOMException과 함께 실행합니다.

close()
모든 대기 작업을 즉시 중단하고 시스템 리소스를 해제합니다. close는 최종적입니다.

호출 시 Close AudioEncoder 알고리즘을 AbortError DOMException과 함께 실행합니다.

isConfigSupported(config)
제공된 config가 User Agent에서 지원되는지 여부를 나타내는 promise를 반환합니다.

참고: 반환된 AudioEncoderSupport config에는 User Agent가 인식한 딕셔너리 멤버만 포함됩니다. 인식하지 못한 멤버는 무시됩니다. 작성자는 반환된 config와 제공한 config를 비교하여 인식하지 못한 멤버를 감지할 수 있습니다.

호출 시 다음 단계를 실행합니다:

  1. config유효한 AudioEncoderConfig가 아니면 거부된 promiseTypeError와 함께 반환합니다.

  2. p를 새 Promise로 생성합니다.

  3. checkSupportQueue를 새 병렬 큐로 시작한 결과로 설정합니다.

  4. checkSupportQueue에 다음 단계를 큐에 추가합니다:

    1. supportedconfigCheck Configuration Support 알고리즘을 실행한 결과로 설정합니다.

    2. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. encoderSupport를 새로 생성한 AudioEncoderSupport로 초기화합니다:

        1. configconfigClone Configuration 알고리즘을 실행한 결과로 설정합니다.

        2. supportedsupported로 설정합니다.

      2. pencoderSupport로 resolve합니다.

  5. p를 반환합니다.

5.6. 알고리즘

Schedule Dequeue Event
  1. [[dequeue event scheduled]] 값이 true이면 반환한다.

  2. [[dequeue event scheduled]]true를 할당한다.

  3. 작업을 큐에 추가하여 다음 단계를 실행한다:

    1. dequeue 라는 단순 이벤트를 this에 발행한다.

    2. [[dequeue event scheduled]]false를 할당한다.

Output EncodedAudioChunks (with outputs)
다음 단계를 실행한다:
  1. outputs의 각 output에 대해:

    1. chunkInit을 다음 키를 가진 EncodedAudioChunkInit 객체로 한다:

      1. dataoutput의 인코딩된 오디오 데이터를 담는다.

      2. typeoutputEncodedAudioChunkType 값을 담는다.

      3. timestampoutput과 연관된 AudioData의 timestamp 값을 담는다.

      4. durationoutput과 연관된 AudioData의 duration 값을 담는다.

    2. chunkchunkInit으로 생성한 새로운 EncodedAudioChunk 객체로 한다.

    3. chunkMetadata를 새로운 EncodedAudioChunkMetadata 객체로 한다.

    4. encoderConfig[[active encoder config]]로 한다.

    5. outputConfigoutput을 설명하는 새로운 AudioDecoderConfig 객체로 한다. outputConfig를 다음과 같이 초기화한다:

      1. encoderConfig.codec 값을 outputConfig.codec에 할당한다.

      2. encoderConfig.sampleRate 값을 outputConfig.sampleRate에 할당한다.

      3. encoderConfig.numberOfChannels 값을 outputConfig.numberOfChannels에 할당한다.

      4. outputConfig.description[[codec implementation]]에 의해 결정된 코덱 특화 바이트 시퀀스를 할당한다. User Agent는 제공된 description이 출력 디코딩에 올바르게 사용될 수 있도록 반드시 보장해야 한다.

        참고: description을 채우기 위한 코덱별 요구사항은 [WEBCODECS-CODEC-REGISTRY]에 기술되어 있다.

    6. outputConfig[[active output config]]동일한 딕셔너리가 아니라면:

      1. outputConfigchunkMetadata.decoderConfig에 할당한다.

      2. outputConfig[[active output config]]에 할당한다.

    7. [[output callback]]chunkchunkMetadata로 호출한다.

Reset AudioEncoder (with exception)
다음 단계를 실행한다:
  1. [[state]]"closed"이면 InvalidStateError를 throw한다.

  2. [[state]]"unconfigured"로 설정한다.

  3. [[active encoder config]]null로 설정한다.

  4. [[active output config]]null로 설정한다.

  5. [[codec implementation]] 에 이전 설정에 대한 출력 생성을 중단하도록 신호한다.

  6. 모든 control messages[[control message queue]]에서 제거한다.

  7. [[encodeQueueSize]] 가 0보다 크면:

    1. [[encodeQueueSize]] 를 0으로 설정한다.

    2. Schedule Dequeue Event 알고리즘을 실행한다.

  8. [[pending flush promises]]의 각 promise에 대해:

    1. promiseexception으로 reject한다.

    2. promise[[pending flush promises]]에서 제거한다.

Close AudioEncoder (with exception)
다음 단계를 실행한다:
  1. Reset AudioEncoder 알고리즘을 exception과 함께 실행한다.

  2. [[state]]"closed"로 설정한다.

  3. [[codec implementation]] 를 클리어하고 관련 시스템 리소스를 해제한다.

  4. exceptionAbortError DOMException이 아니라면, [[error callback]]exception과 함께 호출한다.

5.7. EncodedAudioChunkMetadata

다음 메타데이터 딕셔너리는 EncodedAudioChunkOutputCallback 에 의해 관련된 EncodedAudioChunk 와 함께 방출된다.
dictionary EncodedAudioChunkMetadata {
          AudioDecoderConfig decoderConfig;
        };
        
decoderConfig, of type AudioDecoderConfig

작성자는 사용할 수 있다 AudioDecoderConfig 를 사용하여 관련 EncodedAudioChunk를 디코드할 수 있다.

6. VideoEncoder 인터페이스

[Exposed=(Window,DedicatedWorker), SecureContext]
interface VideoEncoder : EventTarget {
  constructor(VideoEncoderInit init);

  readonly attribute CodecState state;
  readonly attribute unsigned long encodeQueueSize;
  attribute EventHandler ondequeue;

  undefined configure(VideoEncoderConfig config);
  undefined encode(VideoFrame frame, optional VideoEncoderEncodeOptions options = {});
  Promise<undefined> flush();
  undefined reset();
  undefined close();

  static Promise<VideoEncoderSupport> isConfigSupported(VideoEncoderConfig config);
};

dictionary VideoEncoderInit {
  required EncodedVideoChunkOutputCallback output;
  required WebCodecsErrorCallback error;
};

callback EncodedVideoChunkOutputCallback =
    undefined (EncodedVideoChunk chunk,
               optional EncodedVideoChunkMetadata metadata = {});

6.1. 내부 슬롯

[[control message queue]]

A of 제어 메시지 to be performed upon this 코덱 instance. See [[control message queue]].

[[message queue blocked]]

처리가 보류 중인 제어 메시지에 의해 [[control message queue]] 의 처리가 차단될 때를 나타내는 불리언입니다. See [[message queue blocked]].

[[codec implementation]]

User Agent가 제공하는 기본 인코더 구현입니다. See [[codec implementation]].

[[codec work queue]]

병렬 큐로, [[codec implementation]] 를 참조하는 병렬 단계들을 실행하는 데 사용됩니다. See [[codec work queue]].

[[codec saturated]]

[[codec implementation]] 이 추가 인코딩 작업을 수락할 수 없는 상태일 때를 나타내는 불리언입니다.

[[output callback]]

인코딩된 출력에 대해 생성 시 제공된 콜백입니다.

[[error callback]]

인코딩 오류에 대해 생성 시 제공된 콜백입니다.

[[active encoder config]]

현재 적용 중인 VideoEncoderConfig입니다.

[[active output config]]

가장 최근에 방출된 EncodedVideoChunk 를 디코드하는 방법을 설명하는 VideoDecoderConfig입니다.

[[state]]

VideoEncoder 의 현재 CodecState입니다.

[[encodeQueueSize]]

대기 중인 인코드 요청의 수입니다. 이 수는 기본 코덱이 새 입력을 받을 준비가 되면 감소합니다.

[[pending flush promises]]

flush() 호출로 반환된 해결되지 않은 프라미스들의 목록입니다.

[[dequeue event scheduled]]

이미 발행이 예약된 dequeue 이벤트가 있는지를 나타내는 불리언입니다. 이벤트 스팸을 피하는 데 사용됩니다.

[[active orientation]]

[[flip]][[rotation]] 을 나타내는 정수와 불리언 쌍으로, VideoFrameencode() 에 처음으로 제공된 후의 방향을 나타냅니다.

6.2. 생성자

VideoEncoder(init)
  1. e를 새로운 VideoEncoder 객체로 둔다.

  2. 새 큐[[control message queue]] 에 할당한다.

  3. false[[message queue blocked]] 에 할당한다.

  4. null[[codec implementation]] 에 할당한다.

  5. 새로운 병렬 큐 시작 결과를 [[codec work queue]] 에 할당한다.

  6. false[[codec saturated]] 에 할당한다.

  7. init.output을 [[output callback]] 에 할당한다.

  8. init.error를 [[error callback]] 에 할당한다.

  9. null[[active encoder config]] 에 할당한다.

  10. null[[active output config]] 에 할당한다.

  11. "unconfigured"[[state]] 에 할당한다.

  12. 0[[encodeQueueSize]] 에 할당한다.

  13. 새로운 리스트[[pending flush promises]] 에 할당한다.

  14. false[[dequeue event scheduled]] 에 할당한다.

  15. e를 반환한다.

6.3. 속성

state, of type CodecState, readonly

[[state]] 의 값을 반환합니다.

encodeQueueSize, of type unsigned long, readonly

[[encodeQueueSize]] 의 값을 반환합니다.

ondequeue, of type EventHandler

이벤트 핸들러 IDL 속성으로, 이벤트 타입은 dequeue 입니다.

6.4. 이벤트 요약

dequeue

VideoEncoderencodeQueueSize 가 감소했을 때 발행됩니다.

6.5. 메서드

configure(config)
제어 메시지를 큐에 추가하여 config에 따라 비디오 프레임 인코딩을 위해 인코더를 설정합니다.

참고: User Agent가 config를 지원하지 않으면 이 메서드는 NotSupportedError 를 발생시킵니다. 저자는 먼저 isConfigSupported() 를 호출하여 지원 여부를 확인하는 것이 권장됩니다. User Agent는 특정 코덱 타입이나 구성 전체를 반드시 지원할 필요는 없습니다.

호출 시 다음 단계를 실행합니다:

  1. config유효한 VideoEncoderConfig가 아니면 TypeError 를 던집니다.

  2. [[state]]"closed"이면 InvalidStateError 를 던집니다.

  3. [[state]]"configured"로 설정합니다.

  4. [[active orientation]]null으로 설정합니다.

  5. 제어 메시지를 큐에 추가하여 config으로 인코더를 설정합니다.

  6. 제어 메시지 큐 처리를 실행합니다.

제어 메시지 실행으로 인코더를 설정한다는 것은 다음 단계들을 수행함을 의미합니다:

  1. true[[message queue blocked]] 에 할당합니다.

  2. 다음 단계들을 [[codec work queue]] 에 등록합니다:

    1. supportedCheck Configuration Support 알고리즘을 config로 실행한 결과로 둡니다.

    2. supportedfalse이면, 작업을 큐에 추가하여 Close VideoEncoder 알고리즘을 NotSupportedError 와 함께 실행하고 이 단계들을 중단합니다.

    3. 필요한 경우 [[codec implementation]]config 를 지원하는 구현을 할당합니다.

    4. [[codec implementation]]config 로 구성합니다.

    5. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. false[[message queue blocked]] 에 할당합니다.

      2. 작업을 큐에 추가하여 제어 메시지 큐 처리를 실행합니다.

  3. "processed"를 반환합니다.

encode(frame, options)
제어 메시지를 큐에 추가하여 주어진 frame을 인코딩합니다.

호출 시 다음 단계를 실행합니다:

  1. frame[[Detached]] 내부 슬롯 값이 true이면 TypeError 를 던집니다.

  2. [[state]]"configured"가 아니면 InvalidStateError 를 던집니다.

  3. [[active orientation]]null이 아니고 frame[[rotation]][[flip]] 과 일치하지 않으면 DataError 를 던집니다.

  4. [[active orientation]]null이면, 이를 frame[[rotation]][[flip]] 값으로 설정합니다.

  5. frameCloneClone VideoFrame 알고리즘을 frame으로 실행한 결과로 둡니다.

  6. [[encodeQueueSize]] 를 증가시킵니다.

  7. 제어 메시지를 큐에 추가하여 frameClone을 인코딩하도록 합니다.

  8. 제어 메시지 큐 처리를 실행합니다.

제어 메시지 실행으로 프레임을 인코딩한다는 것은 다음 단계들을 수행함을 의미합니다:

  1. [[codec saturated]]true이면 "not processed" 를 반환합니다.

  2. 프레임 인코딩이 [[codec implementation]] 을 포화 상태로 만들 경우, true[[codec saturated]] 에 할당합니다.

  3. [[encodeQueueSize]] 를 감소시키고 Schedule Dequeue Event 알고리즘을 실행합니다.

  4. 다음 단계들을 [[codec work queue]] 에 등록합니다:

    1. [[codec implementation]] 을 사용하여 frameCloneoptions에 따라 인코딩하려 시도합니다.

    2. 인코딩 중 오류가 발생하면, 작업을 큐에 추가하여 Close VideoEncoder 알고리즘을 EncodingError 와 함께 실행하고 반환합니다.

    3. [[codec saturated]]true이고 [[codec implementation]] 이 더 이상 포화 상태가 아니게 되면, 작업을 큐에 추가하여 다음 단계를 수행합니다:

      1. false[[codec saturated]] 에 할당합니다.

      2. 제어 메시지 큐 처리를 실행합니다.

    4. encoded outputs리스트 로 하여 [[codec implementation]] 이 방출한 인코딩된 비디오 데이터 출력을 담습니다.

    5. encoded outputs가 비어있지 않으면, 작업을 큐에 추가하여 Output EncodedVideoChunks 알고리즘을 encoded outputs와 함께 실행합니다.

  5. "processed"를 반환합니다.

flush()
제어 메시지 큐의 모든 제어 메시지를 완료하고 모든 출력을 방출합니다.

호출 시 다음 단계를 실행합니다:

  1. [[state]]"configured"가 아니면 a promise rejected with InvalidStateError DOMException을 반환합니다.

  2. promise를 새 Promise로 둡니다.

  3. promise[[pending flush promises]] 에 추가합니다.

  4. 제어 메시지를 큐에 추가하여 promise와 함께 코덱을 flush하도록 합니다.

  5. 제어 메시지 큐 처리를 실행합니다.

  6. promise를 반환합니다.

제어 메시지 실행으로 코덱을 flush한다는 것은, promise와 함께 다음 단계들을 수행함을 의미합니다:

  1. 다음 단계들을 [[codec work queue]] 에 등록합니다:

    1. [[codec implementation]] 에 내부 대기 출력(internal pending outputs)을 방출하도록 신호합니다.

    2. encoded outputs리스트 로 하여 [[codec implementation]] 이 방출한 인코딩된 비디오 데이터 출력을 담습니다.

    3. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. encoded outputs가 비어있지 않으면, Output EncodedVideoChunks 알고리즘을 encoded outputs와 함께 실행합니다.

      2. promise[[pending flush promises]] 에서 제거합니다.

      3. promise를 resolve합니다.

  2. "processed"를 반환합니다.

reset()
구성(설정 포함), 제어 메시지 큐에 있는 제어 메시지, 및 모든 보류 중인 콜백을 즉시 재설정합니다.

호출 시 Reset VideoEncoder 알고리즘을 AbortError DOMException 와 함께 실행합니다.

close()
모든 대기 작업을 즉시 중단하고 시스템 리소스를 해제합니다. close는 최종적입니다.

호출 시 Close VideoEncoder 알고리즘을 AbortError DOMException 와 함께 실행합니다.

isConfigSupported(config)
제공된 config가 User Agent에서 지원되는지 여부를 나타내는 프라미스를 반환합니다.

참고: 반환되는 VideoEncoderSupportconfig 는 User Agent가 인식한 딕셔너리 멤버만 포함합니다. 인식되지 않은 딕셔너리 멤버는 무시됩니다. 저자는 제공한 config와 반환된 config 를 비교하여 인식되지 않은 멤버를 감지할 수 있습니다.

호출 시 다음 단계를 실행합니다:

  1. config유효한 VideoEncoderConfig가 아니면 a promise rejected with TypeError 를 반환합니다.

  2. p를 새 Promise로 둡니다.

  3. checkSupportQueue를 새 병렬 큐 시작 결과로 둡니다.

  4. checkSupportQueue에 다음 단계들을 등록합니다:

    1. supportedCheck Configuration Support 알고리즘을 config로 실행한 결과로 둡니다.

    2. 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. encoderSupport를 새로 구성된 VideoEncoderSupport 로 하여 다음과 같이 초기화합니다:

        1. configClone Configuration 알고리즘을 config로 실행한 결과를 설정합니다.

        2. supportedsupported 값으로 설정합니다.

    3. pencoderSupport로 resolve합니다.

  5. p를 반환합니다.

6.6. 알고리즘

Schedule Dequeue Event
  1. [[dequeue event scheduled]]true이면 반환한다.

  2. true[[dequeue event scheduled]] 에 할당한다.

  3. Queue a task를 사용해 다음 단계를 실행한다:

    1. dequeue 라는 단순 이벤트를 this에 발행한다.

    2. false[[dequeue event scheduled]] 에 할당한다.

Output EncodedVideoChunks (with outputs)
다음 단계를 실행한다:
  1. outputs의 각 output에 대해:

    1. chunkInit을 다음 키를 가진 EncodedVideoChunkInit 객체로 한다:

      1. dataoutput의 인코딩된 비디오 데이터를 담는다.

      2. typeoutputEncodedVideoChunkType 값을 담는다.

      3. timestampoutput과 연관된 VideoFrame[[timestamp]] 값을 담는다.

      4. durationoutput과 연관된 VideoFrame[[duration]] 값을 담는다.

    2. chunkchunkInit으로 생성한 새로운 EncodedVideoChunk 객체로 한다.

    3. chunkMetadata를 새로운 EncodedVideoChunkMetadata 객체로 한다.

    4. encoderConfig[[active encoder config]] 로 둔다.

    5. outputConfigoutput을 설명하는 VideoDecoderConfig 로 한다. outputConfig를 다음과 같이 초기화한다:

      1. encoderConfig.codecoutputConfig.codec에 할당한다.

      2. encoderConfig.widthoutputConfig.codedWidth에 할당한다.

      3. encoderConfig.heightoutputConfig.codedHeight에 할당한다.

      4. encoderConfig.displayWidthoutputConfig.displayAspectWidth에 할당한다.

      5. encoderConfig.displayHeightoutputConfig.displayAspectHeight에 할당한다.

      6. [[rotation]]output과 연관된 VideoFrame 에서 가져와 outputConfig.rotation에 할당한다.

      7. [[flip]]output과 연관된 VideoFrame 에서 가져와 outputConfig.flip에 할당한다.

      8. outputConfig의 나머지 키들을 [[codec implementation]] 에 의해 결정되는 대로 할당한다. User Agent는 outputConfigoutput을 올바르게 디코드하는 데 충분히 기술되도록 반드시 보장해야 한다.

        참고: description 을 채우기 위한 코덱별 요구사항은 [WEBCODECS-CODEC-REGISTRY]에 설명되어 있다.

    6. outputConfig[[active output config]]동일한 딕셔너리가 아니라면:

      1. outputConfigchunkMetadata.decoderConfig 에 할당한다.

      2. outputConfig[[active output config]] 에 할당한다.

    7. encoderConfig.scalabilityMode 가 여러 temporal layers를 설명하면:

      1. svc를 새로운 SvcOutputMetadata 인스턴스로 한다.

      2. temporal_layer_idoutput에 대한 0 기반 인덱스로 둔다.

      3. temporal_layer_idsvc.temporalLayerId 에 할당한다.

      4. svcchunkMetadata.svc 에 할당한다.

    8. encoderConfig.alpha"keep"로 설정되어 있으면:

      1. alphaSideDataoutput에 포함된 인코딩된 알파 데이터로 둔다.

      2. alphaSideDatachunkMetadata.alphaSideData 에 할당한다.

    9. [[output callback]]chunkchunkMetadata로 호출한다.

Reset VideoEncoder (with exception)
다음 단계를 실행한다:
  1. [[state]]"closed"이면 InvalidStateError 를 throw 한다.

  2. [[state]]"unconfigured"로 설정한다.

  3. [[active encoder config]]null로 설정한다.

  4. [[active output config]]null로 설정한다.

  5. [[codec implementation]] 에 이전 구성에 대한 출력 생성을 중단하도록 신호한다.

  6. 모든 control messages[[control message queue]] 에서 제거한다.

  7. [[encodeQueueSize]] 가 0보다 크면:

    1. [[encodeQueueSize]] 를 0으로 설정한다.

    2. Schedule Dequeue Event 알고리즘을 실행한다.

  8. [[pending flush promises]] 의 각 promise에 대해:

    1. promiseexception으로 reject 한다.

    2. promise[[pending flush promises]] 에서 제거한다.

Close VideoEncoder (with exception)
다음 단계를 실행한다:
  1. Reset VideoEncoder 알고리즘을 exception과 함께 실행한다.

  2. [[state]]"closed"로 설정한다.

  3. [[codec implementation]] 를 클리어하고 관련된 시스템 리소스를 해제한다.

  4. exceptionAbortError 또는 DOMException이 아니면, [[error callback]]exception과 함께 호출한다.

6.7. EncodedVideoChunkMetadata

다음 메타데이터 딕셔너리는 EncodedVideoChunkOutputCallback 에 의해 관련된 EncodedVideoChunk 와 함께 방출된다.
dictionary EncodedVideoChunkMetadata {
          VideoDecoderConfig decoderConfig;
          SvcOutputMetadata svc;
          BufferSource alphaSideData;
        };
        
        dictionary SvcOutputMetadata {
          unsigned long temporalLayerId;
        };
        
decoderConfig, of type VideoDecoderConfig

작성자는 관련 EncodedVideoChunk 를 디코드하기 위해 사용할 수 있는 VideoDecoderConfig 를 사용할 수 있다.

svc, of type SvcOutputMetadata

구성된 scalabilityMode 에 관해 해당 EncodedVideoChunk 을 설명하는 메타데이터 모음이다.

alphaSideData, of type BufferSource

해당 EncodedVideoChunk 의 추가 알파 채널 데이터를 포함하는 BufferSource이다.

temporalLayerId, of type unsigned long

관련 EncodedVideoChunk 에 대한 temporal layer를 식별하는 숫자이다.

7. 구성(Configurations)

7.1. 구성 지원 확인 (with config)

다음 단계를 실행한다:
  1. config.codec에 있는 codec string유효한 codec string이 아니거나 User Agent가 인식하지 못하면, false를 반환한다.

  2. configAudioDecoderConfig 또는 VideoDecoderConfig 이고, User Agent가 config.codec에 지정된(존재하는 경우) 정확한 프로필, 레벨, 제약 비트를 디코드할 수 있는 코덱을 제공할 수 없으면, false를 반환한다.

  3. configAudioEncoderConfig 또는 VideoEncoderConfig 인 경우:

    1. config.codec의 codec string이 프로필을 포함하고 있으며 User Agent가 해당 프로필을 인코딩할 수 있는 코덱을 제공할 수 없으면, false를 반환한다.

    2. config.codec의 codec string이 레벨을 포함하고 있으며 User Agent가 그 레벨 이하로 인코딩할 수 있는 코덱을 제공할 수 없으면, false를 반환한다.

    3. config.codec의 codec string이 제약 비트를 포함하고 있으며 User Agent가 그에 상응하는 제약을 가진 인코딩 비트스트림을 생성할 수 있는 코덱을 제공할 수 없으면, false를 반환한다.

  4. User Agent가 config의 모든 항목을 지원할 수 있고, 포함되지 않은 키에 대한 적용 가능한 기본값까지 포함하여 지원할 수 있으면, true를 반환한다.

    참고: AudioDecoderConfig, VideoDecoderConfig, AudioEncoderConfig, 및 VideoEncoderConfig 는 각각 해당 구성 항목과 기본값을 정의한다.

    참고: 하드웨어 변경(예: 외장 GPU 분리)이나 필수 하드웨어 자원의 고갈로 인해 특정 구성에 대한 지원이 동적으로 변경될 수 있다. User Agent는 쿼리 시점의 사용 가능한 자원에 따라 최선의 노력을 기반으로 지원을 설명한다.

  5. 그 외의 경우 false를 반환한다.

7.2. 구성 복제 (with config)

참고: 이 알고리즘은 User Agent가 딕셔너리 타입의 일부로 인식하는 딕셔너리 멤버만 복사한다.

다음 단계를 실행한다:

  1. dictTypeconfig의 딕셔너리 타입으로 둔다.

  2. clonedictType의 새로운 빈 인스턴스로 둔다.

  3. dictType에 정의된 각 딕셔너리 멤버 m에 대해:

    1. mconfig에 존재하지 않으면 continue한다.

    2. 만약 config[m]가 중첩된 딕셔너리이면, clone[m]config[m]에 대해 재귀적으로 Clone Configuration 알고리즘을 실행한 결과로 설정한다.

    3. 그렇지 않으면, config[m]의 복사본을 clone[m]에 할당한다.

참고: 이는 "deep-copy"를 구현한다. 이러한 구성 객체들은 비동기 작업의 입력으로 자주 사용된다. 복사하면 원본 객체를 작업이 진행되는 동안 수정해도 작업 결과에 영향을 주지 않는다.

7.3. 구성 지원 신호(Signalling Configuration Support)

7.3.1. AudioDecoderSupport

dictionary AudioDecoderSupport {
          boolean supported;
          AudioDecoderConfig config;
        };
        
supported, of type boolean
해당 config이 User Agent에 의해 지원되는지 여부를 나타내는 불리언입니다.
config, of type AudioDecoderConfig
User Agent가 AudioDecoderConfig를 사용하여 supported의 값을 결정하는 데 사용하는 구성입니다。

7.3.2. VideoDecoderSupport

dictionary VideoDecoderSupport {
          boolean supported;
          VideoDecoderConfig config;
        };
        
supported, of type boolean
해당 config이 User Agent에 의해 지원되는지 여부를 나타내는 불리언입니다。
config, of type VideoDecoderConfig
User Agent가 VideoDecoderConfig를 사용하여 supported의 값을 결정하는 데 사용하는 구성입니다。

7.3.3. AudioEncoderSupport

dictionary AudioEncoderSupport {
          boolean supported;
          AudioEncoderConfig config;
        };
        
supported, of type boolean
해당 config이 User Agent에 의해 지원되는지 여부를 나타내는 불리언입니다。
config, of type AudioEncoderConfig
User Agent가 AudioEncoderConfig를 사용하여 supported의 값을 결정하는 데 사용하는 구성입니다。

7.3.4. VideoEncoderSupport

dictionary VideoEncoderSupport {
          boolean supported;
          VideoEncoderConfig config;
        };
        
supported, of type boolean
해당 config이 User Agent에 의해 지원되는지 여부를 나타내는 불리언입니다。
config, of type VideoEncoderConfig
User Agent가 VideoEncoderConfig를 사용하여 supported의 값을 결정하는 데 사용하는 구성입니다。

7.4. 코덱 문자열

코덱 문자열은 인코딩 또는 디코딩에 사용될 특정 코덱 형식을 설명합니다.

A valid codec string MUST meet the following conditions.

  1. 관련 코덱 명세에 따라 유효해야 합니다(아래 예시 참조).

  2. 단일 코덱을 설명해야 합니다.

  3. 이러한 개념을 정의하는 코덱의 경우, 코덱 프로파일, 레벨 및 제약 비트에 대해 모호함이 없어야 합니다.

NOTE: 다른 미디어 명세에서는 코덱 문자열이 전통적으로 MIME type의 "codecs=" 매개변수와 함께 사용되었습니다 (isTypeSupported(), canPlayType()) [RFC6381]. 이 명세에서는 인코딩된 미디어가 컨테이너화되어 있지 않으므로, codecs 매개변수의 값만 허용됩니다.

NOTE: 레벨 및 제약 비트를 정의하는 코덱의 인코더는 이들 매개변수에 대해 유연성을 가질 수 있으나, 요청한 것보다 더 높은 레벨이거나 덜 제약된 비트스트림을 생성하지는 않습니다.

코덱 문자열의 형식 및 의미는 [WEBCODECS-CODEC-REGISTRY]에 나열된 코덱 등록에 의해 정의됩니다. 준수하는 구현체는 어떤 조합의 코덱 등록이든(또는 전혀 없음) 지원할 수 있습니다.

7.5. AudioDecoderConfig

dictionary AudioDecoderConfig {
  required DOMString codec;
  [EnforceRange] required unsigned long sampleRate;
  [EnforceRange] required unsigned long numberOfChannels;
  AllowSharedBufferSource description;
};

AudioDecoderConfig유효한 AudioDecoderConfig인지 확인하려면 다음 단계를 실행합니다:

  1. 만약 codec선행 및 후행 ASCII 공백 제거 후 비어 있으면, false를 반환합니다.

  2. 만약 description이 [detached]이면, false를 반환합니다.

  3. true를 반환합니다.

codec, 형식: DOMString
config.codec에 있는 코덱 문자열로, 해당 코덱을 설명합니다.
sampleRate, 형식: unsigned long
초당 프레임 샘플 수입니다.
numberOfChannels, 형식: unsigned long
오디오 채널 수입니다.
description, 형식: AllowSharedBufferSource
코덱 특화 바이트의 시퀀스로, 일반적으로 extradata라고 불립니다.

참고: [WEBCODECS-CODEC-REGISTRY]의 등록 항목들은 제공된 codec에 대응하여 이 시퀀스를 어떻게/여부를 채워야 하는지를 설명합니다.

7.6. VideoDecoderConfig

dictionary VideoDecoderConfig {
  required DOMString codec;
  AllowSharedBufferSource description;
  [EnforceRange] unsigned long codedWidth;
  [EnforceRange] unsigned long codedHeight;
  [EnforceRange] unsigned long displayAspectWidth;
  [EnforceRange] unsigned long displayAspectHeight;
  VideoColorSpaceInit colorSpace;
  HardwareAcceleration hardwareAcceleration = "no-preference";
  boolean optimizeForLatency;
  double rotation = 0;
  boolean flip = false;
};

VideoDecoderConfig유효한 VideoDecoderConfig인지 확인하려면 다음 단계를 실행합니다:

  1. 만약 codec선행 및 후행 ASCII 공백 제거 후에 비어 있으면, false를 반환합니다.

  2. 만약 codedWidth 또는 codedHeight 중 하나만 제공되고 다른 하나가 제공되지 않았다면, false를 반환합니다.

  3. 만약 codedWidth = 0 이거나 codedHeight = 0 이면, false를 반환합니다.

  4. 만약 displayAspectWidth 또는 displayAspectHeight 중 하나만 제공되고 다른 하나가 제공되지 않았다면, false를 반환합니다.

  5. 만약 displayAspectWidth = 0 이거나 displayAspectHeight = 0 이면, false를 반환합니다.

  6. 만약 description이 [detached]이면, false를 반환합니다.

  7. true를 반환합니다.

codec, 형식: DOMString
해당 코덱을 설명하는 코덱 문자열을 포함합니다.
description, 형식: AllowSharedBufferSource
코덱 특화 바이트의 시퀀스로, 일반적으로 extradata라 불립니다.

참고: [WEBCODECS-CODEC-REGISTRY]의 등록 항목들은 제공된 codec에 대응하여 이 시퀀스를 어떻게/여부를 채워야 하는지를 설명합니다.

codedWidth, 형식: unsigned long
VideoFrame의 너비(픽셀 단위). 보이지 않는 패딩을 포함할 수 있으며 비율 조정을 고려하기 전의 값입니다.
codedHeight, 형식: unsigned long
VideoFrame의 높이(픽셀 단위). 보이지 않는 패딩을 포함할 수 있으며 비율 조정을 고려하기 전의 값입니다.

참고: codedWidthcodedHeight[[codec implementation]] 선택 시 사용됩니다.

displayAspectWidth, 형식: unsigned long
표시될 때 VideoFrame의 가로 종횡비 치수입니다.
displayAspectHeight, 형식: unsigned long
표시될 때 VideoFrame의 세로 종횡비 치수입니다.

참고: displayWidthdisplayHeightdisplayAspectWidthdisplayAspectHeight와 다를 수 있으나, 프레임 생성 시 적용되는 스케일링 후에는 동일한 비율을 가집니다.

colorSpace, 형식: VideoColorSpaceInit
VideoFrame에 연결된 colorSpace을 구성합니다. colorSpace가 존재하면, 제공된 값은 비트스트림의 인밴드 값을 오버라이드합니다.
hardwareAcceleration, 형식: HardwareAcceleration, 기본값 "no-preference"
이 코덱에 대한 하드웨어 가속을 구성하는 힌트입니다. 자세한 내용은 HardwareAcceleration를 참조하세요.
optimizeForLatency, 형식: boolean
선택된 디코더는 SHOULD 출력이 생성되기 전에 디코드해야 하는 EncodedVideoChunk 수를 최소화하도록 구성되어야 합니다.

참고: User Agent 및 하드웨어 제한 외에, 일부 코덱 비트스트림은 출력을 생성하기 위해 최소 입력 수를 필요로 합니다.

rotation, 형식: double, 기본값 0
디코드된 프레임의 rotation 속성을 설정합니다.
flip, 형식: boolean, 기본값 false
디코드된 프레임의 flip 속성을 설정합니다.

7.7. AudioEncoderConfig

dictionary AudioEncoderConfig {
required DOMString codec;
[EnforceRange] required unsigned long sampleRate;
[EnforceRange] required unsigned long numberOfChannels;
[EnforceRange] unsigned long long bitrate;
BitrateMode bitrateMode = "variable";
};

참고: AudioEncoderConfig에 대한 코덱별 확장은 [WEBCODECS-CODEC-REGISTRY]의 등록 항목에 설명되어 있습니다.

AudioEncoderConfig유효한 AudioEncoderConfig인지 확인하려면 다음 단계를 실행합니다:

  1. 만약 codec선행 및 후행 ASCII 공백 제거 후에 비어 있으면, false를 반환합니다.

  2. 만약 AudioEncoderConfig에 코덱별 확장이 있고, 해당 확장에 대해 [WEBCODECS-CODEC-REGISTRY]의 등록이 유효성 검사를 위한 절차를 정의하면, 그 절차를 실행한 결과를 반환합니다.

  3. 만약 sampleRate 또는 numberOfChannels가 0이면, false를 반환합니다.

  4. true를 반환합니다.

codec, 형식: DOMString
해당 코덱을 설명하는 코덱 문자열을 포함합니다.
sampleRate, 형식: unsigned long
초당 프레임 샘플 수입니다.
numberOfChannels, 형식: unsigned long
오디오 채널 수입니다.
bitrate, 형식: unsigned long long
인코딩된 오디오의 평균 비트레이트(초당 비트 단위)입니다.
bitrateMode, 형식: BitrateMode, 기본값 "variable"
인코더가 constant 또는 variable 비트레이트를 사용하도록 구성합니다.

참고: 모든 오디오 코덱이 특정 BitrateMode를 지원하는 것은 아닙니다. Authors는 isConfigSupported()를 호출하여 지원 여부를 확인하는 것이 권장됩니다.

7.8. VideoEncoderConfig

dictionary VideoEncoderConfig {
  required DOMString codec;
  [EnforceRange] required unsigned long width;
  [EnforceRange] required unsigned long height;
  [EnforceRange] unsigned long displayWidth;
  [EnforceRange] unsigned long displayHeight;
  [EnforceRange] unsigned long long bitrate;
  double framerate;
  HardwareAcceleration hardwareAcceleration = "no-preference";
  AlphaOption alpha = "discard";
  DOMString scalabilityMode;
  VideoEncoderBitrateMode bitrateMode = "variable";
  LatencyMode latencyMode = "quality";
  DOMString contentHint;
};

NOTE: VideoEncoderConfig에 대한 코덱별 확장은 해당 항목들의 [WEBCODECS-CODEC-REGISTRY] 등록에서 설명됩니다.

다음 VideoEncoderConfig유효한 VideoEncoderConfig인지 확인하려면, 다음 단계를 실행합니다:

  1. codec선행 및 후행 ASCII 공백 제거 후 비어 있으면, false를 반환합니다.

  2. width = 0 이거나 height = 0이면, false를 반환합니다.

  3. displayWidth = 0 이거나 displayHeight = 0이면, false를 반환합니다.

  4. true를 반환합니다.

codec, of type DOMString
해당 코덱을 설명하는 코덱 문자열config.codec에 포함합니다.
width, of type unsigned long
출력 EncodedVideoChunk의 인코딩된 너비(픽셀 단위)로, 표시 종횡비 조정이 적용되기 이전의 값입니다.

인코더는 MUST 해당 값과 다른 VideoFrame[[visible width]]을 스케일해야 합니다.

height, of type unsigned long
출력 EncodedVideoChunk의 인코딩된 높이(픽셀 단위)로, 표시 종횡비 조정이 적용되기 이전의 값입니다.

인코더는 MUST 해당 값과 다른 VideoFrame[[visible height]]을 스케일해야 합니다.

displayWidth, of type unsigned long
출력 EncodedVideoChunk의 의도된 표시 너비(픽셀 단위)입니다. 명시되지 않으면 width가 기본값입니다.
displayHeight, of type unsigned long
출력 EncodedVideoChunk의 의도된 표시 높이(픽셀 단위)입니다. 명시되지 않으면 width가 기본값입니다。
NOTE: displayWidthdisplayHeightwidthheight와 다르면, 이는 디코딩 이후 청크가 최종 표시 종횡비에 맞게 스케일되어야 함을 나타냅니다.

많은 코덱에서는 이것이 단순히 전달되는 정보에 불과하지만, 일부 코덱은 때때로 비트스트림에 표시 크기를 포함할 수 있습니다.

bitrate, of type unsigned long long
인코딩된 비디오의 평균 비트레이트(초당 비트 단위)입니다.

NOTE: 작성자는 제어를 위한 정보 제공을 위해 framerate를 함께 제공하는 것이 권장됩니다.

framerate, of type double
알려진 경우 초당 프레임 수로 기대되는 프레임률입니다. 이 값은 프레임의 timestamp와 함께, 인코더가 각 인코딩된 프레임에 대한 최적의 바이트 길이를 계산하는 데 SHOULD 사용되어야 합니다. 또한, latencyModerealtime으로 설정된 경우 출력 청크를 생성하기 위한 목표 기한으로 간주되어야 합니다.
hardwareAcceleration, of type HardwareAcceleration, defaulting to "no-preference"
이 코덱에 대한 하드웨어 가속을 구성하는 힌트입니다. 자세한 내용은 HardwareAcceleration을 참조하세요.
alpha, of type AlphaOption, defaulting to "discard"
입력 VideoFrame의 알파 컴포넌트를 인코딩 전에 유지할지 버릴지를 SHOULD 지정합니다. 만약 alphadiscard이면, 알파 데이터는 해당 VideoFrame[[format]]와 관계없이 항상 삭제됩니다.
scalabilityMode, of type DOMString
[WebRTC-SVC]에서 정의된 인코딩 확장성 모드 식별자입니다.
bitrateMode, of type VideoEncoderBitrateMode, defaulting to "variable"
인코딩 시 VideoEncoderBitrateMode로 정의된 레이트 컨트롤 모드 중 하나를 사용하도록 구성합니다。

NOTE: 두 모드 중 어느 쪽이든 비트레이트 변동의 정확한 정도는 구현체에 따라 달라집니다.

latencyMode, of type LatencyMode, defaulting to "quality"
이 코덱에 대한 지연 관련 동작을 구성합니다. LatencyMode를 참조하세요。
contentHint, of type DOMString
비디오 콘텐츠 힌트로, [mst-content-hint]에서 정의된 것입니다。

User Agent는 이 힌트를 사용하여 들어오는 VideoFrame에 대한 기대치를 설정하고 인코딩 품질을 개선할 수 있습니다. 이 힌트를 사용할 경우:

  • User Agent는 인코더를 구성할 때 다른 명시적으로 설정된 인코딩 옵션(코덱별 옵션 여부와 관계없이)을 반드시 존중해야 합니다.

  • User Agent는 해당 비디오 콘텐츠 힌트가 정의한 목표에 따라 인코딩 품질을 향상시키기 위해 추가 구성 옵션을 최선의 노력으로 사용해야 합니다.

NOTE: 일부 인코더 옵션은 구현체별로 다르며, contentHint과 해당 옵션 간의 매핑을 규정할 수 없는 경우가 있습니다.

User Agent는 이 content hint를 지원하지 않는다고 해서 구성을 거부해서는 안 됩니다. 자세한 내용은 isConfigSupported()를 참조하세요。

7.9. 하드웨어 가속

enum HardwareAcceleration {
  "no-preference",
  "prefer-hardware",
  "prefer-software",
};

지원되는 경우, 하드웨어 가속은 인코딩 또는 디코딩을 특수 하드웨어에 오프로드합니다. prefer-hardwareprefer-software 는 힌트입니다. User Agent는 가능한 경우 이러한 값을 SHOULD 준수해야 하지만, User Agent는 어떤 이유로든 일부 또는 모든 상황에서 이러한 값을 무시할 수 있습니다.

지문 채취(fingerprinting)를 방지하기 위해, 만약 User Agent가 [media-capabilities]를 구현한다면, User Agent는 주어진 HardwareAcceleration 선호도의 거부 또는 수락이 User Agent 자체에 본래 존재하며 [media-capabilities]로 드러나는 정보 외에 추가 정보를 드러내지 않도록 보장해야 합니다. 만약 User Agent가 지문 채취 문제로 인해 [media-capabilities]를 구현하지 않는다면, 그들은 HardwareAcceleration 선호도를 SHOULD 무시해야 합니다.

참고: User Agent가 prefer-hardware 또는 prefer-software 를 무시할 수 있는 좋은 사례는 사용자 프라이버시와 관련된 이유이거나 User Agent가 대체 설정이 최종 사용자에게 더 유리하다고 판단하는 상황입니다.

대부분의 작성자는 기본값인 no-preference를 사용하는 것이 가장 적합합니다. 이는 User Agent가 시스템 및 구성에 대한 지식을 바탕으로 최적화할 수 있는 유연성을 제공합니다. 일반적인 전략은 더 높은 해상도에서 하드웨어 가속을 우선으로 하고, 하드웨어 가속이 실패할 경우 소프트웨어 코덱으로 폴백하는 것입니다.

작성자는 하드웨어 가속 선호도를 설정할 때 트레이드오프를 신중히 고려하는 것이 권장됩니다. 정확한 트레이드오프는 장치별로 다르겠지만, 작성자는 일반적으로 다음과 같은 사항을 기대할 수 있습니다:

이러한 트레이드오프를 고려할 때, 작성자가 자체 소프트웨어 기반 폴백을 WebAssembly로 제공하려는 경우 "prefer-hardware"를 사용하는 것이 좋은 예입니다.

반대로, 작성자가 하드웨어 가속과 일반적으로 관련된 더 높은 시작 지연이나 감소된 강건성에 특히 민감한 경우에는 "prefer-software"를 사용하는 것이 좋은 예가 됩니다.

no-preference
이는 User Agent가 호환되고 사용 가능한 경우 하드웨어 가속을 사용할 MAY 있음을 나타냅니다.
prefer-software
이는 User Agent가 소프트웨어 코덱 구현을 우선해야 함을 나타냅니다(SHOULD). User Agent는 어떤 이유로든 이 값을 무시할 수 있습니다.

참고: 이 설정은 가속되지 않은 코덱이 없거나 코덱 구성의 다른 측면과 호환되지 않는 플랫폼에서는 구성이 지원되지 않게 만들 수 있습니다.

prefer-hardware
이는 User Agent가 하드웨어 가속을 우선해야 함을 나타냅니다(SHOULD). User Agent는 어떤 이유로든 이 값을 무시할 수 있습니다.

참고: 이 설정은 가속된 코덱이 없거나 코덱 구성의 다른 측면과 호환되지 않는 플랫폼에서는 구성이 지원되지 않게 만들 수 있습니다.

7.10. 알파 옵션

enum AlphaOption {
  "keep",
  "discard",
};

다양한 작업에서 알파 채널을 처리할 때 사용자 에이전트가 어떻게 동작해야 하는지를 설명합니다. SHOULD

keep
해당 프레임에 알파 채널 데이터가 존재하는 경우, 사용자 에이전트가 SHOULD VideoFrame의 알파 채널 데이터를 보존해야 함을 나타냅니다.
discard
이는 사용자 에이전트가 VideoFrame의 알파 채널 데이터를 무시하거나 제거해야 함을 나타냅니다(SHOULD).

7.11. 지연 모드

enum LatencyMode {
  "quality",
  "realtime"
};
quality

이는 User Agent가 인코딩 품질을 최적화해야 함을 나타냅니다(SHOULD). 이 모드에서는:

  • User Agent는 품질 향상을 위해 인코딩 지연을 증가시킬 MAY 있습니다.

  • User Agent는 목표 bitrate 및/또는 framerate를 달성하기 위해 프레임을 드롭해서는 안 됩니다(MUST).

  • framerate 은 인코딩된 청크를 출력하기 위한 목표 데드라인으로 사용되어서는 안 됩니다(SHOULD).

realtime

이는 User Agent가 낮은 지연을 최적화해야 함을 나타냅니다(SHOULD). 이 모드에서는:

  • User Agent는 지연 개선을 위해 품질을 희생할 MAY 있습니다.

  • User Agent는 목표 bitrate 및/또는 framerate를 달성하기 위해 프레임을 드롭할 MAY 있습니다.

  • framerate 은 인코딩된 청크를 출력하기 위한 목표 데드라인으로 사용되어야 합니다(SHOULD).

7.12. 구성 동등성

두 딕셔너리는 동일한 키와 값을 포함하고 있으면 동일한 딕셔너리로 간주됩니다. 중첩된 딕셔너리의 경우 이 정의를 재귀적으로 적용합니다.

7.13. VideoEncoderEncodeOptions

dictionary VideoEncoderEncodeOptions {
  boolean keyFrame = false;
};

참고: VideoEncoderEncodeOptions 에 대한 코덱별 확장은 [WEBCODECS-CODEC-REGISTRY]에 등록된 설명에서 다룹니다.

keyFrame, of type boolean, defaulting to false
값이 true이면 해당 프레임은 키 프레임으로 인코딩되어야 함을 나타냅니다(MUST). 값이 false이면 User Agent는 해당 프레임을 키 프레임으로 인코딩할지 여부를 결정할 유연성이 있음을 나타냅니다(key frame로 인코딩).

7.14. VideoEncoderBitrateMode

enum VideoEncoderBitrateMode {
  "constant",
  "variable",
  "quantizer"
};
constant
고정 비트레이트로 인코딩합니다. See bitrate.
variable
가변 비트레이트를 사용하여 인코딩합니다. 복잡한 신호에는 더 많은 공간을, 덜 복잡한 신호에는 더 적은 공간을 할당할 수 있습니다. See bitrate.
quantizer
코덱별 확장의 VideoEncoderEncodeOptions에 있는 각 비디오 프레임에 대해 지정된 양자화기(quantizer)를 사용하여 인코딩합니다.

7.15. 코덱 상태

enum CodecState {
  "unconfigured",
  "configured",
  "closed"
};
unconfigured
코덱이 인코딩이나 디코딩을 위해 구성되지 않은 상태입니다.
configured
유효한 구성이 제공되었습니다. 코덱은 인코딩 또는 디코딩할 준비가 되었습니다.
closed
코덱은 더 이상 사용할 수 없으며 기본 시스템 리소스가 해제되었습니다.

7.16. WebCodecsErrorCallback

callback WebCodecsErrorCallback = undefined(DOMException error);

8. 인코딩된 미디어 인터페이스 (청크)

이러한 인터페이스는 인코딩된 미디어의 청크를 나타냅니다.

8.1. EncodedAudioChunk 인터페이스

[Exposed=(Window,DedicatedWorker), Serializable]
interface EncodedAudioChunk {
  constructor(EncodedAudioChunkInit init);
  readonly attribute EncodedAudioChunkType type;
  readonly attribute long long timestamp;          // microseconds
  readonly attribute unsigned long long? duration; // microseconds
  readonly attribute unsigned long byteLength;

  undefined copyTo(AllowSharedBufferSource destination);
};

dictionary EncodedAudioChunkInit {
  required EncodedAudioChunkType type;
  [EnforceRange] required long long timestamp;    // microseconds
  [EnforceRange] unsigned long long duration;     // microseconds
  required AllowSharedBufferSource data;
  sequence<ArrayBuffer> transfer = [];
};

enum EncodedAudioChunkType {
    "key",
    "delta",
};

8.1.1. 내부 슬롯

[[internal data]]

인코딩된 청크 데이터를 나타내는 바이트 배열입니다.

[[type]]

해당 청크가 키 청크인지 여부를 설명합니다.

[[timestamp]]

프레젠테이션 타임스탬프이며, 마이크로초 단위로 주어집니다.

[[duration]]

프레젠테이션 지속 시간이며, 마이크로초 단위로 주어집니다.

[[byte length]]

[[internal data]]의 바이트 길이입니다.

8.1.2. 생성자

EncodedAudioChunk(init)
  1. If init.transfer contains more than one reference to the same ArrayBuffer, then throw a DataCloneError DOMException.

  2. For each transferable in init.transfer:

    1. If [[Detached]] internal slot is true, then throw a DataCloneError DOMException.

  3. Let chunk be a new EncodedAudioChunk object, initialized as follows

    1. Assign init.type to [[type]].

    2. Assign init.timestamp to [[timestamp]].

    3. If init.duration exists, assign it to [[duration]], or assign null otherwise.

    4. Assign init.data.byteLength to [[byte length]];

    5. If init.transfer contains an ArrayBuffer referenced by init.data the User Agent MAY choose to:

      1. Let resource be a new media resource referencing sample data in init.data.

    6. Otherwise:

      1. Assign a copy of init.data to [[internal data]].

  4. For each transferable in init.transfer:

    1. Perform DetachArrayBuffer on transferable

  5. Return chunk.

8.1.3. 속성

type, of type EncodedAudioChunkType, readonly

[[type]]의 값을 반환합니다.

timestamp, of type long long, readonly

[[timestamp]]의 값을 반환합니다.

duration, of type unsigned long long, readonly, nullable

[[duration]]의 값을 반환합니다.

byteLength, of type unsigned long, readonly

[[byte length]]의 값을 반환합니다.

8.1.4. 메서드

copyTo(destination)

호출되면, 다음 단계를 실행합니다:

  1. [[byte length]]EncodedAudioChunk 의 값보다 destination이 작으면, TypeError를 던집니다.

  2. [[internal data]]destination으로 복사합니다.

8.1.5. 직렬화

EncodedAudioChunk직렬화 단계 (value, serialized, forStorage 포함):
  1. forStoragetrue이면 DataCloneError를 던집니다.

  2. value의 각각의 EncodedAudioChunk 내부 슬롯에 대해, 그 값을 동일한 이름의 필드로 serialized에 할당합니다.

EncodedAudioChunk역직렬화 단계 (serialized, value 포함):
  1. serialized의 모든 명명된 필드에 대해, 각 필드의 값을 value의 동일한 이름의 EncodedAudioChunk 내부 슬롯에 할당합니다.

참고: EncodedAudioChunk는 불변이므로, User Agent는 § 9.2.6 전송 및 직렬화와 유사한 참조 카운팅 모델로 직렬화를 구현할 수 있습니다.

8.2. EncodedVideoChunk 인터페이스

[Exposed=(Window,DedicatedWorker), Serializable]
interface EncodedVideoChunk {
  constructor(EncodedVideoChunkInit init);
  readonly attribute EncodedVideoChunkType type;
  readonly attribute long long timestamp;             // microseconds
  readonly attribute unsigned long long? duration;    // microseconds
  readonly attribute unsigned long byteLength;

  undefined copyTo(AllowSharedBufferSource destination);
};

dictionary EncodedVideoChunkInit {
  required EncodedVideoChunkType type;
  [EnforceRange] required long long timestamp;        // microseconds
  [EnforceRange] unsigned long long duration;         // microseconds
  required AllowSharedBufferSource data;
  sequence<ArrayBuffer> transfer = [];
};

enum EncodedVideoChunkType {
    "key",
    "delta",
};

8.2.1. 내부 슬롯

[[internal data]]

인코딩된 청크 데이터를 나타내는 바이트 배열입니다.

[[type]]

EncodedVideoChunkType의 타입입니다. EncodedVideoChunk

[[timestamp]]

프레젠테이션 타임스탬프(마이크로초 단위)입니다.

[[duration]]

프레젠테이션 지속 시간(마이크로초 단위)입니다.

[[byte length]]

[[internal data]]의 바이트 길이입니다.

8.2.2. 생성자

EncodedVideoChunk(init)
  1. 만약 init.transfer 에 같은 ArrayBuffer가 두 번 이상 참조되어 있으면, DataCloneErrorDOMException을 던집니다.

  2. init.transfer에 있는 각 transferable에 대해:

    1. 만약 [[Detached]] 내부 슬롯이 true라면, DataCloneErrorDOMException을 던집니다.

  3. chunk를 다음과 같이 초기화된 새로운 EncodedVideoChunk 객체로 둡니다.

    1. init.type[[type]]에 할당합니다.

    2. init.timestamp[[timestamp]]에 할당합니다.

    3. 만약 init에 duration이 있으면 init.duration[[duration]]에 할당하고, 없으면 null[[duration]]에 할당합니다.

    4. init.data.byteLength[[byte length]]에 할당합니다;

    5. 만약 init.transferinit.data가 참조하는 ArrayBuffer가 포함되어 있으면, User Agent는 MAY 다음을 선택할 수 있습니다:

      1. resourceinit.data의 샘플 데이터를 참조하는 새로운 media resource로 둡니다.

    6. 그 외의 경우:

      1. init.data의 복사본을 [[internal data]]에 할당합니다.

  4. init.transfer의 각 transferable에 대해:

    1. transferableDetachArrayBuffer를 수행합니다.

  5. chunk를 반환합니다.

8.2.3. 속성

type, of type EncodedVideoChunkType, readonly

[[type]]의 값을 반환합니다.

timestamp, of type long long, readonly

[[timestamp]]의 값을 반환합니다.

duration, of type unsigned long long, readonly, nullable

[[duration]]의 값을 반환합니다.

byteLength, of type unsigned long, readonly

[[byte length]]의 값을 반환합니다.

8.2.4. 메서드

copyTo(destination)

호출 시, 다음 단계를 실행합니다:

  1. [[byte length]]destination[[byte length]]보다 크면, TypeError를 던집니다.

  2. [[internal data]]destination에 복사합니다.

8.2.5. 직렬화

EncodedVideoChunk직렬화 단계 (value, serialized, forStorage 포함):
  1. forStoragetrue이면 DataCloneError를 던집니다.

  2. value의 각각의 EncodedVideoChunk 내부 슬롯에 대해, 그 값을 동일한 이름의 필드로 serialized에 할당합니다.

EncodedVideoChunk역직렬화 단계 (serialized, value 포함):
  1. serialized의 모든 명명된 필드에 대해, 각 필드의 값을 value의 동일한 이름의 EncodedVideoChunk 내부 슬롯에 할당합니다.

참고: EncodedVideoChunk는 불변이므로, User Agent는 § 9.4.7 전송 및 직렬화와 유사한 참조 카운팅 모델로 직렬화를 구현할 수 있습니다.

9. 원시 미디어 인터페이스

이러한 인터페이스는 인코딩되지 않은(원시) 미디어를 나타냅니다.

9.1. 메모리 모델

9.1.1. 배경

이 섹션은 규범적이지 않습니다.

디코딩된 미디어 데이터는 MAY 시스템 메모리의 많은 부분을 차지할 수 있습니다. 값비싼 복사 작업을 최소화하기 위해, 본 명세서는 참조 카운팅(clone(), close()) 방식의 스킴을 정의합니다.

NOTE: 작성자는 프레임이 더 이상 필요하지 않을 때 즉시 close()를 호출하는 것이 권장됩니다.

9.1.2. 참조 카운팅

media resourceVideoFrame 또는 AudioData에 의해 설명되는 실제 픽셀 데이터 또는 오디오 샘플 데이터를 저장하는 저장소입니다.

AudioData[[resource reference]]VideoFrame[[resource reference]] 내부 슬롯은 media resource를 참조합니다.

VideoFrame.clone()AudioData.clone()[[resource reference]]가 원래 객체와 동일한 media resource를 가리키는 새 객체를 반환합니다.

VideoFrame.close()AudioData.close()[[resource reference]] 슬롯을 지워 해당 media resource에 대한 참조를 해제합니다.

media resourceMUST [[resource reference]]에 의해 참조되는 동안에는 반드시 살아 있어야 합니다.

NOTE: media resource가 더 이상 [[resource reference]]에 의해 참조되지 않으면, 해당 리소스는 파괴될 수 있습니다. User Agent는 메모리 압박을 줄이고 자원 재사용을 촉진하기 위해 이러한 리소스를 신속하게 파괴할 것을 권장합니다.

9.1.3. 전송 및 직렬화

이 섹션은 규범적이지 않습니다.

AudioDataVideoFrame 모두 transferableserializable 객체입니다. 그들의 전송 및 직렬화 단계는 각각 § 9.2.6 전송 및 직렬화§ 9.4.7 전송 및 직렬화에 정의되어 있습니다.

AudioData 또는 VideoFrame을 전송하면 [[resource reference]]가 대상 객체로 이동하고, 소스 객체는 close()처럼 닫힙니다. 작성자는 이 기능을 사용하여 AudioData 또는 VideoFrame을 영역(realm) 간에 기본 media resource를 복사하지 않고 이동할 수 있습니다.

AudioData 또는 VideoFrame을 직렬화하면 소스 객체가 clone()처럼 복제되어 두 객체가 동일한 media resource를 참조하게 됩니다. 작성자는 이 기능을 이용해 AudioData 또는 VideoFrame을 다른 realm으로 복사하지 않고 복제할 수 있습니다.

9.2. AudioData 인터페이스

[Exposed=(Window,DedicatedWorker), Serializable, Transferable]
interface AudioData {
  constructor(AudioDataInit init);

  readonly attribute AudioSampleFormat? format;
  readonly attribute float sampleRate;
  readonly attribute unsigned long numberOfFrames;
  readonly attribute unsigned long numberOfChannels;
  readonly attribute unsigned long long duration;  // microseconds
  readonly attribute long long timestamp;          // microseconds

  unsigned long allocationSize(AudioDataCopyToOptions options);
  undefined copyTo(AllowSharedBufferSource destination, AudioDataCopyToOptions options);
  AudioData clone();
  undefined close();
};

dictionary AudioDataInit {
  required AudioSampleFormat format;
  required float sampleRate;
  [EnforceRange] required unsigned long numberOfFrames;
  [EnforceRange] required unsigned long numberOfChannels;
  [EnforceRange] required long long timestamp;  // microseconds
  required BufferSource data;
  sequence<ArrayBuffer> transfer = [];
};

9.2.1. 내부 슬롯

[[resource reference]]

AudioData의 오디오 샘플 데이터를 저장하는 media resource에 대한 참조입니다.

[[format]]

AudioData에서 사용되는 AudioSampleFormat입니다. 기본 포맷이 AudioSampleFormat에 매핑되지 않거나 [[Detached]]true일 때는 null입니다.

[[sample rate]]

AudioData의 샘플레이트(Hz)입니다.

[[number of frames]]

AudioData프레임 개수입니다.

[[number of channels]]

AudioData의 오디오 채널 수입니다.

[[timestamp]]

AudioData의 프레젠테이션 타임스탬프(마이크로초 단위)입니다.

9.2.2. 생성자

AudioData(init)
  1. initvalid AudioDataInit가 아니면 TypeError를 던집니다.

  2. init.transfer에 같은 ArrayBuffer가 두 번 이상 참조되어 있으면, DataCloneErrorDOMException을 던집니다.

  3. init.transfer의 각 transferable에 대해:

    1. [[Detached]] 내부 슬롯이 true이면 DataCloneErrorDOMException을 던집니다.

  4. frame을 다음과 같이 초기화된 새로운 AudioData 객체로 둡니다:

    1. false[[Detached]]에 할당합니다.

    2. init.format[[format]]에 할당합니다.

    3. init.sampleRate[[sample rate]]에 할당합니다.

    4. init.numberOfFrames[[number of frames]]에 할당합니다.

    5. init.numberOfChannels[[number of channels]]에 할당합니다.

    6. init.timestamp[[timestamp]]에 할당합니다.

    7. 만약 init.transferinit.data가 참조하는 ArrayBuffer가 포함되어 있으면, User Agent는 MAY 다음을 선택할 수 있습니다:

      1. resourcedata의 샘플 데이터를 참조하는 새로운 media resource로 둡니다.

    8. 그 외의 경우:

      1. resourceinit.data의 복사본을 포함하는 media resource로 둡니다.

    9. resourceReferenceresource에 대한 참조로 둡니다.

    10. resourceReference[[resource reference]]에 할당합니다.

  5. init.transfer의 각 transferable에 대해:

    1. transferableDetachArrayBuffer를 수행합니다.

  6. frame을 반환합니다.

9.2.3. 속성

format, of type AudioSampleFormat, readonly, nullable

AudioData에서 사용되는 AudioSampleFormat입니다. 기본 포맷이 AudioSampleFormat에 매핑되지 않거나 [[Detached]]true일 때는 null입니다.

format getter 단계는 [[format]]을 반환하는 것입니다.

sampleRate, of type float, readonly

AudioData의 샘플레이트(Hz)입니다.

sampleRate getter 단계는 [[sample rate]]을 반환하는 것입니다.

numberOfFrames, of type unsigned long, readonly

AudioData프레임 개수입니다.

numberOfFrames getter 단계는 [[number of frames]]을 반환하는 것입니다.

numberOfChannels, of type unsigned long, readonly

AudioData의 오디오 채널 수입니다.

numberOfChannels getter 단계는 [[number of channels]]을 반환하는 것입니다.

timestamp, of type long long, readonly

AudioData의 프레젠테이션 타임스탬프(마이크로초 단위)입니다.

numberOfChannels getter 단계는 [[timestamp]]을 반환하는 것입니다.

duration, of type unsigned long long, readonly

AudioData의 지속 시간(마이크로초 단위)입니다.

duration getter 단계는 다음과 같습니다:

  1. microsecondsPerSecond1,000,000으로 둡니다.

  2. durationInSeconds[[number of frames]][[sample rate]]로 나눈 결과로 둡니다.

  3. durationInSecondsmicrosecondsPerSecond의 곱을 반환합니다.

9.2.4. 메서드

allocationSize(options)

options에 의해 설명되는 샘플을 저장하는 데 필요한 바이트 수를 반환합니다.

호출 시, 다음 단계를 수행합니다:

  1. [[Detached]]true이면 InvalidStateErrorDOMException을 던집니다.

  2. copyElementCountoptions와 함께 Compute Copy Element Count 알고리즘을 실행한 결과로 둡니다.

  3. destFormat[[format]]의 값으로 둡니다.

  4. options.format 존재하면, options.formatdestFormat에 할당합니다.

  5. bytesPerSampledestFormat이 정의하는 샘플 당 바이트 수로 둡니다.

  6. bytesPerSample × copyElementCount의 곱을 반환합니다.

copyTo(destination, options)

AudioData의 지정된 플레인(plane)에서 destination 버퍼로 샘플을 복사합니다.

호출 시, 다음 단계를 수행합니다:

  1. [[Detached]]true이면 InvalidStateErrorDOMException을 던집니다.

  2. copyElementCountoptions와 함께 Compute Copy Element Count 알고리즘을 실행한 결과로 둡니다.

  3. destFormat[[format]]의 값으로 둡니다.

  4. options.format 존재하면, options.formatdestFormat에 할당합니다.

  5. bytesPerSampledestFormat이 정의하는 샘플 당 바이트 수로 둡니다.

  6. bytesPerSample × copyElementCount의 곱이 destination.byteLength보다 크면 RangeError를 던집니다.

  7. resource[[resource reference]]가 참조하는 media resource로 둡니다.

  8. planeFramesresource에서 options.planeIndex에 해당하는 영역(region)으로 둡니다.

  9. planeFrames의 요소들을 destination에 복사합니다. 복사는 options.frameOffset에 위치한 프레임부터 시작해서 copyElementCount만큼 복사될 때까지 진행합니다. 만약 destFormat[[format]]과 다르다면 복사 시 destFormat AudioSampleFormat으로 변환합니다.

clone()

동일한 media resource를 참조하는 새로운 AudioData를 생성합니다.

호출 시, 다음 단계를 수행합니다:

  1. [[Detached]]true이면 InvalidStateErrorDOMException을 던집니다.

  2. Clone AudioData 알고리즘을 this로 실행한 결과를 반환합니다.

close()

모든 상태를 지우고 media resource에 대한 참조를 해제합니다. close는 최종적입니다.

호출 시, Close AudioData 알고리즘을 this로 실행합니다.

9.2.5. 알고리즘

Compute Copy Element Count (options 포함)

다음 단계를 실행합니다:

  1. destFormat[[format]]의 값으로 둡니다.

  2. options.format 존재하면, options.formatdestFormat에 할당합니다.

  3. destFormatinterleaved AudioSampleFormat을 설명하며 options.planeIndex 가 0보다 크면, RangeError를 던집니다.

  4. 그 외에 destFormatplanar AudioSampleFormat을 설명하며 options.planeIndex[[number of channels]] 이상이면 RangeError를 던집니다.

  5. [[format]]destFormat이 다르고 User Agent가 요청된 AudioSampleFormat 변환을 지원하지 않으면, NotSupportedErrorDOMException을 던집니다. f32-planar로의 변환은 MUST 항상 지원되어야 합니다.

  6. frameCountoptions.planeIndex로 식별된 플레인의 프레임 개수로 둡니다.

  7. options.frameOffsetframeCount 이상이면 RangeError를 던집니다.

  8. copyFrameCountframeCount에서 options.frameOffset을 뺀 값으로 둡니다.

  9. options.frameCount 존재하면:

    1. options.frameCountcopyFrameCount보다 크면 RangeError를 던집니다.

    2. 그 외의 경우 options.frameCountcopyFrameCount에 할당합니다.

  10. elementCountcopyFrameCount로 둡니다.

  11. destFormatinterleaved AudioSampleFormat을 설명하면, elementCount[[number of channels]]을 곱합니다.

  12. elementCount를 반환합니다.

Clone AudioData (data 포함)

다음 단계를 실행합니다:

  1. clone을 다음과 같이 초기화된 새로운 AudioData로 둡니다:

    1. resourcedata[[resource reference]]가 참조하는 media resource로 둡니다.

    2. referenceresource에 대한 새로운 참조로 둡니다.

    3. reference[[resource reference]]에 할당합니다.

    4. data[[Detached]], [[format]], [[sample rate]], [[number of frames]], [[number of channels]], [[timestamp]] 값을 clone의 해당 슬롯에 할당합니다.

  2. clone을 반환합니다.

Close AudioData (data 포함)

다음 단계를 실행합니다:

  1. data[[Detached]] 내부 슬롯에 true를 할당합니다.

  2. data[[resource reference]]null을 할당합니다.

  3. data[[sample rate]]0을 할당합니다.

  4. data[[number of frames]]0을 할당합니다.

  5. data[[number of channels]]0을 할당합니다.

  6. data[[format]]null을 할당합니다.

AudioDataInitvalid AudioDataInit인지 확인하려면, 다음 단계를 실행합니다:
  1. sampleRate 가 0 이하이면 false를 반환합니다.

  2. numberOfFrames 가 0이면 false를 반환합니다.

  3. numberOfChannels 가 0이면 false를 반환합니다.

  4. data 가 충분한 데이터를 가지고 있는지 다음 단계로 검증합니다:

    1. totalSamplesnumberOfFrames × numberOfChannels로 둡니다.

    2. bytesPerSampleformat이 정의하는 샘플 당 바이트 수로 둡니다.

    3. totalSizebytesPerSample × totalSamples로 둡니다.

    4. dataSizedata의 바이트 크기로 둡니다.

    5. dataSizetotalSize보다 작으면 false를 반환합니다.

  5. true를 반환합니다.

참고: AudioDataInitdata의 메모리 레이아웃은 planar 또는 interleaved format의 기대값과 일치하는 것이 예상됩니다. 샘플이 AudioSampleFormat에 부합하는지 실제로 검증하는 방법은 없습니다.

9.2.6. 전송 및 직렬화

AudioData전송 단계 (valuedataHolder 포함)는 다음과 같습니다:
  1. value[[Detached]]true이면, DataCloneErrorDOMException을 던집니다.

  2. value의 모든 AudioData 내부 슬롯 값을 동일한 이름의 필드로 dataHolder에 할당합니다.

  3. Close AudioData 알고리즘을 value로 실행합니다.

AudioDatatransfer-receiving 단계 (dataHolder, value 포함)는 다음과 같습니다:
  1. dataHolder의 모든 명명된 필드 값을 value의 동일한 이름의 AudioData 내부 슬롯에 할당합니다.

AudioData직렬화 단계 (value, serialized, forStorage 포함)는 다음과 같습니다:
  1. value[[Detached]]true이면, DataCloneErrorDOMException을 던집니다.

  2. forStoragetrue이면 DataCloneError를 던집니다.

  3. resourcevalue[[resource reference]]가 참조하는 media resource로 둡니다.

  4. newReferenceresource에 대한 새로운 참조로 둡니다.

  5. newReference를 |serialized.resource reference|에 할당합니다.

  6. value의 나머지 AudioData 내부 슬롯(단, [[resource reference]] 제외)은 각각의 값들을 동일한 이름의 필드로 serialized에 할당합니다.

AudioData역직렬화 단계 (serialized, value 포함)는 다음과 같습니다:
  1. serialized의 모든 명명된 필드 값을 value의 동일한 이름의 AudioData 내부 슬롯에 할당합니다.

9.2.7. AudioDataCopyToOptions

dictionary AudioDataCopyToOptions {
  [EnforceRange] required unsigned long planeIndex;
  [EnforceRange] unsigned long frameOffset = 0;
  [EnforceRange] unsigned long frameCount;
  AudioSampleFormat format;
};
planeIndex, of type unsigned long

복사할 plane을 식별하는 인덱스입니다.

frameOffset, of type unsigned long, 기본값 0

소스 plane 데이터에서 복사를 시작할 프레임의 오프셋입니다. 기본값은 0입니다.

frameCount, of type unsigned long

복사할 프레임 개수입니다. 지정하지 않을 경우, 복사는 frameOffset부터 plane의 모든 프레임을 포함합니다.

format, of type AudioSampleFormat

destination 데이터의 출력 AudioSampleFormat입니다. 지정하지 않을 경우, 복사 결과는 this AudioData의 [[format]]를 사용합니다. copyTo()를 호출하면 요청한 형식으로 변환을 지원하지 않으면 NotSupportedError가 발생합니다. 어떤 AudioSampleFormat에서 f32-planar로의 변환은 MUST 항상 지원되어야 합니다.

참고: [WEBAUDIO]와 연동하려는 작성자는 f32-planar를 요청하고, 복사 결과를 AudioBuffer 생성 또는 AudioWorklet 렌더에 사용할 수 있습니다.

9.3. 오디오 샘플 형식

오디오 샘플 형식은 단일 샘플(예: 32비트 부동소수점)을 표현하는 숫자 타입과 여러 채널의 샘플을 interleaved 또는 planar로 배치하는 방법을 설명합니다. 오디오 샘플 타입은 데이터 저장에 사용되는 숫자 타입과 단위만을 의미하며, 이는 u8, s16, s32, 또는 f32 (각각 부호 없는 8비트, 부호 있는 16비트, 부호 있는 32비트, 32비트 부동소수점)입니다. 오디오 버퍼 배치는 샘플이 메모리에서 배치되는 방식(planar 또는 interleaved)만을 의미합니다.

샘플은 특정 시점, 특정 채널에서의 신호 크기를 의미하는 단일 값을 의미합니다.

프레임 또는 (샘플-프레임)은 다채널 신호의 모든 채널 값이 동일한 시점에 발생하는 값의 집합을 의미합니다.

참고: 오디오 신호가 모노(채널이 하나)라면, 프레임과 샘플은 동일한 개념입니다.

이 명세의 모든 오디오 샘플은 선형 펄스 코드 변조(Linear PCM)를 사용합니다: 양자화 레벨 간 간격이 균일합니다.

참고: 이 명세와 함께 사용되는 것이 예상되는 Web Audio API 역시 Linear PCM을 사용합니다.

enum AudioSampleFormat {
  "u8",
  "s16",
  "s32",
  "f32",
  "u8-planar",
  "s16-planar",
  "s32-planar",
  "f32-planar",
};
u8

8비트 부호 없는 정수 샘플이며 interleaved 채널 배치입니다.

s16

16비트 부호 있는 정수 샘플이며 interleaved 채널 배치입니다.

s32

32비트 부호 있는 정수 샘플이며 interleaved 채널 배치입니다.

f32

32비트 부동소수점 샘플이며 interleaved 채널 배치입니다.

u8-planar

8비트 부호 없는 정수 샘플이며 planar 채널 배치입니다.

s16-planar

16비트 부호 있는 정수 샘플이며 planar 채널 배치입니다.

s32-planar

32비트 부호 있는 정수 샘플이며 planar 채널 배치입니다.

f32-planar

32비트 부동소수점 샘플이며 planar 채널 배치입니다.

9.3.1. 오디오 버퍼 배치 방식

AudioDataAudioSampleFormatinterleaved일 경우, 여러 채널의 오디오 샘플이 동일 버퍼에 연속적으로 배치됩니다. 채널 순서는 § 9.3.3 Audio channel ordering에 설명되어 있습니다. AudioData는 단일 plane만 가지며, plane의 요소 개수는 [[number of frames]] * [[number of channels]]과 같습니다.

AudioDataAudioSampleFormatplanar일 경우, 여러 채널의 오디오 샘플이 각각 별도 버퍼에 배치되며, 각 버퍼의 순서는 § 9.3.3 Audio channel ordering에 설명되어 있습니다. AudioDataAudioData[[number of channels]] 개수만큼 plane을 가지며, 각 plane은 [[number of frames]]만큼 요소를 가집니다.

참고: Web Audio API는 현재 f32-planar만 사용합니다.

참고: 아래 다이어그램은 planarinterleaved AudioSampleFormat의 메모리 배치 예시입니다.

Graphical representation the memory layout of interleaved and planar
    formats

9.3.2. 오디오 샘플의 크기

최소값최대값은 특정 오디오 샘플 타입에서 오디오 클리핑이 발생할 수 있는 경계값입니다. 그 외에는 일반적인 타입으로, 프로세싱 중에는 이 범위를 벗어난 값도 저장할 수 있습니다.

바이어스 값은 오디오 샘플 타입에서 주로 범위의 중간값이며(범위가 대칭적이지 않은 경우도 있음), 모든 값이 바이어스 값인 오디오 버퍼는 무음입니다.

샘플 타입 IDL 타입 최소값 바이어스 값 최대값
u8 octet 0 128 +255
s16 short -32768 0 +32767
s32 long -2147483648 0 +2147483647
f32 float -1.0 0.0 +1.0

참고: 24비트 정보를 저장할 수 있는 데이터 타입은 없지만, 24비트 샘플을 사용하는 오디오 콘텐츠는 흔하므로 32비트 정수형이 24비트 콘텐츠 저장에 흔히 사용됩니다.

AudioData 가 24비트 샘플을 포함하는 경우 SHOULD s32 또는 f32에 샘플을 저장해야 합니다. s32에 저장할 때는 각 샘플을 반드시 8비트 왼쪽으로 쉬프트해야 하며, 이 과정에서 유효 24비트 범위([-8388608, +8388607])를 벗어난 샘플은 클리핑됩니다. 클리핑 없이 무손실 전송을 원할 때는 MAY f32로 변환할 수 있습니다.

참고: u8, s16, s32 샘플은 저장 타입 특성상 클리핑이 불가피하지만, f32 샘플 처리 시 내부적으로 클리핑이 발생하지 않도록 구현하는 것이 SHOULD 권장됩니다.

9.3.3. 오디오 채널 순서

디코딩 시 결과 AudioData의 오디오 채널 순서는 MUST EncodedAudioChunk에 있는 순서와 같아야 합니다.

인코딩 시 결과 EncodedAudioChunk의 오디오 채널 순서는 MUST 주어진 AudioData에 있는 순서와 같아야 합니다.

즉, 인코딩과 디코딩 시 채널 재정렬은 수행되지 않습니다.

참고: 컨테이너는 채널 매핑(특정 채널 인덱스에 할당된 채널)을 내포하거나 명시합니다.

9.4. VideoFrame 인터페이스

참고: VideoFrameCanvasImageSource입니다. VideoFrameCanvasImageSource를 받는 모든 메서드에 전달할 수 있으며, CanvasDrawImagedrawImage()에도 사용할 수 있습니다.

[Exposed=(Window,DedicatedWorker), Serializable, Transferable]
interface VideoFrame {
  constructor(CanvasImageSource image, optional VideoFrameInit init = {});
  constructor(AllowSharedBufferSource data, VideoFrameBufferInit init);

  readonly attribute VideoPixelFormat? format;
  readonly attribute unsigned long codedWidth;
  readonly attribute unsigned long codedHeight;
  readonly attribute DOMRectReadOnly? codedRect;
  readonly attribute DOMRectReadOnly? visibleRect;
  readonly attribute double rotation;
  readonly attribute boolean flip;
  readonly attribute unsigned long displayWidth;
  readonly attribute unsigned long displayHeight;
  readonly attribute unsigned long long? duration;  // microseconds
  readonly attribute long long timestamp;           // microseconds
  readonly attribute VideoColorSpace colorSpace;

  VideoFrameMetadata metadata();

  unsigned long allocationSize(
      optional VideoFrameCopyToOptions options = {});
  Promise<sequence<PlaneLayout>> copyTo(
      AllowSharedBufferSource destination,
      optional VideoFrameCopyToOptions options = {});
  VideoFrame clone();
  undefined close();
};

dictionary VideoFrameInit {
  unsigned long long duration;  // microseconds
  long long timestamp;          // microseconds
  AlphaOption alpha = "keep";

  // Default matches image. May be used to efficiently crop. Will trigger
  // new computation of displayWidth and displayHeight using image's pixel
  // aspect ratio unless an explicit displayWidth and displayHeight are given.
  DOMRectInit visibleRect;

  double rotation = 0;
  boolean flip = false;

  // Default matches image unless visibleRect is provided.
  [EnforceRange] unsigned long displayWidth;
  [EnforceRange] unsigned long displayHeight;

  VideoFrameMetadata metadata;
};

dictionary VideoFrameBufferInit {
  required VideoPixelFormat format;
  required [EnforceRange] unsigned long codedWidth;
  required [EnforceRange] unsigned long codedHeight;
  required [EnforceRange] long long timestamp;  // microseconds
  [EnforceRange] unsigned long long duration;  // microseconds

  // Default layout is tightly-packed.
  sequence<PlaneLayout> layout;

  // Default visible rect is coded size positioned at (0,0)
  DOMRectInit visibleRect;

  double rotation = 0;
  boolean flip = false;

  // Default display dimensions match visibleRect.
  [EnforceRange] unsigned long displayWidth;
  [EnforceRange] unsigned long displayHeight;

  VideoColorSpaceInit colorSpace;

  sequence<ArrayBuffer> transfer = [];

  VideoFrameMetadata metadata;
};

dictionary VideoFrameMetadata {
  // Possible members are recorded in the VideoFrame Metadata Registry.
};

9.4.1. 내부 슬롯

[[resource reference]]

이 프레임의 픽셀 데이터를 저장하는 media resource에 대한 참조입니다.

[[format]]

VideoFrame의 픽셀 포맷을 설명하는 VideoPixelFormat입니다. 기본 포맷이 VideoPixelFormat에 매핑되지 않거나 [[Detached]]true일 때는 null입니다.

[[coded width]]

VideoFrame의 픽셀 단위 폭입니다. 비가시 패딩이 포함될 수 있으며, 비율 조정 전의 값입니다.

[[coded height]]

VideoFrame의 픽셀 단위 높이입니다. 비가시 패딩이 포함될 수 있으며, 비율 조정 전의 값입니다.

[[visible left]]

가시 사각형의 왼쪽 오프셋을 정의하는 픽셀 수입니다.

[[visible top]]

가시 사각형의 위쪽 오프셋을 정의하는 픽셀 수입니다.

[[visible width]]

가시 사각형에 포함할 픽셀의 폭입니다. [[visible left]]에서 시작합니다.

[[visible height]]

가시 사각형에 포함할 픽셀의 높이입니다. [[visible top]]에서 시작합니다.

[[rotation]]

렌더링 시 VideoFrame에 적용되는 회전 각도(시계 방향, 도 단위)입니다. 회전은 flip보다 먼저 적용됩니다.

[[flip]]

렌더링 시 VideoFrame에 수평 flip이 적용되는지 여부입니다. flip은 회전 이후에 적용됩니다.

[[display width]]

비율 조정 후 디스플레이될 때 VideoFrame의 폭입니다.

[[display height]]

비율 조정 후 디스플레이될 때 VideoFrame의 높이입니다.

[[duration]]

프레젠테이션 지속 시간(마이크로초 단위)입니다. 이 값은 해당 EncodedVideoChunk에서 복사됩니다.

[[timestamp]]

프레젠테이션 타임스탬프(마이크로초 단위)입니다. 이 값은 해당 EncodedVideoChunk에서 복사됩니다.

[[color space]]

이 프레임과 연관된 VideoColorSpace입니다.

[[metadata]]

이 프레임과 연관된 VideoFrameMetadata입니다. 가능한 멤버는 [webcodecs-video-frame-metadata-registry]에 기록되어 있습니다. 설계상 모든 VideoFrameMetadata 속성은 직렬화 가능합니다.

9.4.2. 생성자

VideoFrame(image, init)

  1. 이미지 인자 사용 가능성 검사. 예외가 발생하거나 bad가 반환되면, InvalidStateError DOMException을 던집니다.

  2. imageorigin-clean이 아니면, SecurityError DOMException을 던집니다.

  3. frame을 새로운 VideoFrame으로 둡니다.

  4. image에 대해 다음을 분기합니다:

    참고: 작성자는 CanvasImageSource에서 암묵적으로 제공되지 않는 경우 의미 있는 timestamp를 제공하는 것이 권장됩니다. VideoFrame을 소비하는 인터페이스는 이 값으로 타이밍 결정을 할 수 있습니다. 예를 들어 VideoEncodertimestamp 값을 사용하여 rate control을 할 수 있습니다(framerate 참조).

  5. frame을 반환합니다.

VideoFrame(data, init)

  1. initvalid VideoFrameBufferInit가 아니면 TypeError를 던집니다.

  2. defaultRect를 «[ "x:" → 0, "y" → 0, "width" → init.codedWidth, "height" → init.codedWidth ]»로 둡니다.

  3. overrideRectundefined로 둡니다.

  4. init.visibleRect 가 존재하면, 그 값을 overrideRect에 할당합니다.

  5. parsedRectParse Visible Rect 알고리즘을 defaultRect, overrideRect, init.codedWidth, init.codedHeight, init.format으로 실행한 결과로 둡니다.

  6. parsedRect가 예외면 parsedRect를 반환합니다.

  7. optLayoutundefined로 둡니다.

  8. init.layout 가 존재하면, 그 값을 optLayout에 할당합니다.

  9. combinedLayoutCompute Layout and Allocation Size 알고리즘을 parsedRect, init.format, optLayout로 실행한 결과로 둡니다.

  10. combinedLayout이 예외면 combinedLayout을 던집니다.

  11. data.byteLengthcombinedLayoutallocationSize보다 작으면 TypeError를 던집니다.

  12. init.transfer 에 같은 ArrayBuffer가 두 번 이상 참조되어 있으면, DataCloneError DOMException을 던집니다.

  13. init.transfer의 각 transferable에 대해:

    1. [[Detached]] 내부 슬롯이 true라면, DataCloneError DOMException을 던집니다.

  14. init.transferdata가 참조하는 ArrayBuffer가 포함되어 있으면, User Agent는 MAY 다음을 선택할 수 있습니다:

    1. resourcedata의 픽셀 데이터를 참조하는 새로운 media resource로 둡니다.

  15. 그 외의 경우:

    1. resourcedata의 복사본을 가진 새로운 media resource로 둡니다. visibleRectlayout 을 사용해 data의 각 plane 픽셀 위치를 결정합니다.

      User Agent는 MAY 메모리 정렬을 개선하기 위해 더 큰 coded size와 plane stride로 resource를 할당할 수 있습니다. 증가는 codedWidthcodedHeight에 반영됩니다. 또한 User Agent는 visibleRect를 사용해 가시 사각형만 복사할 수 있습니다. 또한 resource 내에서 가시 사각형 위치를 재정렬할 수도 있습니다. 최종 위치는 visibleRect에 반영됩니다.

  16. init.transfer의 각 transferable에 대해:

    1. transferableDetachArrayBuffer를 수행합니다.

  17. resourceCodedWidthresource의 coded width로 둡니다.

  18. resourceCodedHeightresource의 coded height로 둡니다.

  19. resourceVisibleLeftresource의 가시 사각형 left offset으로 둡니다.

  20. resourceVisibleTopresource의 가시 사각형 top offset으로 둡니다.

    명세는 coded size, visible rectangle, display size에 대한 정의(및 다이어그램)를 SHOULD 제공해야 합니다. #166 참고.

  21. frame을 다음과 같이 초기화된 새로운 VideoFrame 객체로 둡니다:

    1. resourceCodedWidth, resourceCodedHeight, resourceVisibleLeft, resourceVisibleTop를 각각 [[coded width]], [[coded height]], [[visible left]], [[visible top]]에 할당합니다.

    2. init.visibleRect 가 존재하면:

      1. truncatedVisibleWidthvisibleRect.width의 절삭값으로 둡니다.

      2. truncatedVisibleWidth[[visible width]]에 할당합니다.

      3. truncatedVisibleHeightvisibleRect.height의 절삭값으로 둡니다.

      4. truncatedVisibleHeight[[visible height]]에 할당합니다.

    3. 그 외의 경우:

      1. [[coded width]][[visible width]]에 할당합니다.

      2. [[coded height]][[visible height]]에 할당합니다.

    4. Parse Rotation 알고리즘을 init.rotation과 함께 실행한 결과를 [[rotation]]에 할당합니다.

    5. init.flip[[flip]]에 할당합니다.

    6. displayWidthdisplayHeightinit에 존재하면, 각각 [[display width]][[display height]]에 할당합니다.

    7. 그 외의 경우:

      1. [[rotation]]0 또는 180이면:

        1. [[visible width]][[display width]]에 할당합니다.

        2. [[visible height]][[display height]]에 할당합니다.

      2. 그 외의 경우:

        1. [[visible height]][[display width]]에 할당합니다.

        2. [[visible width]][[display height]]에 할당합니다.

    8. inittimestampduration 을 각각 [[timestamp]], [[duration]]에 할당합니다.

    9. colorSpaceundefined로 둡니다.

    10. init.colorSpace 가 존재하면, 그 값을 colorSpace에 할당합니다.

    11. initformat[[format]]에 할당합니다.

    12. Pick Color Space 알고리즘을 colorSpace[[format]]과 함께 실행한 결과를 [[color space]]에 할당합니다.

    13. Copy VideoFrame metadatainitmetadata와 함께 호출한 결과를 frame.[[metadata]]에 할당합니다.

  22. frame을 반환합니다.

9.4.3. 속성

format, 타입 VideoPixelFormat, 읽기 전용, nullable

각 plane의 바이트 배열 방식과 plane의 개수 및 순서를 설명합니다. 기본 포맷이 VideoPixelFormat에 매핑되지 않거나 [[Detached]]true일 때 null이 됩니다.

format getter 단계는 [[format]]을 반환하는 것입니다.

codedWidth, 타입 unsigned long, 읽기 전용

VideoFrame의 픽셀 단위 폭입니다. 비가시 패딩이 포함될 수 있으며, 비율 조정 전의 값입니다.

codedWidth getter 단계는 [[coded width]]을 반환하는 것입니다.

codedHeight, 타입 unsigned long, 읽기 전용

VideoFrame의 픽셀 단위 높이입니다. 비가시 패딩이 포함될 수 있으며, 비율 조정 전의 값입니다.

codedHeight getter 단계는 [[coded height]]을 반환하는 것입니다.

codedRect, 타입 DOMRectReadOnly, 읽기 전용, nullable

DOMRectReadOnly로서 widthheightcodedWidthcodedHeight에 일치하며, xy(0,0)입니다. allocationSize()copyTo()와 함께 사용하기 편리하도록 제공됩니다.

codedRect getter 단계는 다음과 같습니다:

  1. [[Detached]]truenull을 반환합니다.

  2. rect를 다음과 같이 초기화된 새로운 DOMRectReadOnly로 둡니다:

    1. 0xy에 할당합니다.

    2. [[coded width]][[coded height]]를 각각 width, height에 할당합니다.

  3. rect를 반환합니다.

visibleRect, 타입 DOMRectReadOnly, 읽기 전용, nullable

VideoFrame의 가시 픽셀 사각형을 설명하는 DOMRectReadOnly입니다.

visibleRect getter 단계는 다음과 같습니다:

  1. [[Detached]]truenull을 반환합니다.

  2. rect를 다음과 같이 초기화된 새로운 DOMRectReadOnly로 둡니다:

    1. [[visible left]], [[visible top]], [[visible width]], [[visible height]]를 각각 x, y, width, height에 할당합니다.

  3. rect를 반환합니다.

rotation, 타입 double, 읽기 전용

렌더링 시 VideoFrame에 적용되는 회전 각도(시계 방향, 도 단위)입니다. 회전은 flip보다 먼저 적용됩니다.

rotation getter 단계는 [[rotation]]을 반환하는 것입니다.

flip, 타입 boolean, 읽기 전용

렌더링 시 VideoFrame에 수평 flip이 적용되는지 여부입니다. flip은 회전 이후에 적용됩니다.

flip getter 단계는 [[flip]]을 반환하는 것입니다.

displayWidth, 타입 unsigned long, 읽기 전용

회전, 비율 조정 이후 디스플레이될 때 VideoFrame의 폭입니다.

displayWidth getter 단계는 [[display width]]을 반환하는 것입니다.

displayHeight, 타입 unsigned long, 읽기 전용

회전, 비율 조정 이후 디스플레이될 때 VideoFrame의 높이입니다.

displayHeight getter 단계는 [[display height]]을 반환하는 것입니다.

timestamp, 타입 long long, 읽기 전용

프레젠테이션 타임스탬프(마이크로초 단위)입니다. 디코드 시에는 해당 EncodedVideoChunk에서 복사되고, 인코드 시에는 이 VideoFrame에서 EncodedVideoChunk로 복사됩니다.

timestamp getter 단계는 [[timestamp]]을 반환하는 것입니다.

duration, 타입 unsigned long long, 읽기 전용, nullable

프레젠테이션 지속 시간(마이크로초 단위)입니다. 이 값은 해당 EncodedVideoChunk에서 복사됩니다.

duration getter 단계는 [[duration]]을 반환하는 것입니다.

colorSpace, 타입 VideoColorSpace, 읽기 전용

이 프레임과 연관된 VideoColorSpace입니다.

colorSpace getter 단계는 [[color space]]을 반환하는 것입니다.

9.4.4. 내부 구조체

combined buffer layout은 다음으로 구성된 구조체입니다:

computed plane layout은 다음으로 구성된 구조체입니다:

9.4.5. 메서드

allocationSize(options)

지정된 options와 함께 BufferSourcecopyTo()에 사용할 때 필요한 최소 바이트 길이를 반환합니다.

호출 시, 다음 단계를 실행합니다:

  1. [[Detached]]true이면 InvalidStateError DOMException을 던집니다.

  2. [[format]]null이면 NotSupportedError DOMException을 던집니다.

  3. combinedLayoutParse VideoFrameCopyToOptions 알고리즘을 options와 함께 실행한 결과로 둡니다.

  4. combinedLayout이 예외면 combinedLayout을 던집니다.

  5. combinedLayoutallocationSize를 반환합니다.

copyTo(destination, options)

이 프레임의 plane들을 options에 따라 destination으로 비동기적으로 복사합니다. 데이터 형식은 options.format존재하면 그 값을 사용하고, 아니면 this VideoFrameformat을 사용합니다.

참고: 여러 번 copyTo()를 호출해 반환된 Promise들은 반환 순서대로 resolve될 것이라는 보장은 없습니다.

호출 시, 다음 단계를 실행합니다:

  1. [[Detached]]true면, InvalidStateError DOMException으로 reject된 promise를 반환합니다.

  2. [[format]]null이면, NotSupportedError DOMException으로 reject된 promise를 반환합니다.

  3. combinedLayoutParse VideoFrameCopyToOptions 알고리즘을 options와 함께 실행한 결과로 둡니다.

  4. combinedLayout이 예외면, combinedLayout으로 reject된 promise를 반환합니다.

  5. destination.byteLengthcombinedLayoutallocationSize보다 작으면 TypeError로 reject된 promise를 반환합니다.

  6. options.formatRGBA, RGBX, BGRA, BGRX 중 하나와 같으면:

    1. newOptionsClone Configuration 알고리즘을 options와 함께 실행한 결과로 둡니다.

    2. newOptions.formatundefined를 할당합니다.

    3. rgbFrameConvert to RGB frame 알고리즘을 this, options.format, options.colorSpace와 함께 실행한 결과로 둡니다.

    4. rgbFramedestinationnewOptions를 인자로 하여 copyTo()를 호출한 결과를 반환합니다.

  7. p를 새로운 Promise로 둡니다.

  8. copyStepsQueue를 새로운 parallel queue로 둡니다.

  9. planeLayouts를 새로운 목록으로 둡니다.

  10. 다음 단계들을 copyStepsQueue에 enqueue 합니다:

    1. resource를 [[resource reference]]가 참조하는 media resource로 둡니다.

    2. numPlanes[[format]]이 정의하는 plane 개수로 둡니다.

    3. planeIndex0으로 둡니다.

    4. planeIndexcombinedLayoutnumPlanes보다 작은 동안:

      1. sourceStrideresourceplaneIndex로 식별되는 plane의 stride로 둡니다.

      2. computedLayoutcombinedLayoutcomputedLayouts에서 planeIndex 위치에 있는 computed plane layout로 둡니다.

      3. sourceOffsetcomputedLayoutsourceTop × sourceStride의 곱으로 둡니다.

      4. computedLayoutsourceLeftBytessourceOffset에 더합니다.

      5. destinationOffsetcomputedLayoutdestinationOffset으로 둡니다.

      6. rowBytescomputedLayoutsourceWidthBytes로 둡니다.

      7. layout을 새로운 PlaneLayout으로, offsetdestinationOffset, striderowBytes로 초기화합니다.

      8. row0으로 둡니다.

      9. rowcomputedLayoutsourceHeight보다 작은 동안:

        1. rowBytes 만큼의 바이트를 resource에서 sourceOffset 위치에서 시작하여 destinationdestinationOffset 위치로 복사합니다.

        2. sourceOffsetsourceStride를 더해 증가시킵니다.

        3. destinationOffsetcomputedLayoutdestinationStride를 더해 증가시킵니다.

        4. row1을 더해 증가시킵니다.

      10. planeIndex1을 더해 증가시킵니다.

      11. layoutplaneLayouts에 추가합니다.

    5. 작업을 큐에 추가하여 pplaneLayouts로 resolve합니다.

  11. p를 반환합니다.

clone()

동일한 media resource를 참조하는 새로운 VideoFrame을 생성합니다.

호출 시, 다음 단계를 실행합니다:

  1. frame[[Detached]] 내부 슬롯 값이 true이면, InvalidStateErrorDOMException을 던집니다.

  2. Clone VideoFrame 알고리즘을 this와 함께 실행한 결과를 반환합니다.

close()

모든 상태를 지우고 media resource에 대한 참조를 해제합니다. close는 최종적입니다.

호출 시, Close VideoFrame 알고리즘을 this와 함께 실행합니다.

metadata()

이 프레임과 연관된 VideoFrameMetadata를 가져옵니다.

호출 시, 다음 단계를 실행합니다:

  1. [[Detached]]true이면, InvalidStateErrorDOMException을 던집니다.

  2. Copy VideoFrame metadata[[metadata]]와 함께 호출한 결과를 반환합니다.

9.4.6. 알고리즘

VideoFrame 생성 (output, timestamp, duration, displayAspectWidth, displayAspectHeight, colorSpace, rotation, flip 포함)
  1. frame을 다음과 같이 생성된 새로운 VideoFrame으로 둡니다:

    1. [[Detached]]false를 할당합니다.

    2. resourceoutput이 설명하는 media resource로 둡니다.

    3. resourceReferenceresource에 대한 참조로 둡니다.

    4. resourceReference[[resource reference]]에 할당합니다.

    5. output이 인식 가능한 VideoPixelFormat을 사용하면 해당 포맷을 [[format]]에 할당하고, 아니면 [[format]]null을 할당합니다.

    6. codedWidth, codedHeightoutput의 픽셀 단위 coded width, coded height로 둡니다.

    7. visibleLeft, visibleTop, visibleWidth, visibleHeightoutput의 가시 사각형의 left, top, width, height로 둡니다.

    8. displayWidth, displayHeightoutput의 픽셀 단위 디스플레이 크기로 둡니다.

    9. displayAspectWidthdisplayAspectHeight가 주어지면 displayWidth 또는 displayHeight를 조정하여 비율이 displayAspectWidthdisplayAspectHeight와 같아지도록 합니다.

    10. codedWidth, codedHeight, visibleLeft, visibleTop, visibleWidth, visibleHeight, displayWidth, displayHeight 값을 각각 [[coded width]], [[coded height]], [[visible left]], [[visible top]], [[visible width]], [[visible height]] 에 각각 할당합니다.

    11. duration, timestamp를 각각 [[duration]], [[timestamp]]에 할당합니다.

    12. [[color space]]Pick Color Space 알고리즘을 colorSpace[[format]]과 함께 실행한 결과를 할당합니다.

    13. rotationflip에 각각 rotationflip을 할당합니다.

  2. frame을 반환합니다.

Pick Color Space (overrideColorSpace, format 포함)
  1. overrideColorSpace가 제공되면, overrideColorSpace로 생성된 새로운 VideoColorSpace를 반환합니다.

    User Agent는 구현자 정의 휴리스틱에 따라 overrideColorSpacenull 멤버를 추측 값으로 대체할 수 있습니다.

  2. 그 외에 [[format]]RGB format이면 새로운 sRGB Color Space 인스턴스를 반환합니다.

  3. 그 외의 경우, 새로운 REC709 Color Space 인스턴스를 반환합니다.

VideoFrameInit 유효성 검사 (format, codedWidth, codedHeight 포함)
  1. visibleRect존재하면:

    1. validAlignmentVerify Rect Offset Alignment 알고리즘을 format, visibleRect와 함께 실행한 결과로 둡니다.

    2. validAlignmentfalsefalse를 반환합니다.

    3. visibleRect의 속성 중 음수 또는 유한하지 않은 값이 있으면 false를 반환합니다.

    4. visibleRect.width == 0 또는 visibleRect.height == 0이면 false를 반환합니다.

    5. visibleRect.y + visibleRect.heightcodedHeight를 초과하면 false를 반환합니다.

    6. visibleRect.x + visibleRect.widthcodedWidth를 초과하면 false를 반환합니다.

  2. codedWidth = 0 또는 codedHeight = 0이면 false를 반환합니다.

  3. displayWidthdisplayHeight 중 하나만 존재하면 false를 반환합니다.

  4. displayWidth == 0 또는 displayHeight == 0이면 false를 반환합니다.

  5. true를 반환합니다.

VideoFrameBufferInitvalid VideoFrameBufferInit인지 확인하려면 다음 단계를 실행합니다:
  1. codedWidth = 0 또는 codedHeight = 0이면 false를 반환합니다.

  2. visibleRect의 속성 중 음수 또는 유한하지 않은 값이 있으면 false를 반환합니다.

  3. visibleRect.y + visibleRect.heightcodedHeight를 초과하면 false를 반환합니다.

  4. visibleRect.x + visibleRect.widthcodedWidth를 초과하면 false를 반환합니다.

  5. displayWidthdisplayHeight 중 하나만 존재하면 false를 반환합니다.

  6. displayWidth = 0 또는 displayHeight = 0이면 false를 반환합니다.

  7. true를 반환합니다.

다른 프레임에서 Frame 초기화 (init, frame, otherFrame 포함)
  1. formatotherFrame.format으로 둡니다.

  2. init.alphadiscard이면, otherFrame.formatequivalent opaque formatformat에 할당합니다.

  3. validInitValidate VideoFrameInit 알고리즘을 formatotherFrame[[coded width]], [[coded height]]로 실행한 결과로 둡니다.

  4. validInitfalseTypeError를 던집니다.

  5. resourceotherFrame[[resource reference]]가 참조하는 media resource로 둡니다.

  6. resource의 새로운 참조를 frame[[resource reference]]에 할당합니다.

  7. 다음 속성들을 otherFrame에서 frame으로 할당합니다: codedWidth, codedHeight, colorSpace.

  8. defaultVisibleRectotherFramevisibleRect getter 단계를 수행한 결과로 둡니다.

  9. baseRotationbaseFlip을 각각 otherFrame[[rotation]], [[flip]]로 둡니다.

  10. defaultDisplayWidthdefaultDisplayHeight를 각각 otherFrame[[display width]], [[display height]]로 둡니다.

  11. Initialize Visible Rect, Orientation, and Display Size 알고리즘을 init, frame, defaultVisibleRect, baseRotation, baseFlip, defaultDisplayWidth, defaultDisplayHeight와 함께 실행합니다.

  12. durationinit존재하면, frame[[duration]]에 할당하고, 아니면 otherFrame.durationframe[[duration]]에 할당합니다.

  13. timestampinit존재하면, frame[[timestamp]]에 할당하고, 아니면 otherFrame.timestampframe[[timestamp]]에 할당합니다.

  14. formatframe.[[format]]에 할당합니다.

  15. Copy VideoFrame metadata 알고리즘을 initmetadata와 함께 호출한 결과를 frame.[[metadata]]에 할당합니다.

리소스로 프레임 초기화 (init, frame, resource, codedWidth, codedHeight, baseRotation, baseFlip, defaultDisplayWidth, defaultDisplayHeight 사용)
  1. formatnull로 설정한다.

  2. resource가 인식 가능한 VideoPixelFormat을 사용하면, resourceVideoPixelFormatformat에 할당한다.

  3. validInitVideoFrameInit 검증 알고리즘을 format, width, height로 실행한 결과로 설정한다.

  4. validInitfalse이면 TypeError를 throw한다.

  5. resource에 대해 새로운 참조를 생성하여 frame[[resource reference]]에 할당한다.

  6. init.alphadiscard이면, format동등 불투명 포맷format에 할당한다.

  7. format[[format]]에 할당한다.

  8. codedWidthcodedHeight를 각각 frame[[coded width]][[coded height]]에 할당한다.

  9. defaultVisibleRect를 새로운 DOMRect로, «[ "x:" → 0, "y" → 0, "width" → codedWidth, "height" → codedHeight ]»로 생성한다.

  10. 가시 영역, 방향, 디스플레이 크기 초기화 알고리즘을 init, frame, defaultVisibleRect, defaultDisplayWidth, defaultDisplayHeight로 실행한다.

  11. init.durationframe[[duration]]에 할당한다.

  12. init.timestampframe[[timestamp]]에 할당한다.

  13. resource가 알려진 VideoColorSpace를 가지면, 그 값을 [[color space]]에 할당한다.

  14. 그렇지 않으면, 비어있는 VideoColorSpaceInit으로 생성한 새로운 VideoColorSpace[[color space]]에 할당한다.

가시 사각형, 방향, 디스플레이 크기 초기화 (init, frame, defaultVisibleRect, baseRotation, baseFlip, defaultDisplayWidth, defaultDisplayHeight 포함)
  1. visibleRectdefaultVisibleRect로 둡니다.

  2. init.visibleRect존재하면, 그 값을 visibleRect에 할당합니다.

  3. visibleRectx, y, width, height 를 각각 frame[[visible left]], [[visible top]], [[visible width]], [[visible height]]에 할당합니다.

  4. rotationParse Rotation 알고리즘을 init.rotation과 함께 실행한 결과로 둡니다.

  5. Add Rotations 알고리즘을 baseRotation, baseFlip, rotation과 함께 실행한 결과를 frame[[rotation]]에 할당합니다.

  6. baseFlipinit.flip과 같으면, frame[[flip]]false를 할당하고, 아니면 true를 할당합니다.

  7. displayWidthdisplayHeightinit존재하면, 각각 [[display width]][[display height]]에 할당합니다.

  8. 그 외의 경우:

    1. baseRotation0 또는 180이면:

      1. widthScaledefaultDisplayWidthdefaultVisibleRect.width로 나눈 값으로 둡니다.

      2. heightScaledefaultDisplayHeightdefaultVisibleRect.height로 나눈 값으로 둡니다.

    2. 그 외의 경우:

      1. widthScaledefaultDisplayHeightdefaultVisibleRect.width로 나눈 값으로 둡니다.

      2. heightScaledefaultDisplayWidthdefaultVisibleRect.height로 나눈 값으로 둡니다.

    3. displayWidth|frame|의 {{VideoFrame/[[visible width]]}} × |widthScale|로, 가장 가까운 정수로 반올림합니다.

    4. displayHeight|frame|의 {{VideoFrame/[[visible height]]}} × |heightScale|로, 가장 가까운 정수로 반올림합니다.

    5. rotation0 또는 180이면:

      1. displayWidthframe[[display width]]에 할당합니다.

      2. displayHeightframe[[display height]]에 할당합니다.

    6. 그 외의 경우:

      1. displayHeightframe[[display width]]에 할당합니다.

      2. displayWidthframe[[display height]]에 할당합니다.

VideoFrame 복제 (frame 포함)
  1. clone을 다음과 같이 초기화된 새로운 VideoFrame으로 둡니다:

    1. resourceframe[[resource reference]]가 참조하는 media resource로 둡니다.

    2. newReferenceresource에 대한 새로운 참조로 둡니다.

    3. newReferenceclone[[resource reference]]에 할당합니다.

    4. [[resource reference]]를 제외한 frame의 나머지 내부 슬롯을 같은 이름의 clone 슬롯에 할당합니다.

  2. clone을 반환합니다.

VideoFrame 닫기 (frame 포함)
  1. frame[[resource reference]]null을 할당합니다.

  2. frame[[Detached]]true를 할당합니다.

  3. frameformatnull을 할당합니다.

  4. frame[[coded width]], [[coded height]], [[visible left]], [[visible top]], [[visible width]], [[visible height]], [[rotation]], [[display width]], [[display height]]0을 할당합니다.

  5. frame[[flip]]false를 할당합니다.

  6. frame.[[metadata]]에 새로운 VideoFrameMetadata를 할당합니다.

회전값 파싱 (rotation 포함)
  1. alignedRotationrotation에 가장 가까운 90의 배수로, 동점은 양의 방향으로 반올림하여 둡니다.

  2. fullTurnsalignedRotation 이하의 최대 360의 배수로 둡니다.

  3. |alignedRotation| - |fullTurns|을 반환합니다.

회전값 합산 (baseRotation, baseFlip, rotation 포함)
  1. baseFlipfalsecombinedRotation|baseRotation| + |rotation|으로, 아니면 |baseRotation| - |rotation|으로 둡니다.

  2. fullTurnscombinedRotation 이하의 최대 360의 배수로 둡니다.

  3. |combinedRotation| - |fullTurns|을 반환합니다.

VideoFrameCopyToOptions 파싱 (options 포함)
  1. defaultRectvisibleRect의 getter 단계를 수행한 결과로 둡니다.

  2. overrideRectundefined로 둡니다.

  3. options.rect존재하면, 그 값을 overrideRect에 할당합니다.

  4. parsedRectParse Visible Rect 알고리즘을 defaultRect, overrideRect, [[coded width]], [[coded height]], [[format]]와 함께 실행한 결과로 둡니다.

  5. parsedRect가 예외면 parsedRect를 반환합니다.

  6. optLayoutundefined로 둡니다.

  7. options.layout존재하면, 그 값을 optLayout에 할당합니다.

  8. formatundefined로 둡니다.

  9. options.format존재하지 않으면, [[format]]format에 할당합니다.

  10. 그 외에 options.formatRGBA, RGBX, BGRA, BGRX 중 하나와 같으면 options.formatformat에 할당하고, 아니면 NotSupportedError를 반환합니다.

  11. combinedLayoutCompute Layout and Allocation Size 알고리즘을 parsedRect, format, optLayout와 함께 실행한 결과로 둡니다.

  12. combinedLayout을 반환합니다.

Rect 오프셋 정렬 검증 (format, rect 포함)
  1. formatnull이면, true를 반환합니다.

  2. planeIndex0으로 둡니다.

  3. numPlanesformat이 정의하는 plane 개수로 둡니다.

  4. planeIndexnumPlanes보다 작은 동안:

    1. planeformat이 정의하는 planeIndex번째 Plane으로 둡니다.

    2. sampleWidthplane의 각 서브샘플의 수평 sub-sampling factor로 둡니다.

    3. sampleHeightplane의 각 서브샘플의 수직 sub-sampling factor로 둡니다.

    4. rect.xsampleWidth의 배수가 아니면 false를 반환합니다.

    5. rect.ysampleHeight의 배수가 아니면 false를 반환합니다.

    6. planeIndex1을 더해 증가시킵니다.

  5. true를 반환합니다.

가시 사각형 파싱 (defaultRect, overrideRect, codedWidth, codedHeight, format 포함)
  1. sourceRectdefaultRect로 둡니다.

  2. overrideRectundefined가 아니면:

    1. overrideRect.width 또는 height0이면, TypeError를 반환합니다.

    2. overrideRect.xoverrideRect.width 의 합이 codedWidth보다 크면, TypeError를 반환합니다.

    3. overrideRect.yoverrideRect.height 의 합이 codedHeight보다 크면, TypeError를 반환합니다.

    4. sourceRectoverrideRect를 할당합니다.

  3. validAlignmentRect 오프셋 정렬 검증 알고리즘을 format, sourceRect와 함께 실행한 결과로 둡니다.

  4. validAlignmentfalseTypeError를 던집니다.

  5. sourceRect를 반환합니다.

레이아웃 및 할당 크기 계산 (parsedRect, format, layout 포함)
  1. numPlanesformat이 정의하는 plane 개수로 둡니다.

  2. layoutundefined가 아니고 길이가 numPlanes과 같지 않으면, TypeError를 던집니다.

  3. minAllocationSize0으로 둡니다.

  4. computedLayouts를 새로운 목록으로 둡니다.

  5. endOffsets를 새로운 목록으로 둡니다.

  6. planeIndex0으로 둡니다.

  7. planeIndex < numPlanes 동안:

    1. planeformat이 정의하는 planeIndex번째 Plane으로 둡니다.

    2. sampleBytesplane의 샘플당 바이트 수로 둡니다.

    3. sampleWidthplane의 각 서브샘플의 수평 sub-sampling factor로 둡니다.

    4. sampleHeightplane의 각 서브샘플의 수직 sub-sampling factor로 둡니다.

    5. computedLayout를 새로운 computed plane layout으로 둡니다.

    6. computedLayoutsourceTopparsedRect.y의 절삭값을 sampleHeight로 나눈 값을 올림하여 할당합니다.

    7. computedLayoutsourceHeightparsedRect.height의 절삭값을 sampleHeight로 나눈 값을 올림하여 할당합니다.

    8. computedLayoutsourceLeftBytesparsedRect.x의 절삭값을 sampleWidth로 나눈 후 sampleBytes를 곱한 값을 할당합니다.

    9. computedLayoutsourceWidthBytesparsedRect.width의 절삭값을 sampleWidth로 나눈 후 sampleBytes를 곱한 값을 할당합니다.

    10. layoutundefined가 아니면:

      1. planeLayoutlayoutplaneIndex 위치의 PlaneLayout으로 둡니다.

      2. planeLayout.stridecomputedLayoutsourceWidthBytes보다 작으면 TypeError를 반환합니다.

      3. planeLayout.offsetcomputedLayoutdestinationOffset에 할당합니다.

      4. planeLayout.stridecomputedLayoutdestinationStride에 할당합니다.

    11. 그 외의 경우:

      참고: 명시적 레이아웃이 없으면 아래 단계는 타이트 패킹을 기본으로 합니다.

      1. minAllocationSizecomputedLayoutdestinationOffset에 할당합니다.

      2. computedLayoutsourceWidthBytescomputedLayoutdestinationStride에 할당합니다.

    12. planeSizecomputedLayoutdestinationStridesourceHeight의 곱으로 둡니다.

    13. planeEndplaneSizecomputedLayoutdestinationOffset의 합으로 둡니다.

    14. planeSize 또는 planeEndunsigned long의 최대 범위를 초과하면 TypeError를 반환합니다.

    15. endOffsetsplaneEnd를 추가합니다.

    16. minAllocationSizeplaneEnd 중 큰 값을 minAllocationSize에 할당합니다.

      참고: 위 단계는 사용자가 지정한 plane offset이 plane의 순서를 바꿀 수 있음을 고려해 최대값을 사용합니다.

    17. earlierPlaneIndex0으로 둡니다.

    18. earlierPlaneIndexplaneIndex보다 작은 동안:

      1. earlierLayoutcomputedLayouts[earlierPlaneIndex]로 둡니다.

      2. endOffsets[planeIndex]earlierLayoutdestinationOffset 이하이거나 endOffsets[earlierPlaneIndex]computedLayoutdestinationOffset 이하이면 continue.

        참고: plane A가 plane B 시작 전에 끝나면 겹치지 않습니다.

      3. 그 외의 경우 TypeError를 반환합니다.

      4. earlierPlaneIndex1을 더해 증가시킵니다.

    19. computedLayoutscomputedLayout을 추가합니다.

    20. planeIndex1을 더해 증가시킵니다.

  8. combinedLayout를 새로운 combined buffer layout으로, 다음과 같이 초기화합니다:

    1. computedLayoutscomputedLayouts에 할당합니다.

    2. minAllocationSizeallocationSize에 할당합니다.

  9. combinedLayout을 반환합니다.

PredefinedColorSpace를 VideoColorSpace로 변환 (colorSpace 포함)
  1. 단언: colorSpacesrgb 또는 display-p3와 같아야 합니다.

  2. colorSpacesrgb와 같으면 새로운 sRGB Color Space 인스턴스를 반환합니다.

  3. colorSpacedisplay-p3와 같으면 새로운 Display P3 Color Space 인스턴스를 반환합니다.

RGB 프레임으로 변환 (frame, format, colorSpace 포함)
  1. 이 알고리즘은 formatRGBA, RGBX, BGRA, BGRX 중 하나와 같을 때만 반드시 호출되어야 합니다.

  2. convertedFrame을 다음과 같이 생성된 새로운 VideoFrame으로 둡니다:

    1. [[Detached]]false를 할당합니다.

    2. [[format]]format을 할당합니다.

    3. widthframe[[visible width]]로 둡니다.

    4. heightframe[[visible height]]로 둡니다.

    5. [[coded width]], [[coded height]], [[visible left]], [[visible top]], [[visible width]], [[visible height]], [[display width]], [[display height]]에 각각 width, height, 0, 0, width, height, width, height를 할당합니다.

    6. frame[[duration]]frame[[timestamp]]를 각각 [[duration]][[timestamp]]에 할당합니다.

    7. PredefinedColorSpace를 VideoColorSpace로 변환 알고리즘을 colorSpace와 함께 실행한 결과를 [[color space]]에 할당합니다.

    8. resourcemedia resource로, frame[[resource reference]]가 참조하는 media resource[[color space]][[format]]에 지정된 색상 공간 및 픽셀 포맷으로 변환한 결과를 포함하도록 생성합니다.

    9. resource에 대한 참조를 [[resource reference]]에 할당합니다.

  3. convertedFrame을 반환합니다.

VideoFrame 메타데이터 복사 (metadata 포함)
  1. metadataCopySerializedStructuredSerialize(metadata)로 둡니다.

  2. metadataCopyStructuredDeserialize(metadataCopySerialized, 현재 Realm)로 둡니다.

  3. metadataCopy를 반환합니다.

이 알고리즘의 목적은 VideoFrame이 소유한 메타데이터가 불변임을 보장하는 것입니다.

9.4.7. 전송 및 직렬화

VideoFrame 전송 단계 (value, dataHolder 포함) :
  1. value[[Detached]] 값이 true이면, DataCloneError DOMException을 throw합니다.

  2. 모든 VideoFrame 내부 슬롯에 대해, value의 각 내부 슬롯 값을 동일한 이름의 필드에 dataHolder에 할당합니다.

  3. Close VideoFrame 알고리즘을 value로 실행합니다.

VideoFrame 전송-수신 단계 (dataHolder, value 포함) :
  1. dataHolder의 모든 필드에 대해, 각 필드 값을 value의 이름이 같은 VideoFrame 내부 슬롯에 할당합니다.

VideoFrame 직렬화 단계 (value, serialized, forStorage 포함) :
  1. value[[Detached]] 값이 true이면, DataCloneError DOMException을 throw합니다.

  2. forStoragetrue이면 DataCloneError를 throw합니다.

  3. resourcevalue[[resource reference]]가 참조하는 media resource로 둡니다.

  4. newReferenceresource에 대한 새 참조로 둡니다.

  5. newReference를 |serialized.resource reference|에 할당합니다.

  6. 남은 모든 VideoFrame 내부 슬롯(단, [[resource reference]] 제외)을 value에서 동일한 이름의 필드로 serialized에 할당합니다.

VideoFrame 역직렬화 단계 (serialized, value 포함) :
  1. serialized의 모든 필드에 대해, 각 필드 값을 value의 이름이 같은 VideoFrame 내부 슬롯에 할당합니다.

9.4.8. 렌더링

렌더링 시에는, 예를 들어 CanvasDrawImage drawImage() 등에서, VideoFrame 은 렌더링 타겟과 호환되는 색상 공간으로 변환되어야 하며, 색상 변환이 명시적으로 비활성화된 경우를 제외합니다.

ImageBitmap 생성 중 색상 공간 변환은 ImageBitmapOptionscolorSpaceConversion 값에 의해 제어됩니다. 이 값을 "none" 으로 지정하면 색상 공간 변환이 비활성화됩니다.

VideoFrame 의 렌더링은 media resource에서 생성되며, 필요한 색상 공간 변환을 적용하고, visibleRect로 크롭, rotation 만큼 시계 방향 회전, fliptrue면 수평 플립을 적용하여 처리됩니다.

9.5. VideoFrame CopyTo() 옵션

복사할 픽셀 사각형, 포맷, 목적지 버퍼에서 plane의 offset과 stride를 지정하는 옵션입니다.
dictionary VideoFrameCopyToOptions {
  DOMRectInit rect;
  sequence<PlaneLayout> layout;
  VideoPixelFormat format;
  PredefinedColorSpace colorSpace;
};
참고: copyTo() 또는 allocationSize() 단계는 아래 요구 조건을 강제합니다:
rect, 타입 DOMRectInit

DOMRectInit으로 복사할 픽셀 사각형을 설명합니다. VideoFrame에서 복사합니다. 지정하지 않으면 visibleRect가 사용됩니다.

참고: coded rectangle은 VideoFramecodedRect를 전달해 지정할 수 있습니다.

참고: 기본 rect 는 샘플 정렬 요구를 반드시 만족하지 않으므로, copyTo() 또는 allocationSize() 호출 시 reject될 수 있습니다.

layout, 타입 sequence<PlaneLayout>

VideoFrame의 plane에 대해 PlaneLayout을 제공합니다. 목적지 BufferSource에서 각 plane의 offset과 stride를 지정할 수 있습니다. 지정하지 않으면 plane들은 타이트 패킹됩니다. plane들이 겹치도록 지정하는 것은 유효하지 않습니다.

format, 타입 VideoPixelFormat

목적지 BufferSource의 픽셀 데이터에 사용할 VideoPixelFormat입니다. 가능한 값: RGBA, RGBX, BGRA, BGRX. 존재하지 않으면, 목적지 BufferSourceformat과 동일한 포맷을 사용합니다.

colorSpace, 타입 PredefinedColorSpace

목적지 BufferSource의 픽셀 데이터에 대해 반드시 사용해야 하는 대상 색상 공간 PredefinedColorSpace입니다. 단, formatRGBA, RGBX, BGRA, BGRX 중 하나일 때만 적용됩니다. 그 외에는 무시됩니다. 존재하지 않으면 srgb가 사용됩니다.

9.6. VideoFrame의 DOMRect

VideoFrame 인터페이스는 사각형 픽셀의 위치와 크기를 지정하기 위해 DOMRect를 사용합니다. DOMRectInitcopyTo()allocationSize() 에서 소스 사각형의 크기를 설명하는 데 사용됩니다. VideoFramecodedRectvisibleRect 를 각각 coded 크기와 가시 영역을 편리하게 복사할 수 있도록 정의합니다.

참고: VideoFrame의 픽셀은 정수로만 접근할 수 있습니다. DOMRectInit에 제공된 모든 부동 소수점 값은 버림됩니다.

9.7. 플레인 레이아웃

PlaneLayoutVideoFrame plane이 BufferSource로 복사될 때의 offset과 stride를 지정하는 딕셔너리입니다. PlaneLayout의 시퀀스를 제공할 수 있습니다 VideoFramecopyTo() 에, plane이 목적지 BufferSource에 어떻게 배치될지 지정할 수 있습니다. 또는 호출자는 copyTo()가 반환한 PlaneLayout 시퀀스를 검사하여 User Agent가 결정한 각 plane의 offset과 stride를 확인할 수 있습니다.
dictionary PlaneLayout {
  [EnforceRange] required unsigned long offset;
  [EnforceRange] required unsigned long stride;
};
offset, 타입 unsigned long

해당 plane이 BufferSource 내에서 시작되는 바이트 offset입니다.

stride, 타입 unsigned long

BufferSource 내에서 plane의 각 row가 사용하는(패딩 포함) 바이트 수입니다.

9.8. 픽셀 포맷

픽셀 포맷은 각 plane의 바이트 배치와 plane의 개수, 순서를 설명합니다. 각 포맷은 별도의 세부 섹션에서 설명됩니다.
enum VideoPixelFormat {
  // 4:2:0 Y, U, V
  "I420",
  "I420P10",
  "I420P12",
  // 4:2:0 Y, U, V, A
  "I420A",
  "I420AP10",
  "I420AP12",
  // 4:2:2 Y, U, V
  "I422",
  "I422P10",
  "I422P12",
  // 4:2:2 Y, U, V, A
  "I422A",
  "I422AP10",
  "I422AP12",
  // 4:4:4 Y, U, V
  "I444",
  "I444P10",
  "I444P12",
  // 4:4:4 Y, U, V, A
  "I444A",
  "I444AP10",
  "I444AP12",
  // 4:2:0 Y, UV
  "NV12",
  // 4:4:4 RGBA
  "RGBA",
  // 4:4:4 RGBX (opaque)
  "RGBX",
  // 4:4:4 BGRA
  "BGRA",
  // 4:4:4 BGRX (opaque)
  "BGRX",
};

Sub-sampling은 단일 샘플이 최종 이미지의 여러 픽셀에 대한 정보를 포함하는 기술입니다. Sub-sampling은 수평, 수직 또는 둘 다일 수 있으며, factor를 가지는데, 이는 sub-sampled 샘플로부터 유도된 최종 이미지의 픽셀 수를 의미합니다.

만약 VideoFrameI420 포맷이라면, 두 번째 플레인(U 플레인)의 매우 첫 번째 컴포넌트는 이미지의 좌상단에 있는 네 픽셀에 해당합니다. 결과적으로 두 번째 행의 첫 번째 컴포넌트는 그 처음 네 개의 좌상단 픽 아래에 있는 네 픽셀에 해당합니다. sub-sampling factor는 가로와 세로 방향 모두에서 2입니다.

만약 VideoPixelFormat 에 알파 컴포넌트가 있다면, 그 포맷의 equivalent opaque format은 알파 컴포넌트가 제거된 동일한 VideoPixelFormat입니다. 만약 VideoPixelFormat 에 알파 컴포넌트가 없다면, 그것 자체가 equivalent opaque format입니다.

정수 값은 달리 명시되지 않는 한 부호 없는 값입니다.

I420
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다. 종종 Planar YUV 4:2:0으로도 불립니다.

U 및 V 플레인은 Y 플레인과 비교하여 수평 및 수직으로 sub-sampled 되며, factor는 2입니다.

이 포맷에서 각 샘플은 8비트입니다.

Y 플레인에는 codedWidth * codedHeight 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 행 수가 codedHeight 를 2로 나눈 결과의 올림값과 같고, 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형 오프셋(visibleRect.xvisibleRect.y) 는 MUST 짝수여야 합니다.

I420P10
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

U 및 V 플레인은 Y 플레인과 비교하여 수평 및 수직으로 sub-sampled 되며, factor는 2입니다.

이 포맷에서 각 샘플은 10비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

Y 플레인에는 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 행 수가 codedHeight 를 2로 나눈 결과의 올림값과 같고, 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형 오프셋(visibleRect.xvisibleRect.y) 는 MUST 짝수여야 합니다.

I420P12
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

U 및 V 플레인은 Y 플레인과 비교하여 수평 및 수직으로 sub-sampled 되며, factor는 2입니다.

이 포맷에서 각 샘플은 12비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

Y 플레인에는 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 행 수가 codedHeight 를 2로 나눈 결과의 올림값과 같고, 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형 오프셋(visibleRect.xvisibleRect.y) 는 MUST 짝수여야 합니다.

I420A
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 그리고 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다. 종종 알파 채널을 가진 Planar YUV 4:2:0으로도 불립니다.

U 및 V 플레인은 Y 및 Alpha 플레인과 비교하여 수평 및 수직으로 sub-sampled 되며, factor는 2입니다.

이 포맷에서 각 샘플은 8비트입니다.

Y 및 Alpha 플레인에는 codedWidth * codedHeight 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 행 수가 codedHeight 를 2로 나눈 결과의 올림값과 같고, 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형 오프셋(visibleRect.xvisibleRect.y) 는 MUST 짝수여야 합니다.

I420Aequivalent opaque formatI420입니다.

I420AP10
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 그리고 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

U 및 V 플레인은 Y 및 Alpha 플레인과 비교하여 수평 및 수직으로 sub-sampled 되며, factor는 2입니다.

이 포맷에서 각 샘플은 10비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

Y 및 Alpha 플레인에는 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 행 수가 codedHeight 를 2로 나눈 결과의 올림값과 같고, 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형 오프셋(visibleRect.xvisibleRect.y) 는 MUST 짝수여야 합니다.

I420AP10equivalent opaque formatI420P10입니다.

I420AP12
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인 및 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

U 및 V 플레인은 Y 및 Alpha 플레인과 비교하여 수평 및 수직으로 sub-sampled 되며, factor는 2입니다.

이 포맷에서 각 샘플은 12비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

Y 및 Alpha 플레인에는 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 행 수가 codedHeight 를 2로 나눈 결과의 올림값과 같고, 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형 오프셋(visibleRect.xvisibleRect.y) 는 MUST 짝수여야 합니다.

I420AP12equivalent opaque formatI420P12입니다.

I422
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다. 종종 Planar YUV 4:2:2로 불립니다.

U 및 V 플레인은 Y 플레인과 비교하여 수평으로는 sub-sampled 되며 그 factor는 2입니다. 수직으로는 sub-sampled 되지 않습니다.

이 포맷에서 각 샘플은 8비트입니다.

Y 플레인에는 codedWidth * codedHeight 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 codedHeight 개의 행을 가집니다. 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형의 수평 오프셋(visibleRect.x) 는 MUST 짝수여야 합니다.

I422P10
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

U 및 V 플레인은 Y 플레인과 비교하여 수평으로 sub-sampled 되며 그 factor는 2입니다. 수직으로는 sub-sampled 되지 않습니다.

이 포맷에서 각 샘플은 10비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

Y 플레인에는 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 codedHeight 개의 행을 가집니다. 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형의 수평 오프셋(visibleRect.x) 는 MUST 짝수여야 합니다.

I422P12
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

U 및 V 플레인은 Y 플레인과 비교하여 수평으로 sub-sampled 되며 그 factor는 2입니다. 수직으로는 sub-sampled 되지 않습니다.

이 포맷에서 각 샘플은 12비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

Y 플레인에는 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 codedHeight 개의 행을 가집니다. 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형의 수평 오프셋(visibleRect.x) 는 MUST 짝수여야 합니다.

I422A
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 그리고 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다. 종종 알파 채널을 가진 Planar YUV 4:2:2로도 불립니다.

U 및 V 플레인은 Y 및 Alpha 플레인과 비교하여 수평으로 sub-sampled 되며 그 factor는 2입니다. 수직으로는 sub-sampled 되지 않습니다.

이 포맷에서 각 샘플은 8비트입니다.

Y 및 Alpha 플레인에는 codedWidth * codedHeight 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 codedHeight 개의 행을 가집니다. 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형의 수평 오프셋(visibleRect.x) 는 MUST 짝수여야 합니다.

I422Aequivalent opaque formatI422입니다.

I422AP10
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 그리고 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

U 및 V 플레인은 Y 및 Alpha 플레인과 비교하여 수평으로 sub-sampled 되며 그 factor는 2입니다. 수직으로는 sub-sampled 되지 않습니다.

이 포맷에서 각 샘플은 10비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

Y 및 Alpha 플레인에는 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 codedHeight 개의 행을 가집니다. 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형의 수평 오프셋(visibleRect.x) 는 MUST 짝수여야 합니다.

I422AP10equivalent opaque formatI420P10입니다.

I422AP12
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인 및 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

U 및 V 플레인은 Y 및 Alpha 플레인과 비교하여 수평으로 sub-sampled 되며 그 factor는 2입니다. 수직으로는 sub-sampled 되지 않습니다.

이 포맷에서 각 샘플은 12비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

Y 및 Alpha 플레인에는 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

U 및 V 플레인은 codedHeight 개의 행을 가집니다. 각 행의 샘플 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형의 수평 오프셋(visibleRect.x) 는 MUST 짝수여야 합니다.

I422AP10equivalent opaque formatI420P10입니다.

I444
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다. 종종 Planar YUV 4:4:4로 불립니다.

이 포맷은 sub-sampling을 사용하지 않습니다.

이 포맷에서 각 샘플은 8비트입니다.

세 플레인 모두에 codedWidth * codedHeight 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

I444P10
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

이 포맷은 sub-sampling을 사용하지 않습니다.

이 포맷에서 각 샘플은 10비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

세 플레인 모두에 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

I444P12
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 총 세 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

이 포맷은 sub-sampling을 사용하지 않습니다.

이 포맷에서 각 샘플은 12비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

세 플레인 모두에 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

I444A
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 그리고 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

이 포맷은 sub-sampling을 사용하지 않습니다.

이 포맷에서 각 샘플은 8비트입니다.

네 플레인 모두에 codedWidth * codedHeight 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

I444Aequivalent opaque formatI444입니다.

I444AP10
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인, 그리고 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

이 포맷은 sub-sampling을 사용하지 않습니다.

이 포맷에서 각 샘플은 10비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

네 플레인 모두에 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

I444AP10equivalent opaque formatI444P10입니다.

I444AP12
이 포맷은 Y, U, V로 표시되는 하나의 Luma 플레인과 두 개의 Chroma 플레인 및 하나의 Alpha 플레인 등 네 개의 별도 플레인으로 구성되며, 이 순서로 존재합니다.

이 포맷은 sub-sampling을 사용하지 않습니다.

이 포맷에서 각 샘플은 12비트이며, 리틀 엔디언 바이트 순서의 16비트 정수로 인코딩됩니다.

네 플레인 모두에 codedWidth * codedHeight 샘플이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

I444AP10equivalent opaque formatI444P10입니다.

NV12
이 포맷은 Y 플레인 하나와 두 Chroma 컴포넌트를 위한 또 다른 플레인, 총 두 개의 별도 플레인으로 구성됩니다. 이 두 플레인은 이 순서로 존재하며, 각각 Y 플레인과 UV 플레인이라고 칭합니다.

U 및 V 컴포넌트는 Y 플레인의 컴포넌트들과 비교하여 수평 및 수직으로 sub-sampled 되며, factor는 2입니다.

이 포맷에서 각 샘플은 8비트입니다.

Y 플레인과 UV 플레인에는 codedWidth * codedHeight 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

UV 플레인은 U와 V 값이 교차(interleaved)된 형태로 구성되며, 행 수는 codedHeight 를 2로 나눈 결과의 올림값과 같고, 각 행의 요소 수는 codedWidth 를 2로 나눈 결과의 올림값과 같습니다. 각 요소는 두 개의 Chroma 샘플(U, V)을 그 순서로 포함합니다. 샘플들은 이미지의 좌상단에서부터 배치됩니다.

가시 사각형 오프셋(visibleRect.xvisibleRect.y) 는 MUST 짝수여야 합니다.

가로 16 픽셀, 세로 10 픽인 NV12 픽셀 포맷 이미지는 메모리상에서 다음과 같이 배치됩니다:
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
YYYYYYYYYYYYYYYY
UVUVUVUVUVUVUVUV
UVUVUVUVUVUVUVUV
UVUVUVUVUVUVUVUV
UVUVUVUVUVUVUVUV
UVUVUVUVUVUVUVUV

모든 샘플이 메모리상에서 선형으로 배치됩니다.

RGBA
이 포맷은 Red, Green, Blue 및 알파 값을 이 순서로 인코딩하는 단일 플레인으로 구성됩니다.

이 포맷에서 각 샘플은 8비트이며, 따라서 각 픽셀은 32비트입니다.

단일 플레인에는 codedWidth * codedHeight * 4 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

RGBAequivalent opaque formatRGBX입니다.

RGBX
이 포맷은 Red, Green, Blue 및 패딩 값을 이 순서로 인코딩하는 단일 플레인으로 구성됩니다.

이 포맷에서 각 샘플은 8비트입니다. 각 픽셀의 네 번째 요소는 무시되어야 하며, 이미지는 항상 완전히 불투명합니다.

단일 플레인에는 codedWidth * codedHeight * 4 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

BGRA
이 포맷은 Blue, Green, Red 및 알파 값을 이 순서로 인코딩하는 단일 플레인으로 구성됩니다.

이 포맷에서 각 샘플은 8비트입니다.

단일 플레인에는 codedWidth * codedHeight * 4 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

BGRAequivalent opaque formatBGRX입니다.

BGRX
이 포맷은 Blue, Green, Red 및 패딩 값을 이 순서로 인코딩하는 단일 플레인으로 구성됩니다.

이 포맷에서 각 샘플은 8비트입니다. 각 픽셀의 네 번째 요소는 무시되어야 하며, 이미지는 항상 완전히 불투명합니다.

단일 플레인에는 codedWidth * codedHeight * 4 샘플(따라서 바이트)이 있으며, 이미지의 좌상단에서 시작하여 codedHeight 개의 행에 걸쳐 각 행에 codedWidth 샘플이 배치됩니다.

9.9. 비디오 색상 공간 인터페이스

[Exposed=(Window,DedicatedWorker)]
interface VideoColorSpace {
  constructor(optional VideoColorSpaceInit init = {});

  readonly attribute VideoColorPrimaries? primaries;
  readonly attribute VideoTransferCharacteristics? transfer;
  readonly attribute VideoMatrixCoefficients? matrix;
  readonly attribute boolean? fullRange;

  [Default] VideoColorSpaceInit toJSON();
};

dictionary VideoColorSpaceInit {
  VideoColorPrimaries? primaries = null;
  VideoTransferCharacteristics? transfer = null;
  VideoMatrixCoefficients? matrix = null;
  boolean? fullRange = null;
};

9.9.1. 내부 슬롯

[[primaries]]

색상 프라이머리(primaries)입니다.

[[transfer]]

트랜스퍼 특성입니다.

[[matrix]]

매트릭스 계수입니다.

[[full range]]

풀레인지 색상 값이 사용되는지 여부를 나타냅니다.

9.9.2. 생성자

VideoColorSpace(init)
  1. c를 다음과 같이 초기화된 새로운 VideoColorSpace 객체로 둡니다:

    1. init.primaries[[primaries]]에 할당합니다.

    2. init.transfer[[transfer]]에 할당합니다.

    3. init.matrix[[matrix]]에 할당합니다.

    4. init.fullRange[[full range]]에 할당합니다.

  2. c를 반환합니다.

9.9.3. 속성

primaries, 타입 VideoColorPrimaries, readonly, nullable

primaries getter 단계는 [[primaries]] 값을 반환합니다.

transfer, 타입 VideoTransferCharacteristics, readonly, nullable

transfer getter 단계는 [[transfer]] 값을 반환합니다.

matrix, 타입 VideoMatrixCoefficients, readonly, nullable

matrix getter 단계는 [[matrix]] 값을 반환합니다.

fullRange, 타입 boolean, readonly, nullable

fullRange getter 단계는 [[full range]] 값을 반환합니다.

9.10. 비디오 색상 프라이머리

색상 프라이머리는 비디오 샘플의 색상 감마(gamut)를 설명합니다.
enum VideoColorPrimaries {
  "bt709",
  "bt470bg",
  "smpte170m",
  "bt2020",
  "smpte432",
};
bt709
BT.709 및 sRGB에서 사용되는 색상 프라이머리. [H.273] 섹션 8.1 테이블 2 값 1에 기술됨.
bt470bg
BT.601 PAL에서 사용되는 색상 프라이머리. [H.273] 섹션 8.1 테이블 2 값 5에 기술됨.
smpte170m
BT.601 NTSC에서 사용되는 색상 프라이머리. [H.273] 섹션 8.1 테이블 2 값 6에 기술됨.
bt2020
BT.2020 및 BT.2100에서 사용되는 색상 프라이머리. [H.273] 섹션 8.1 테이블 2 값 9에 기술됨.
smpte432
P3 D65에서 사용되는 색상 프라이머리. [H.273] 섹션 8.1 테이블 2 값 12에 기술됨.

9.11. 비디오 트랜스퍼 특성

트랜스퍼 특성은 비디오 샘플의 광전자 트랜스퍼 특성(opto-electronic transfer characteristics)을 설명합니다.
enum VideoTransferCharacteristics {
  "bt709",
  "smpte170m",
  "iec61966-2-1",
  "linear",
  "pq",
  "hlg",
};
bt709
BT.709에서 사용되는 트랜스퍼 특성. [H.273] 섹션 8.2 테이블 3 값 1에 기술됨.
smpte170m
BT.601에서 사용되는 트랜스퍼 특성. [H.273] 섹션 8.2 테이블 3 값 6에 기술됨. ("bt709"와 기능적으로 동일함.)
iec61966-2-1
sRGB에서 사용되는 트랜스퍼 특성. [H.273] 섹션 8.2 테이블 3 값 13에 기술됨.
linear
선형 RGB에서 사용되는 트랜스퍼 특성. [H.273] 섹션 8.2 테이블 3 값 8에 기술됨.
pq
BT.2100 PQ에서 사용되는 트랜스퍼 특성. [H.273] 섹션 8.2 테이블 3 값 16에 기술됨.
hlg
BT.2100 HLG에서 사용되는 트랜스퍼 특성. [H.273] 섹션 8.2 테이블 3 값 18에 기술됨.

9.12. 비디오 매트릭스 계수

매트릭스 계수는 샘플 컴포넌트 값과 색상 좌표의 관계를 설명합니다.
enum VideoMatrixCoefficients {
  "rgb",
  "bt709",
  "bt470bg",
  "smpte170m",
  "bt2020-ncl",
};
rgb
sRGB에서 사용되는 매트릭스 계수. [H.273] 섹션 8.3 테이블 4 값 0에 기술됨.
bt709
BT.709에서 사용되는 매트릭스 계수. [H.273] 섹션 8.3 테이블 4 값 1에 기술됨.
bt470bg
BT.601 PAL에서 사용되는 매트릭스 계수. [H.273] 섹션 8.3 테이블 4 값 5에 기술됨.
smpte170m
BT.601 NTSC에서 사용되는 매트릭스 계수. [H.273] 섹션 8.3 테이블 4 값 6에 기술됨. ("bt470bg"와 기능적으로 동일함.)
bt2020-ncl
BT.2020 NCL에서 사용되는 매트릭스 계수. [H.273] 섹션 8.3 테이블 4 값 9에 기술됨.

10. 이미지 디코딩

10.1. 배경

이 섹션은 비규범적입니다.

이미지 코덱 정의는 일반적으로 해당 파일 포맷 정의와 함께 제공됩니다. 따라서 이미지 디코더는 인코딩된 이미지 데이터를 언팩(디멕싱)과 디코딩을 모두 수행하는 경우가 많습니다. WebCodecs의 ImageDecoder 는 이러한 패턴을 따르며, VideoDecoderAudioDecoder와 현저히 다른 인터페이스 디자인을 채택하게 됩니다.

이러한 차이에도 불구하고 ImageDecoder 는 다른 코덱 인터페이스와 동일한 코덱 처리 모델을 사용합니다. 또한, ImageDecoder 는 디코딩된 출력 설명에 VideoFrame 인터페이스를 사용합니다.

10.2. ImageDecoder 인터페이스

[Exposed=(Window,DedicatedWorker), SecureContext]
interface ImageDecoder {
  constructor(ImageDecoderInit init);

  readonly attribute DOMString type;
  readonly attribute boolean complete;
  readonly attribute Promise<undefined> completed;
  readonly attribute ImageTrackList tracks;

  Promise<ImageDecodeResult> decode(optional ImageDecodeOptions options = {});
  undefined reset();
  undefined close();

  static Promise<boolean> isTypeSupported(DOMString type);
};

10.2.1. 내부 슬롯

[[control message queue]]

codec 인스턴스에서 수행될 queue 형태의 control message 목록입니다. [[control message queue]]를 참조하세요.

[[message queue blocked]]

[[control message queue]] 처리 중에 control message 대기 때문에 차단되고 있는지를 나타내는 불리언입니다. [[message queue blocked]]를 참조하세요.

[[codec work queue]]

parallel queue로, [[codec implementation]]을 참조하는 병렬 단계 실행에 사용됩니다. [[codec work queue]]를 참조하세요.

[[ImageTrackList]]

ImageTrackList로, [[encoded data]]에서 발견된 트랙들을 설명합니다.

[[type]]

생성 시 전달된 MIME type 값을 반영하는 문자열입니다.

[[complete]]

[[encoded data]]가 완전히 버퍼링되었는지 나타내는 불리언입니다.

[[completed promise]]

[[complete]]true가 될 때 신호로 사용되는 promise입니다.

[[codec implementation]]

User Agent가 제공하는 실제 이미지 디코더 구현입니다. [[codec implementation]]를 참조하세요.

[[encoded data]]

디코딩할 인코딩된 이미지 데이터가 들어있는 byte sequence입니다.

[[prefer animation]]

생성 시 전달된 preferAnimation 값을 반영하는 불리언입니다.

[[pending decode promises]]

decode() 호출로 반환된 미해결 promise들의 목록입니다.

[[internal selected track index]]

디코딩 알고리즘에서 사용할 [[encoded data]] 내 이미지 트랙을 식별합니다.

[[tracks established]]

[[ImageTrackList]] 내 트랙 리스트가 확정되었는지 나타내는 불리언입니다.

[[closed]]

ImageDecoder가 영구적으로 닫혀 더 이상 사용할 수 없는지 나타내는 불리언입니다.

[[progressive frame generations]]

프레임 인덱스를 Progressive Image Frame Generations에 매핑합니다. 값은 해당 프레임 인덱스로 decode() 호출 시 최근에 출력된 VideoFrame의 Progressive Image Frame Generation을 나타냅니다.

10.2.2. 생성자

ImageDecoder(init)

참고: 생성된 ImageDecoder에서 decode()를 호출하면 User Agent가 type을 지원하지 않을 경우 NotSupportedError가 발생합니다. 작성자는 먼저 isTypeSupported()type 지원 여부를 확인하는 것이 권장됩니다. User Agent는 특정 타입을 반드시 지원할 필요는 없습니다.

호출 시 다음 단계를 실행합니다:

  1. initvalid ImageDecoderInit이 아니면 TypeError를 throw합니다.

  2. init.transfer 에 동일한 ArrayBuffer가 둘 이상 참조되면 DataCloneError DOMException을 throw합니다.

  3. init.transfer의 각 transferable에 대해:

    1. [[Detached]] 내부 슬롯이 true이면 DataCloneError DOMException을 throw합니다.

  4. d를 새로운 ImageDecoder 객체로 둡니다. 아래 단계의 모든 ImageDecoder 멤버 참조는 명시되지 않는 한 d에 적용됩니다.

  5. [[control message queue]]에 새로운 queue를 할당합니다.

  6. [[message queue blocked]]false를 할당합니다.

  7. 새로운 parallel queue의 시작 결과를 [[codec work queue]]에 할당합니다.

  8. [[ImageTrackList]]에 다음과 같이 초기화된 새로운 ImageTrackList를 할당합니다:

    1. [[track list]]에 새로운 list를 할당합니다.

    2. [[selected index]]-1을 할당합니다.

  9. type[[type]]에 할당합니다.

  10. [[codec implementation]]null을 할당합니다.

  11. init.preferAnimation존재하면, init.preferAnimation[[prefer animation]] 내부 슬롯에 할당하고, 그렇지 않으면 [[prefer animation]] 내부 슬롯에 'null'을 할당합니다.

  12. [[pending decode promises]]에 새로운 list를 할당합니다.

  13. [[internal selected track index]]-1을 할당합니다.

  14. [[tracks established]]false를 할당합니다.

  15. [[closed]]false를 할당합니다.

  16. [[progressive frame generations]]에 새로운 map을 할당합니다.

  17. initdata 멤버 타입이 ReadableStream이면:

    1. [[encoded data]]에 새로운 list를 할당합니다.

    2. [[complete]]false를 할당합니다.

    3. Queue a control messageconfigure the image decoderinit과 함께 큐에 추가합니다.

    4. Process the control message queue를 실행합니다.

    5. readerdatareader 가져오기 결과로 둡니다.

    6. 병렬로 Fetch Stream Data Loopdreader로 실행합니다.

  18. 그 외의 경우:

    1. init.dataBufferSource 타입임을 단언합니다.

    2. init.transferinit.data가 참조한 ArrayBuffer가 포함되면 User Agent는 선택적으로:

      1. [[encoded data]]가 인코딩된 이미지를 나타내는 data의 바이트를 참조하도록 둡니다.

    3. 그 외의 경우:

      1. init.data의 복사본을 [[encoded data]]에 할당합니다.

    4. [[complete]]true를 할당합니다.

    5. [[completed promise]]를 resolve합니다.

    6. configure the image decoderinit으로 제어 메시지 큐에 추가합니다.

    7. decode track metadata를 제어 메시지 큐에 추가합니다.

    8. Process the control message queue를 실행합니다.

  19. init.transfer의 각 transferable에 대해:

    1. transferable에 대해 DetachArrayBuffer를 수행합니다.

  20. d를 반환합니다.

제어 메시지 실행으로 configure the image decoder 를 실행한다는 것은 다음 단계를 수행하는 것입니다:

  1. init.type을 사용하여 Check Type Support 알고리즘을 실행한 결과를 supported로 둡니다.

  2. supportedfalse이면 Close ImageDecoder 알고리즘을 NotSupportedError DOMException과 함께 실행하고 "processed"를 반환합니다.

  3. 그 외의 경우 [[codec implementation]] 내부 슬롯에 init.type을 지원하는 구현을 할당합니다.

  4. [[message queue blocked]]true를 할당합니다.

  5. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. [[codec implementation]]colorSpaceConversion, desiredWidth, desiredHeight 값에 따라 설정합니다.

    2. [[message queue blocked]]false를 할당합니다.

    3. Queue a taskProcess the control message queue를 실행합니다.

  6. "processed"를 반환합니다.

제어 메시지 실행으로 decode track metadata 를 실행한다는 것은 다음 단계를 수행하는 것입니다:

  1. [[codec work queue]]에 다음 단계들을 큐에 추가합니다:

    1. Establish Tracks 알고리즘을 실행합니다.

10.2.3. 속성

type, 타입 DOMString, 읽기 전용

생성 시 전달된 MIME type 값을 반영하는 문자열입니다.

type getter 단계는 [[type]] 값을 반환합니다.

complete, 타입 boolean, 읽기 전용

[[encoded data]]가 완전히 버퍼링되었는지 여부를 나타냅니다.

complete getter 단계는 [[complete]] 값을 반환합니다.

completed, 타입 Promise<undefined>, 읽기 전용

completetrue가 될 때 신호로 사용되는 promise입니다.

completed getter 단계는 [[completed promise]] 값을 반환합니다.

tracks, 타입 ImageTrackList, 읽기 전용

사용 가능한 트랙에 대한 메타데이터와 디코딩할 트랙을 선택하는 메커니즘을 제공하는 라이브 ImageTrackList를 반환합니다.

tracks getter 단계는 [[ImageTrackList]] 값을 반환합니다.

10.2.4. 메서드

decode(options)

프레임을 options에 따라 디코드하는 제어 메시지를 큐에 추가합니다.

호출 시 다음 단계를 실행합니다:

  1. [[closed]] 값이 true이면 PromiseInvalidStateError DOMException과 함께 reject하여 반환합니다.

  2. [[ImageTrackList]][[selected index]] 값이 '-1'이면 PromiseInvalidStateError DOMException과 함께 reject하여 반환합니다.

  3. optionsundefined이면 새로운 ImageDecodeOptionsoptions에 할당합니다.

  4. promise를 새로운 Promise로 둡니다.

  5. promise[[pending decode promises]]에 추가합니다.

  6. 제어 메시지 큐에 추가optionspromise와 함께 이미지를 디코드하는 제어 메시지를 큐에 추가합니다.

  7. 제어 메시지 큐 처리를 실행합니다.

  8. promise를 반환합니다.

제어 메시지 실행으로 이미지 디코드란 다음 단계를 수행하는 것입니다:

  1. [[codec work queue]]에 다음 단계를 큐에 추가합니다:

    1. [[tracks established]] 값이 true가 될 때까지 대기합니다.

    2. options.completeFramesOnly 값이 false이고 이미지가 User Agent가 프로그레시브 디코딩을 지원하는 프로그레시브 이미지라면, Decode Progressive Frame 알고리즘을 options.frameIndexpromise와 함께 실행합니다.

    3. 그 외의 경우, Decode Complete Frame 알고리즘을 options.frameIndexpromise와 함께 실행합니다.

reset()

모든 대기 작업을 즉시 중단합니다.

호출 시 Reset ImageDecoder 알고리즘을 AbortError DOMException과 함께 실행합니다.

close()

모든 대기 작업을 즉시 중단하고 시스템 리소스를 해제합니다. close는 최종적입니다.

호출 시 Close ImageDecoder 알고리즘을 AbortError DOMException과 함께 실행합니다.

isTypeSupported(type)

제공된 config가 User Agent에 의해 지원되는지 여부를 나타내는 promise를 반환합니다.

호출 시 다음 단계를 실행합니다:

  1. type유효한 이미지 MIME 타입이 아니면 PromiseTypeError와 함께 reject하여 반환합니다.

  2. p를 새로운 Promise로 둡니다.

  3. 병렬로 pCheck Type Support 알고리즘을 type과 함께 실행한 결과로 resolve합니다.

  4. p를 반환합니다.

10.2.5. 알고리즘

Fetch Stream Data Loop (reader 사용)

다음 단계를 실행한다:

  1. readRequest를 다음 read request로 둔다.

    chunk steps, chunk가 주어질 때
    1. [[closed]]true이면, 이 단계들을 중단한다.

    2. chunk가 Uint8Array 객체가 아니면, task를 큐에 넣어 Close ImageDecoder 알고리즘을 DataError DOMException과 함께 실행하고, 이 단계들을 중단한다.

    3. bytes를 Uint8Array 객체가 나타내는 바이트 시퀀스로 둔다.

    4. bytes[[encoded data]] 내부 슬롯에 추가한다.

    5. [[tracks established]]false이면, Establish Tracks 알고리즘을 실행한다.

    6. 그 밖에는 Update Tracks 알고리즘을 실행한다.

    7. Fetch Stream Data Loop 알고리즘을 reader로 다시 실행한다.

    close steps
    1. true[[complete]] 에 할당한다.

    2. [[completed promise]] 를 resolve한다.

    error steps
    1. task를 큐에 넣어 Close ImageDecoder 알고리즘을 NotReadableError DOMException과 함께 실행한다.

  2. reader에서 readRequest를 사용해 chunk를 읽는다.

Establish Tracks

다음 단계를 실행한다:

  1. [[tracks established]]false임을 assert한다.

  2. [[encoded data]] 에서 트랙 수를 판별하기에 충분한 데이터가 없으면:

    1. completetrue이면, task를 큐에 넣어 Close ImageDecoder 알고리즘을 InvalidStateError DOMException과 함께 실행한다.

    2. 이 단계들을 중단한다.

  3. 트랙 수가 0이면, task를 큐에 넣어 Close ImageDecoder 알고리즘을 실행하고 이 단계들을 중단한다.

  4. newTrackList를 새로운 list로 둔다.

  5. [[encoded data]] 에서 발견된 각 image track에 대해:

    1. newTrack를 다음과 같이 초기화된 새로운 ImageTrack로 둔다:

      1. this[[ImageDecoder]]에 할당한다.

      2. tracks[[ImageTrackList]]에 할당한다.

      3. image track이 애니메이션이라면 newTrack[[animated]] 내부 슬롯에 true를 할당하고, 아니면 false를 할당한다.

      4. image track이 frame count를 가지면 그 값을 newTrack[[frame count]]에 할당하고, 아니면 0을 할당한다.

        참고: thisdataReadableStream으로 생성했다면, frameCount 값은 [[encoded data]]에 바이트가 추가될 때 바뀔 수 있다. Update Tracks 알고리즘 참고.

      5. image track이 반복(repetition) 횟수를 가지고 있으면 그 값을 [[repetition count]]에 할당하고, 아니면 0을 할당한다.

        참고: 값이 Infinity이면 무한 반복을 의미한다.

      6. newTrack[[selected]] 내부 슬롯에 false를 할당한다.

    2. newTracknewTrackList에 추가한다.

  6. selectedTrackIndexGet Default Selected Track Index 알고리즘을 newTrackList로 실행한 결과로 둔다.

  7. selectedTracknewTrackList에서 selectedTrackIndex 위치의 트랙으로 둔다.

  8. selectedTrack[[selected]] 내부 슬롯에 true를 할당한다.

  9. [[internal selected track index]]selectedTrackIndex를 할당한다.

  10. [[tracks established]]true를 할당한다.

  11. task를 큐에 넣어 다음 단계를 실행한다:

    1. tracks[[track list]] 내부 슬롯에 newTrackList를 할당한다.

    2. tracks[[selected index]]selectedTrackIndex를 할당한다.

    3. [[ready promise]]를 resolve한다.

기본 선택 트랙 인덱스 가져오기 (trackList와 함께)

다음 단계를 실행합니다:

  1. [[encoded data]]주 이미지 트랙을 식별하면:

    1. primaryTracktrackList에서 ImageTrack주 이미지 트랙을 설명하는 것으로 둡니다.

    2. primaryTrackIndextrackListprimaryTrack의 위치로 둡니다.

    3. [[prefer animation]]null이면 primaryTrackIndex를 반환합니다.

    4. primaryTrack.animated 값이 [[prefer animation]]과 같으면 primaryTrackIndex를 반환합니다.

  2. trackListImageTrackanimated 값이 [[prefer animation]]과 같은 것이 있으면, trackList에서 가장 먼저 등장하는 해당 트랙의 위치를 반환합니다.

  3. 0을 반환합니다.

트랙 업데이트

트랙 업데이트 구조체구조체이며, 트랙 인덱스 (unsigned long) 와 프레임 수 (unsigned long)로 구성됩니다.

다음 단계를 실행합니다:

  1. [[tracks established]]true임을 assert합니다.

  2. trackChanges를 새로운 리스트로 둡니다.

  3. trackListtracks[[track list]]의 복사본으로 둡니다.

  4. trackList의 각 track에 대해:

    1. trackIndextrackList에서 track의 위치로 둡니다.

    2. latestFrameCount[[encoded data]]에서 해당 트랙에 대해 나타내는 프레임 수로 둡니다.

    3. latestFrameCounttrack.frameCount보다 크거나 같음을 assert합니다.

    4. latestFrameCounttrack.frameCount보다 크면:

      1. change트랙 업데이트 구조체로 두고, 트랙 인덱스trackIndex, 프레임 수latestFrameCount로 설정합니다.

      2. changetracksChanges에 추가합니다.

  5. tracksChanges비어있으면 이 단계들을 중단합니다.

  6. 태스크를 큐에 넣어 다음 단계를 실행합니다:

    1. trackChanges의 각 update에 대해:

      1. updateTrackImageTrack에서 update.trackIndex 위치의 트랙으로 둡니다. (tracks[[track list]] 기준)

      2. updateTrack[[frame count]]update.frameCount를 할당합니다.

완전 프레임 디코드 (frameIndexpromise와 함께)
  1. [[tracks established]]true임을 assert합니다.

  2. [[internal selected track index]]-1이 아님을 assert합니다.

  3. encodedFrameframeIndex[[internal selected track index]]로 식별되는 인코딩된 프레임으로 둡니다.

  4. 다음 중 하나가 참이 될 때까지 대기합니다(먼저 발생하는 조건):

    1. [[encoded data]]encodedFrame을 완전히 디코드하기에 충분한 바이트가 포함됨.

    2. [[encoded data]]가 잘못된 형식임이 발견됨.

    3. completetrue임.

    4. [[closed]]true임.

  5. [[encoded data]]가 잘못된 형식임이 발견되면, 치명적 데이터 거부 알고리즘을 실행하고 이 단계들을 중단합니다.

  6. [[encoded data]]encodedFrame을 완전히 디코드하기에 충분한 바이트가 없다면, 불가능한 디코드 거부 알고리즘을 promise와 함께 실행하고 이 단계들을 중단합니다.

  7. [[codec implementation]]을 사용하여 encodedFrame을 디코드 시도합니다.

  8. 디코드 중 오류가 발생하면 치명적 데이터 거부 알고리즘을 실행하고 이 단계들을 중단합니다.

  9. [[progressive frame generations]]frameIndex로 키된 엔트리가 있으면, 맵에서 해당 엔트리를 제거합니다.

  10. output[[codec implementation]]encodedFrame에 대해 내보낸 디코드된 이미지 데이터로 둡니다.

  11. decodeResult를 새로운 ImageDecodeResult로 초기화합니다:

    1. complete에 'true'를 할당합니다.

    2. durationoutput의 표시 지속 시간으로 둡니다. encodedFrame에 duration이 없으면 durationnull을 할당합니다.

    3. timestampoutput의 표시 타임스탬프로 둡니다. encodedFrame에 timestamp가 없으면:

      1. encodedFrame이 정지 이미지면 timestamp0을 할당합니다.

      2. encodedFrame이 일정 속도의 애니메이션 이미지이고 durationnull이 아니면, timestamp|frameIndex| * |duration|을 할당합니다.

      3. 추가 디코드 없이 메타데이터로부터 timestamp를 쉽게 생성할 수 있으면 해당 값을 할당합니다.

      4. 그 외에는 timestamp0을 할당합니다.

    4. [[encoded data]]에 방향 메타데이터가 있으면 rotationflip으로 설명하고, 없으면 rotation은 0, flip은 false로 설정합니다.

    5. image비디오 프레임 생성 알고리즘을 output, timestamp, duration, rotation, flip과 함께 실행한 결과를 할당합니다.

  12. 디코드 완료 처리 알고리즘을 promisedecodeResult로 실행합니다.

점진적 프레임 디코드 (with frameIndexpromise)
  1. [[tracks established]]true임을 단언합니다.

  2. [[internal selected track index]]-1이 아님을 단언합니다.

  3. encodedFrameframeIndex[[internal selected track index]] 로 식별되는 인코딩된 프레임으로 설정합니다.

  4. lastFrameGenerationnull로 설정합니다.

  5. [[progressive frame generations]]frameIndex 키가 있는 맵 엔트리가 있다면, 그 값을 lastFrameGeneration에 할당합니다.

  6. 다음 조건 중 하나가 참이 될 때까지 기다립니다 (먼저 발생하는 조건 우선):

    1. [[encoded data]]encodedFrame을 디코드하여 Progressive Image Frame GenerationlastFrameGeneration을 초과하는 출력을 생성할 만큼 충분한 바이트를 포함할 때.

    2. [[encoded data]] 가 잘못된 것으로 판명될 때.

    3. completetrue일 때.

    4. [[closed]]true일 때.

  7. [[encoded data]] 가 잘못된 것으로 판명되면, 치명적 잘못된 데이터 거부 알고리즘을 실행하고 이 단계들을 중단합니다.

  8. 그렇지 않고 [[encoded data]]encodedFrame을 디코드하여 Progressive Image Frame GenerationlastFrameGeneration을 초과하는 출력을 생성할 만큼 충분한 바이트를 포함하지 않으면, 불가능한 디코드 거부 알고리즘을 promise와 함께 실행하고 이 단계들을 중단합니다.

  9. [[codec implementation]] 을 사용해 encodedFrame을 디코드 시도합니다.

  10. 디코딩 중 오류가 발생하면, 치명적 잘못된 데이터 거부 알고리즘을 실행하고 이 단계들을 중단합니다.

  11. output[[codec implementation]]encodedFrame에 대해 내보낸 디코드 이미지 데이터로 설정합니다.

  12. decodeResult를 새로운 ImageDecodeResult로 설정합니다.

  13. outputencodedFrame에 해당하는 최종 전체 디테일 점진적 출력이라면:

    1. decodeResultcompletetrue를 할당합니다.

    2. [[progressive frame generations]]frameIndex 키의 엔트리가 있다면, 해당 엔트리를 맵에서 제거합니다.

  14. 그렇지 않은 경우:

    1. decodeResultcompletefalse를 할당합니다.

    2. frameGenerationoutputProgressive Image Frame Generation으로 설정합니다.

    3. [[progressive frame generations]]frameIndex 키와 frameGeneration 값을 추가합니다.

  15. durationencodedFrame에서 설명된 output의 표시 시간으로 설정합니다. encodedFrame에 duration이 없으면 null을 할당합니다.

  16. timestampoutput의 표시 타임스탬프로 설정합니다. encodedFrame에 타임스탬프가 없으면:

    1. encodedFrame이 정지 이미지라면 timestamp0을 할당합니다.

    2. encodedFrame이 일정 속도의 애니메이션 이미지이고 durationnull이 아니라면, timestamp|frameIndex| * |duration|을 할당합니다.

    3. 메타데이터에서 추가 디코드 없이 타임스탬프를 간단히 생성할 수 있다면 해당 값을 timestamp에 할당합니다.

    4. 그 외에는 timestamp0을 할당합니다.

  17. [[encoded data]] 에 방향 메타데이터가 있으면 rotationflip으로 기술하고, 그렇지 않으면 rotation은 0, flip은 false로 설정합니다.

  18. imageoutput, timestamp, duration, rotation, flip으로 비디오 프레임 생성 알고리즘을 실행한 결과를 할당합니다.

  19. promise[[pending decode promises]]에서 제거합니다.

  20. promisedecodeResult로 resolve 합니다.

디코드 완료 처리 (with promiseresult)
  1. 작업 큐에 다음 단계들을 수행하도록 추가합니다:

    1. [[closed]] 라면, 이 단계들을 중단합니다.

    2. promise[[pending decode promises]]의 요소임을 단언합니다.

    3. promise[[pending decode promises]]에서 제거합니다.

    4. promiseresult로 resolve 합니다.

불가능한 디코드 거부 (with promise)
  1. completetrue이거나 [[closed]]true임을 단언합니다.

  2. completetrue이면, exceptionRangeError로 설정합니다. 그렇지 않으면 exceptionInvalidStateError DOMException으로 설정합니다.

  3. 작업 큐에 다음 단계들을 수행하도록 추가합니다:

    1. [[closed]] 라면, 이 단계들을 중단합니다.

    2. promise[[pending decode promises]]의 요소임을 단언합니다.

    3. promise[[pending decode promises]]에서 제거합니다.

    4. promiseexception으로 reject 합니다.

치명적 잘못된 데이터 거부
  1. 작업 큐에 다음 단계들을 수행하도록 추가합니다:

    1. [[closed]] 라면, 이 단계들을 중단합니다.

    2. ImageDecoder 닫기 알고리즘을 EncodingError DOMException과 함께 실행합니다.

타입 지원 확인 (with type)
  1. User Agent가 type 디코딩을 지원하는 코덱을 제공할 수 있으면 true를 반환합니다.

  2. 그렇지 않으면 false를 반환합니다.

ImageDecoder 리셋 (with exception)
  1. [[codec implementation]] 에 모든 활성 디코딩 작업 중단을 신호합니다.

  2. [[pending decode promises]]의 각 decodePromise에 대해:

    1. decodePromiseexception으로 reject 합니다.

    2. decodePromise[[pending decode promises]]에서 제거합니다.

ImageDecoder 닫기 (with exception)
  1. ImageDecoder 리셋 알고리즘을 exception과 함께 실행합니다.

  2. [[closed]]true를 할당합니다.

  3. [[codec implementation]] 를 비우고 관련된 시스템 리소스를 해제합니다.

  4. [[ImageTrackList]] 가 비어 있으면 [[ready promise]]exception으로 reject 합니다. 그렇지 않으면 다음 단계들을 수행합니다,

    1. [[ImageTrackList]] 에서 모든 엔트리를 제거합니다.

    2. [[ImageTrackList]][[selected index]]-1을 할당합니다.

  5. [[complete]] 가 false이면 [[completed promise]]exception으로 resolve 합니다.

10.3. ImageDecoderInit 인터페이스

typedef (AllowSharedBufferSource or ReadableStream) ImageBufferSource;
dictionary ImageDecoderInit {
  required DOMString type;
  required ImageBufferSource data;
  ColorSpaceConversion colorSpaceConversion = "default";
  [EnforceRange] unsigned long desiredWidth;
  [EnforceRange] unsigned long desiredHeight;
  boolean preferAnimation;
  sequence<ArrayBuffer> transfer = [];
};

ImageDecoderInit유효한 ImageDecoderInit인지 판단하려면, 다음 단계들을 실행합니다:

  1. type유효한 이미지 MIME 타입이 아니면, false를 반환합니다.

  2. dataReadableStream 타입이고, 해당 ReadableStream이 disturbed 또는 locked 상태라면, false를 반환합니다.

  3. dataBufferSource 타입인 경우:

    1. data가 [detached] 상태이면, false를 반환합니다.

    2. data비어있으면, false를 반환합니다.

  4. desiredWidth존재하고, desiredHeight 가 존재하지 않으면, false를 반환합니다.

  5. desiredHeight존재하고, desiredWidth 가 존재하지 않으면, false를 반환합니다.

  6. true를 반환합니다.

유효한 이미지 MIME 타입유효한 MIME 타입 문자열이고, type[RFC9110] 8.3.1절에 따라 image인 문자열입니다.

type, 타입: DOMString

디코딩할 이미지 파일의 MIME 타입을 담고 있는 문자열입니다.

data, 타입: ImageBufferSource

BufferSource 또는 ReadableStream 타입의 바이트 시퀀스로, type에 의해 기술된 인코딩된 이미지 파일을 나타냅니다.

colorSpaceConversion, 타입: ColorSpaceConversion, 기본값 "default"

디코딩된 출력의 색 공간 변환 여부를 제어합니다. colorSpaceConversionImageBitmapOptions에서 정의된 대로 동작합니다.

desiredWidth, 타입: unsigned long

디코딩된 출력에 원하는 너비를 지정합니다. 구현은 최선을 다하지만, 모든 포맷/디코더에서 지원되지 않을 수 있습니다.

desiredHeight, 타입: unsigned long

디코딩된 출력에 원하는 높이를 지정합니다. 구현은 최선을 다하지만, 모든 포맷/디코더에서 지원되지 않을 수 있습니다.

preferAnimation, 타입: boolean

이미지에 여러 트랙이 있을 때, 초기 트랙 선택 시 애니메이션 트랙을 우선할지 여부를 지정합니다.

참고: 기본 선택 트랙 인덱스 얻기 알고리즘을 참고하세요.

10.4. ImageDecodeOptions 인터페이스

dictionary ImageDecodeOptions {
  [EnforceRange] unsigned long frameIndex = 0;
  boolean completeFramesOnly = true;
};

frameIndex, 타입 unsigned long, 기본값 0

디코드할 프레임의 인덱스입니다.

completeFramesOnly, 타입 boolean, 기본값 true

점진적 이미지의 경우, false 값은 디코더가 세부 정보가 적은 image 를 출력할 수 있음을 의미합니다. 동일한 decode() 호출을 frameIndex 에 대해 반복 호출할수록 더 높은 점진적 이미지 프레임 생성 (더 많은 이미지 디테일)의 이미지를 얻게 되며, 최종적으로 전체 디테일의 이미지가 생성됩니다.

completeFramesOnlytrue로 할당되거나, 이미지가 점진적 이미지가 아니거나, User Agent가 해당 이미지 타입에 대해 점진적 디코딩을 지원하지 않는 경우, decode() 호출은 전체 디테일의 이미지가 디코딩될 때만 resolve됩니다.

참고: 점진적 이미지의 경우, completeFramesOnlyfalse로 설정하면 네트워크에서 아직 버퍼링 중인 이미지를 미리보기로 제공할 수 있습니다 (data ReadableStream 사용).

전체 디테일 이미지를 디코딩하면 ImageDecodeResultcomplete 가 true로 설정됩니다.

10.5. ImageDecodeResult 인터페이스

dictionary ImageDecodeResult {
  required VideoFrame image;
  required boolean complete;
};

image, 타입 VideoFrame

디코드된 이미지입니다.

complete, 타입 boolean

image 가 최종 전체 디테일 출력을 포함하는지 여부를 나타냅니다.

참고: completedecode()completeFramesOnlytrue로 설정하여 호출할 때 항상 true입니다.

10.6. ImageTrackList 인터페이스

[Exposed=(Window,DedicatedWorker)]
interface ImageTrackList {
  getter ImageTrack (unsigned long index);

  readonly attribute Promise<undefined> ready;
  readonly attribute unsigned long length;
  readonly attribute long selectedIndex;
  readonly attribute ImageTrack? selectedTrack;
};

10.6.1. 내부 슬롯

[[ready promise]]

ImageTrackListImageTrack들로 채워졌을 때 신호로 사용되는 promise입니다.

참고: ImageTrackframeCountcompletetrue가 될 때까지 이후에도 업데이트될 수 있습니다.

[[track list]]

ImageTrackList가 기술하는 ImageTrack들의 리스트입니다.

[[selected index]]

[[track list]] 에서 선택된 트랙의 인덱스입니다. -1 값은 선택된 트랙이 없음을 의미합니다. 초기값은 -1입니다.

10.6.2. 속성

ready, 타입 Promise<undefined>, 읽기 전용

ready getter 단계는 [[ready promise]] 를 반환하는 것입니다.

length, 타입 unsigned long, 읽기 전용

length getter 단계는 [[track list]] 의 길이를 반환합니다.

selectedIndex, 타입 long, 읽기 전용

selectedIndex getter 단계는 [[selected index]] 를 반환합니다.

selectedTrack, 타입 ImageTrack, 읽기 전용, nullable

selectedTrack getter 단계는 다음과 같습니다:

  1. [[selected index]]-1이면 null을 반환합니다.

  2. 그 외에는 [[track list]] 에서 [[selected index]] 위치의 ImageTrack을 반환합니다.

10.7. ImageTrack 인터페이스

[Exposed=(Window,DedicatedWorker)]
interface ImageTrack {
  readonly attribute boolean animated;
  readonly attribute unsigned long frameCount;
  readonly attribute unrestricted float repetitionCount;
  attribute boolean selected;
};

10.7.1. 내부 슬롯

[[ImageDecoder]]

ImageTrack을 생성한 ImageDecoder 인스턴스입니다.

[[ImageTrackList]]

ImageTrack을 포함하는 ImageTrackList 인스턴스입니다.

[[animated]]

이 트랙이 여러 프레임을 가진 애니메이션 이미지를 포함하는지 여부를 나타냅니다.

[[frame count]]

이 트랙의 프레임 수입니다.

[[repetition count]]

애니메이션이 반복될 의도된 횟수입니다.

[[selected]]

이 트랙이 디코딩에 선택되었는지 여부를 나타냅니다.

10.7.2. 속성

animated, 타입 boolean, 읽기 전용

animated getter 단계는 [[animated]] 값을 반환하는 것입니다.

참고: 이 속성은 frameCount 가 최초에 0이고 이후 ReadableStream data 의 새 청크가 도착하면 증가하는 이미지에서 결국 0을 초과하게 될 것임을 미리 알려줍니다.

frameCount, 타입 unsigned long, 읽기 전용

frameCount getter 단계는 [[frame count]] 값을 반환하는 것입니다.

repetitionCount, 타입 unrestricted float, 읽기 전용

repetitionCount getter 단계는 [[repetition count]] 값을 반환하는 것입니다.

selected, 타입 boolean

selected getter 단계는 [[selected]] 값을 반환하는 것입니다.

selected setter 단계는 다음과 같습니다:

  1. [[ImageDecoder]][[closed]] 슬롯이 true이면 이 단계들을 중단합니다.

  2. newValuethe given value로 설정합니다.

  3. newValue[[selected]] 와 같으면 이 단계들을 중단합니다.

  4. newValue[[selected]] 에 할당합니다.

  5. parentTrackList[[ImageTrackList]] 로 설정합니다.

  6. oldSelectedIndexparentTrackList[[selected index]] 값으로 설정합니다.

  7. oldSelectedIndex-1이 아니면:

    1. oldSelectedTrackparentTrackList [[track list]] 에서 oldSelectedIndex 위치의 ImageTrack 로 설정합니다.

    2. oldSelectedTrack[[selected]]false를 할당합니다.

  8. newValuetrue이면, selectedIndexthis ImageTrackparentTrackList[[track list]] 중 몇 번째 인덱스인지로 설정합니다. 그렇지 않으면 selectedIndex-1로 설정합니다.

  9. selectedIndexparentTrackList[[selected index]] 에 할당합니다.

  10. [[ImageDecoder]]ImageDecoder 리셋 알고리즘을 실행합니다.

  11. [[ImageDecoder]]control message queue에 내부 선택 트랙 인덱스를 selectedIndex로 업데이트하는 제어 메시지 큐를 추가합니다.

  12. [[ImageDecoder]]제어 메시지 큐 처리를 실행합니다.

제어 메시지 실행으로 내부 선택 트랙 인덱스를 업데이트한다는 것은 다음 단계를 실행하는 것입니다:

  1. [[ImageDecoder]][[codec work queue]] 에 다음 단계들을 큐에 추가합니다:

    1. [[internal selected track index]]selectedIndex를 할당합니다.

    2. [[progressive frame generations]] 의 모든 엔트리를 제거합니다.

11. 리소스 회수

리소스에 제약이 있는 경우, User Agent는 MAY 코덱을 적극적으로 회수할 수 있습니다. 이는 하드웨어 코덱이 제한적이고 웹 페이지 혹은 플랫폼 앱 간에 공유되는 경우 특히 해당됩니다.

코덱 회수를 하려면, User Agent는 MUST 아래 적절한 close 알고리즘(오디오 디코더 닫기, 오디오 인코더 닫기, 비디오 디코더 닫기비디오 인코더 닫기 중 하나)를 QuotaExceededError 와 함께 실행해야 합니다.

코덱을 언제 회수할 수 있는지에 대한 규칙은 해당 코덱이 활성 또는 비활성 코덱인지, 백그라운드 코덱인지에 따라 달라집니다.

활성 코덱은 최근 10초 내에 [[codec work queue]]에서 작업을 진행한 코덱입니다.

참고: 작업 큐가 진행되었는지 확인하는 신뢰할 수 있는 지표는 output() 콜백 호출입니다.

비활성 코덱활성 코덱 정의를 만족하지 않는 모든 코덱입니다.

백그라운드 코덱ownerDocument (혹은 워커의 경우 owner setDocument) 에 hidden 속성이 true인 코덱입니다.

User Agent는 MUST 코덱 회수비활성 코덱, 백그라운드 코덱 또는 둘 다인 경우에만 진행해야 합니다. User Agent는 MUST NOT 활성이면서 포그라운드(즉, 백그라운드 코덱이 아닌)인 코덱을 회수해서는 안 됩니다.

또한 User Agent는 다음의 경우 활성 백그라운드 코덱을 회수해서는 MUST NOT 합니다:

12. 보안 고려사항

이 섹션은 규범적이지 않습니다.

가장 중요한 보안 영향은 이 API의 기능이 공격자가 기본 플랫폼 코덱의 취약점을 보다 쉽게 악용할 수 있게 해준다는 점입니다. 또한 코덱을 설정하고 제어하는 새로운 기능은 특정 구성/제어 순서에 의존하는 새로운 공격을 가능하게 합니다.

플랫폼 코덱은 역사적으로 HTMLMediaElement, [WEBAUDIO], [WebRTC] 같은 API의 내부 세부사항이었습니다. 이런 방식으로, 변형된 미디어 파일/스트림을 사용하고 다양한 API 제어 메서드를 호출하여 기본 코덱을 공격하는 것이 항상 가능했습니다.

예를 들어, 스트림을 미디어 컨테이너(mp4 등)로 래핑하고 srcHTMLMediaElement 에 설정할 수 있습니다. 그런 다음 reset() 을 호출하거나 <video>.currentTime을 새 값으로 바꿔서 기본 비디오 디코더를 리셋할 수 있습니다.

WebCodecs는 입력이 제공될 때 저수준 제어와 코덱 제어 메서드 직접 접근을 노출함으로써 이러한 공격을 더 쉽게 만듭니다. 또한 공격자는 이전에는 상위 API에서 불가능했던 제어 메서드의 시퀀스를 호출할 수 있습니다.

워킹 그룹은 User Agent가 무작위 입력 및 제어 메서드 호출로 구현을 광범위하게 퍼징(fuzzing)하여 이 위험을 완화할 것으로 기대합니다. 또한 User Agent는 기본 코덱을 권한이 제한된 프로세스(샌드박스)에 격리하여 성공적인 공격이 사용자 데이터를 읽는 것을 방지하는 것이 좋습니다.

또 다른 문제는 기본 코덱이 해당 데이터에 대해 아직 작업 중일 때 사이트가 코덱 입력 또는 출력을 변경할 수 있는 입력 변형 경쟁 조건(race condition)에 노출되는 것입니다. 이 문제는 입력과 출력 인터페이스를 불변으로 하여 완화됩니다.

13. 프라이버시 고려사항

이 섹션은 규범적이지 않습니다.

가장 중요한 프라이버시 영향은 다양한 코덱 기능을 쿼리하여 코덱 기능 프로파일을 수집함으로써 사용자를 지문(fingerprint)으로 식별할 가능성이 높아진다는 점입니다. 이러한 프로파일의 상당 부분은 이미 기존 API에서도 노출되어 있습니다. 이런 프로파일만으로는 고유하게 식별될 가능성이 매우 낮지만, 다른 지표와 결합하면 지문 생성에 사용될 수 있습니다.

공격자는 여러 가지 설정 딕셔너리를 사용해 IsConfigSupported() 메서드를 호출하여 코덱 기능 프로파일을 수집할 수 있습니다. 마찬가지로, 공격자는 여러 설정 딕셔너리로 코덱 configure()를 시도하고 어떤 설정이 받아들여지는지 관찰할 수 있습니다.

공격자는 기존 API를 이용해 대부분의 코덱 기능 프로파일을 알아낼 수 있습니다. 예를 들어, [media-capabilities]decodingInfo() API는 어떤 종류의 디코더가 지원되는지 기술하며, powerEfficient 속성은 디코더가 하드웨어 가속을 사용하는지 신호로 제공합니다. 또 [WebRTC]getCapabilities() API로 어떤 종류의 인코더가 지원되는지 알 수 있고, getStats() API로 인코더가 하드웨어 가속을 사용하는지 알 수 있습니다. WebCodecs는 저수준 코덱 기능 형태로 추가 정보를 노출합니다.

코덱 기능 프로파일만으로는 고유하게 식별될 가능성이 낮습니다. 기본 코덱은 대부분 User Agent 바이너리 또는 OS 일부로 소프트웨어로 구현되어 있고, 해당 소프트웨어를 실행하는 모든 사용자는 공통 기능을 갖게 됩니다. 또한 하드웨어 가속으로 구현되는 경우에도, 해당 하드웨어는 대량 생산되므로 특정 기종/제조일(예: 2020년 출시 플래그십 휴대폰)에는 공통 기능을 갖게 됩니다. 물론 소수는 오래된 소프트웨어 코덱을 쓰거나 희귀 하드웨어를 조합해서 쓰겠지만, 대부분의 경우 코덱 기능 프로파일은 많은 사용자가 공유하게 됩니다.

코덱 기능 프로파일로 사용자 그룹을 분류하는 것도 결국 다른 지표와 결합해 개별 사용자를 식별하는 데 쓰일 수 있는 약간의 엔트로피가 됩니다. User Agent는 MAY 사이트가 코덱 기능을 과도하게 탐색하려 할 때 에러를 반환함으로써 이를 부분적으로 완화할 수 있습니다. 또한 User Agent는 MAY "프라이버시 예산"이라는 개념을 적용해, WebCodecs 및 기타 식별 API 사용에 따라 예산을 소진하게 할 수 있습니다. 프라이버시 예산이 소진되면 코덱 기능을 공통 기준으로 제한하거나 사용자 승인을 요청할 수 있습니다.

14. WebCodecs를 사용하는 저자를 위한 모범 사례

이 섹션은 규범적이지 않습니다.

WebCodecs는 내부적으로 백그라운드 스레드에서 동작하지만, 실시간 미디어나 경쟁이 심한 메인 스레드 환경에서 작업하는 저자는 미디어 파이프라인이 가능하면 메인 스레드와 완전히 독립적인 워커 컨텍스트에서 동작하도록 하는 것이 좋습니다. 예를 들어, VideoFrame 의 실시간 미디어 처리는 일반적으로 워커 컨텍스트에서 수행되어야 합니다.

메인 스레드는 개발 중에는 눈에 띄지 않을 수 있지만, 현장에서 기기와 User Agent마다 일관성 없이 성능 저하가 발생할 수 있는 높은 경쟁과 끊김(jank) 가능성이 있습니다. 미디어 파이프라인을 메인 스레드에서 분리하면 최종 사용자에게 부드러운 경험을 제공할 수 있습니다.

미디어 파이프라인을 메인 스레드에서 사용하는 저자는 목표 프레임 속도, 메인 스레드의 작업량, 애플리케이션이 어떻게 임베드될지, 그리고 사용자가 사용할 기기 종류를 반드시 고려해야 합니다.

15. 감사의 글

편집자들은 이 명세서에 기여해 주신 Alex Russell, Chris Needham, Dale Curtis, Dan Sanders, Eugene Zemtsov, Francois Daoust, Guido Urdaneta, Harald Alvestrand, Jan-Ivar Bruaroey, Jer Noble, Mark Foltz, Peter Thatcher, Steve Anton, Matt Wolenetz, Rijubrata Bhaumik, Thomas Guilbert, Tuukka Toivonen, 그리고 Youenn Fablet께 감사드립니다. 또한 메일링 리스트와 이슈 참여 등으로 명세에 기여한 많은 분들께도 감사드립니다.

워킹 그룹은 이 명세서를 우리의 동료 Bernard Aboba에게 헌정합니다.

적합성

문서 규약

적합성 요구사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. 규범적 부분에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”과 같은 핵심 단어는 RFC 2119에 명시된 대로 해석해야 합니다. 다만, 가독성을 위해 이 단어들은 이 명세서에서 모두 대문자로 표기되지 않습니다.

이 명세서의 모든 텍스트는 명시적으로 규범적이지 않음으로 표시된 섹션, 예제, 참고를 제외하면 규범적입니다. [RFC2119]

이 명세서의 예제는 “for example”이라는 말로 시작하거나, class="example"와 같이 규범적 텍스트와 구분되어 있습니다. 예시:

이것은 정보 제공용 예제입니다.

정보 제공용 참고는 “Note”라는 단어로 시작하며, class="note"로 규범적 텍스트와 구분되어 있습니다. 예시:

참고: 이것은 정보 제공용 참고입니다.

적합한 알고리즘

알고리즘의 일부로 명령문 형태로 표현된 요구사항(예: "strip any leading space characters" 또는 "return false and abort these steps")은 알고리즘 도입부에서 사용된 핵심 단어("must", "should", "may" 등)의 의미에 따라 해석되어야 합니다.

알고리즘이나 특정 단계로 표현된 적합성 요구사항은 결과가 동등하다면 어떤 방식으로든 구현할 수 있습니다. 즉, 이 명세서의 알고리즘은 이해하기 쉽게 작성되었으며 성능을 위해 작성된 것은 아닙니다. 구현자는 최적화를 권장합니다.

색인

이 명세서에서 정의된 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS Images Module Level 3. 2023년 12월 18일. CRD. URL: https://www.w3.org/TR/css-images-3/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[GEOMETRY-1]
Simon Pieters; Chris Harrelson. Geometry Interfaces Module Level 1. 2018년 12월 4일. CR. URL: https://www.w3.org/TR/geometry-1/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MEDIASTREAM-RECORDING]
Miguel Casas-sanchez. MediaStream Recording. 2025년 4월 17일. WD. URL: https://www.w3.org/TR/mediastream-recording/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing Standard. Living Standard. URL: https://mimesniff.spec.whatwg.org/
[MST-CONTENT-HINT]
Harald Alvestrand. MediaStreamTrack Content Hints. 2024년 10월 31일. WD. URL: https://www.w3.org/TR/mst-content-hint/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[STREAMS]
Adam Rice; et al. Streams Standard. Living Standard. URL: https://streams.spec.whatwg.org/
[SVG2]
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. 2018년 10월 4일. CR. URL: https://www.w3.org/TR/SVG2/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/
[WebRTC-SVC]
Bernard Aboba. Scalable Video Coding (SVC) Extension for WebRTC. 2024년 8월 17일. WD. URL: https://www.w3.org/TR/webrtc-svc/

참고용 참고 문헌

[H.273]
Coding-independent code points for video signal type identification. 2016년 12월. URL: https://www.itu.int/rec/T-REC-H.273/en
[MEDIA-CAPABILITIES]
Jean-Yves Avenard; Mark Foltz. Media Capabilities. 2025년 6월 23일. WD. URL: https://www.w3.org/TR/media-capabilities/
[MEDIA-SOURCE-2]
Jean-Yves Avenard; Mark Watson. Media Source Extensions™. 2025년 4월 17일. WD. URL: https://www.w3.org/TR/media-source-2/
[RFC6381]
R. Gellens; D. Singer; P. Frojdh. The 'Codecs' and 'Profiles' Parameters for "Bucket" Media Types. 2011년 8월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6381
[RFC9110]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP Semantics. 2022년 6월. Internet Standard. URL: https://httpwg.org/specs/rfc9110.html
[WEBAUDIO]
Paul Adenot; Hongchan Choi. Web Audio API. 2021년 6월 17일. REC. URL: https://www.w3.org/TR/webaudio-1.0/
[WEBAUDIO-1.1]
Paul Adenot; Hongchan Choi. Web Audio API 1.1. 2024년 11월 5일. FPWD. URL: https://www.w3.org/TR/webaudio-1.1/
[WEBCODECS-CODEC-REGISTRY]
Paul Adenot; Bernard Aboba. WebCodecs Codec Registry. 2024년 9월 9일. DRY. URL: https://www.w3.org/TR/webcodecs-codec-registry/
[WEBCODECS-VIDEO-FRAME-METADATA-REGISTRY]
Youenn Fablet. WebCodecs VideoFrame Metadata Registry. ED. URL: https://w3c.github.io/webcodecs/video_frame_metadata_registry.html
[WebRTC]
Cullen Jennings; et al. WebRTC: Real-Time Communication in Browsers. 2025년 3월 13일. REC. URL: https://www.w3.org/TR/webrtc/

IDL 색인

[Exposed=(Window,DedicatedWorker), SecureContext]
interface AudioDecoder : EventTarget {
  constructor(AudioDecoderInit init);

  readonly attribute CodecState state;
  readonly attribute unsigned long decodeQueueSize;
  attribute EventHandler ondequeue;

  undefined configure(AudioDecoderConfig config);
  undefined decode(EncodedAudioChunk chunk);
  Promise<undefined> flush();
  undefined reset();
  undefined close();

  static Promise<AudioDecoderSupport> isConfigSupported(AudioDecoderConfig config);
};

dictionary AudioDecoderInit {
  required AudioDataOutputCallback output;
  required WebCodecsErrorCallback error;
};

callback AudioDataOutputCallback = undefined(AudioData output);

[Exposed=(Window,DedicatedWorker), SecureContext]
interface VideoDecoder : EventTarget {
  constructor(VideoDecoderInit init);

  readonly attribute CodecState state;
  readonly attribute unsigned long decodeQueueSize;
  attribute EventHandler ondequeue;

  undefined configure(VideoDecoderConfig config);
  undefined decode(EncodedVideoChunk chunk);
  Promise<undefined> flush();
  undefined reset();
  undefined close();

  static Promise<VideoDecoderSupport> isConfigSupported(VideoDecoderConfig config);
};

dictionary VideoDecoderInit {
  required VideoFrameOutputCallback output;
  required WebCodecsErrorCallback error;
};

callback VideoFrameOutputCallback = undefined(VideoFrame output);

[Exposed=(Window,DedicatedWorker), SecureContext]
interface AudioEncoder : EventTarget {
  constructor(AudioEncoderInit init);

  readonly attribute CodecState state;
  readonly attribute unsigned long encodeQueueSize;
  attribute EventHandler ondequeue;

  undefined configure(AudioEncoderConfig config);
  undefined encode(AudioData data);
  Promise<undefined> flush();
  undefined reset();
  undefined close();

  static Promise<AudioEncoderSupport> isConfigSupported(AudioEncoderConfig config);
};

dictionary AudioEncoderInit {
  required EncodedAudioChunkOutputCallback output;
  required WebCodecsErrorCallback error;
};

callback EncodedAudioChunkOutputCallback =
    undefined (EncodedAudioChunk output,
               optional EncodedAudioChunkMetadata metadata = {});

dictionary EncodedAudioChunkMetadata {
  AudioDecoderConfig decoderConfig;
};

[Exposed=(Window,DedicatedWorker), SecureContext]
interface VideoEncoder : EventTarget {
  constructor(VideoEncoderInit init);

  readonly attribute CodecState state;
  readonly attribute unsigned long encodeQueueSize;
  attribute EventHandler ondequeue;

  undefined configure(VideoEncoderConfig config);
  undefined encode(VideoFrame frame, optional VideoEncoderEncodeOptions options = {});
  Promise<undefined> flush();
  undefined reset();
  undefined close();

  static Promise<VideoEncoderSupport> isConfigSupported(VideoEncoderConfig config);
};

dictionary VideoEncoderInit {
  required EncodedVideoChunkOutputCallback output;
  required WebCodecsErrorCallback error;
};

callback EncodedVideoChunkOutputCallback =
    undefined (EncodedVideoChunk chunk,
               optional EncodedVideoChunkMetadata metadata = {});

dictionary EncodedVideoChunkMetadata {
  VideoDecoderConfig decoderConfig;
  SvcOutputMetadata svc;
  BufferSource alphaSideData;
};

dictionary SvcOutputMetadata {
  unsigned long temporalLayerId;
};

dictionary AudioDecoderSupport {
  boolean supported;
  AudioDecoderConfig config;
};

dictionary VideoDecoderSupport {
  boolean supported;
  VideoDecoderConfig config;
};

dictionary AudioEncoderSupport {
  boolean supported;
  AudioEncoderConfig config;
};

dictionary VideoEncoderSupport {
  boolean supported;
  VideoEncoderConfig config;
};

dictionary AudioDecoderConfig {
  required DOMString codec;
  [EnforceRange] required unsigned long sampleRate;
  [EnforceRange] required unsigned long numberOfChannels;
  AllowSharedBufferSource description;
};

dictionary VideoDecoderConfig {
  required DOMString codec;
  AllowSharedBufferSource description;
  [EnforceRange] unsigned long codedWidth;
  [EnforceRange] unsigned long codedHeight;
  [EnforceRange] unsigned long displayAspectWidth;
  [EnforceRange] unsigned long displayAspectHeight;
  VideoColorSpaceInit colorSpace;
  HardwareAcceleration hardwareAcceleration = "no-preference";
  boolean optimizeForLatency;
  double rotation = 0;
  boolean flip = false;
};

dictionary AudioEncoderConfig {
  required DOMString codec;
  [EnforceRange] required unsigned long sampleRate;
  [EnforceRange] required unsigned long numberOfChannels;
  [EnforceRange] unsigned long long bitrate;
  BitrateMode bitrateMode = "variable";
};

dictionary VideoEncoderConfig {
  required DOMString codec;
  [EnforceRange] required unsigned long width;
  [EnforceRange] required unsigned long height;
  [EnforceRange] unsigned long displayWidth;
  [EnforceRange] unsigned long displayHeight;
  [EnforceRange] unsigned long long bitrate;
  double framerate;
  HardwareAcceleration hardwareAcceleration = "no-preference";
  AlphaOption alpha = "discard";
  DOMString scalabilityMode;
  VideoEncoderBitrateMode bitrateMode = "variable";
  LatencyMode latencyMode = "quality";
  DOMString contentHint;
};

enum HardwareAcceleration {
  "no-preference",
  "prefer-hardware",
  "prefer-software",
};

enum AlphaOption {
  "keep",
  "discard",
};

enum LatencyMode {
  "quality",
  "realtime"
};

dictionary VideoEncoderEncodeOptions {
  boolean keyFrame = false;
};

enum VideoEncoderBitrateMode {
  "constant",
  "variable",
  "quantizer"
};

enum CodecState {
  "unconfigured",
  "configured",
  "closed"
};

callback WebCodecsErrorCallback = undefined(DOMException error);

[Exposed=(Window,DedicatedWorker), Serializable]
interface EncodedAudioChunk {
  constructor(EncodedAudioChunkInit init);
  readonly attribute EncodedAudioChunkType type;
  readonly attribute long long timestamp;          // microseconds
  readonly attribute unsigned long long? duration; // microseconds
  readonly attribute unsigned long byteLength;

  undefined copyTo(AllowSharedBufferSource destination);
};

dictionary EncodedAudioChunkInit {
  required EncodedAudioChunkType type;
  [EnforceRange] required long long timestamp;    // microseconds
  [EnforceRange] unsigned long long duration;     // microseconds
  required AllowSharedBufferSource data;
  sequence<ArrayBuffer> transfer = [];
};

enum EncodedAudioChunkType {
    "key",
    "delta",
};

[Exposed=(Window,DedicatedWorker), Serializable]
interface EncodedVideoChunk {
  constructor(EncodedVideoChunkInit init);
  readonly attribute EncodedVideoChunkType type;
  readonly attribute long long timestamp;             // microseconds
  readonly attribute unsigned long long? duration;    // microseconds
  readonly attribute unsigned long byteLength;

  undefined copyTo(AllowSharedBufferSource destination);
};

dictionary EncodedVideoChunkInit {
  required EncodedVideoChunkType type;
  [EnforceRange] required long long timestamp;        // microseconds
  [EnforceRange] unsigned long long duration;         // microseconds
  required AllowSharedBufferSource data;
  sequence<ArrayBuffer> transfer = [];
};

enum EncodedVideoChunkType {
    "key",
    "delta",
};

[Exposed=(Window,DedicatedWorker), Serializable, Transferable]
interface AudioData {
  constructor(AudioDataInit init);

  readonly attribute AudioSampleFormat? format;
  readonly attribute float sampleRate;
  readonly attribute unsigned long numberOfFrames;
  readonly attribute unsigned long numberOfChannels;
  readonly attribute unsigned long long duration;  // microseconds
  readonly attribute long long timestamp;          // microseconds

  unsigned long allocationSize(AudioDataCopyToOptions options);
  undefined copyTo(AllowSharedBufferSource destination, AudioDataCopyToOptions options);
  AudioData clone();
  undefined close();
};

dictionary AudioDataInit {
  required AudioSampleFormat format;
  required float sampleRate;
  [EnforceRange] required unsigned long numberOfFrames;
  [EnforceRange] required unsigned long numberOfChannels;
  [EnforceRange] required long long timestamp;  // microseconds
  required BufferSource data;
  sequence<ArrayBuffer> transfer = [];
};

dictionary AudioDataCopyToOptions {
  [EnforceRange] required unsigned long planeIndex;
  [EnforceRange] unsigned long frameOffset = 0;
  [EnforceRange] unsigned long frameCount;
  AudioSampleFormat format;
};

enum AudioSampleFormat {
  "u8",
  "s16",
  "s32",
  "f32",
  "u8-planar",
  "s16-planar",
  "s32-planar",
  "f32-planar",
};

[Exposed=(Window,DedicatedWorker), Serializable, Transferable]
interface VideoFrame {
  constructor(CanvasImageSource image, optional VideoFrameInit init = {});
  constructor(AllowSharedBufferSource data, VideoFrameBufferInit init);

  readonly attribute VideoPixelFormat? format;
  readonly attribute unsigned long codedWidth;
  readonly attribute unsigned long codedHeight;
  readonly attribute DOMRectReadOnly? codedRect;
  readonly attribute DOMRectReadOnly? visibleRect;
  readonly attribute double rotation;
  readonly attribute boolean flip;
  readonly attribute unsigned long displayWidth;
  readonly attribute unsigned long displayHeight;
  readonly attribute unsigned long long? duration;  // microseconds
  readonly attribute long long timestamp;           // microseconds
  readonly attribute VideoColorSpace colorSpace;

  VideoFrameMetadata metadata();

  unsigned long allocationSize(
      optional VideoFrameCopyToOptions options = {});
  Promise<sequence<PlaneLayout>> copyTo(
      AllowSharedBufferSource destination,
      optional VideoFrameCopyToOptions options = {});
  VideoFrame clone();
  undefined close();
};

dictionary VideoFrameInit {
  unsigned long long duration;  // microseconds
  long long timestamp;          // microseconds
  AlphaOption alpha = "keep";

  // Default matches image. May be used to efficiently crop. Will trigger
  // new computation of displayWidth and displayHeight using image's pixel
  // aspect ratio unless an explicit displayWidth and displayHeight are given.
  DOMRectInit visibleRect;

  double rotation = 0;
  boolean flip = false;

  // Default matches image unless visibleRect is provided.
  [EnforceRange] unsigned long displayWidth;
  [EnforceRange] unsigned long displayHeight;

  VideoFrameMetadata metadata;
};

dictionary VideoFrameBufferInit {
  required VideoPixelFormat format;
  required [EnforceRange] unsigned long codedWidth;
  required [EnforceRange] unsigned long codedHeight;
  required [EnforceRange] long long timestamp;  // microseconds
  [EnforceRange] unsigned long long duration;  // microseconds

  // Default layout is tightly-packed.
  sequence<PlaneLayout> layout;

  // Default visible rect is coded size positioned at (0,0)
  DOMRectInit visibleRect;

  double rotation = 0;
  boolean flip = false;

  // Default display dimensions match visibleRect.
  [EnforceRange] unsigned long displayWidth;
  [EnforceRange] unsigned long displayHeight;

  VideoColorSpaceInit colorSpace;

  sequence<ArrayBuffer> transfer = [];

  VideoFrameMetadata metadata;
};

dictionary VideoFrameMetadata {
  // Possible members are recorded in the VideoFrame Metadata Registry.
};

dictionary VideoFrameCopyToOptions {
  DOMRectInit rect;
  sequence<PlaneLayout> layout;
  VideoPixelFormat format;
  PredefinedColorSpace colorSpace;
};

dictionary PlaneLayout {
  [EnforceRange] required unsigned long offset;
  [EnforceRange] required unsigned long stride;
};

enum VideoPixelFormat {
  // 4:2:0 Y, U, V
  "I420",
  "I420P10",
  "I420P12",
  // 4:2:0 Y, U, V, A
  "I420A",
  "I420AP10",
  "I420AP12",
  // 4:2:2 Y, U, V
  "I422",
  "I422P10",
  "I422P12",
  // 4:2:2 Y, U, V, A
  "I422A",
  "I422AP10",
  "I422AP12",
  // 4:4:4 Y, U, V
  "I444",
  "I444P10",
  "I444P12",
  // 4:4:4 Y, U, V, A
  "I444A",
  "I444AP10",
  "I444AP12",
  // 4:2:0 Y, UV
  "NV12",
  // 4:4:4 RGBA
  "RGBA",
  // 4:4:4 RGBX (opaque)
  "RGBX",
  // 4:4:4 BGRA
  "BGRA",
  // 4:4:4 BGRX (opaque)
  "BGRX",
};

[Exposed=(Window,DedicatedWorker)]
interface VideoColorSpace {
  constructor(optional VideoColorSpaceInit init = {});

  readonly attribute VideoColorPrimaries? primaries;
  readonly attribute VideoTransferCharacteristics? transfer;
  readonly attribute VideoMatrixCoefficients? matrix;
  readonly attribute boolean? fullRange;

  [Default] VideoColorSpaceInit toJSON();
};

dictionary VideoColorSpaceInit {
  VideoColorPrimaries? primaries = null;
  VideoTransferCharacteristics? transfer = null;
  VideoMatrixCoefficients? matrix = null;
  boolean? fullRange = null;
};

enum VideoColorPrimaries {
  "bt709",
  "bt470bg",
  "smpte170m",
  "bt2020",
  "smpte432",
};

enum VideoTransferCharacteristics {
  "bt709",
  "smpte170m",
  "iec61966-2-1",
  "linear",
  "pq",
  "hlg",
};

enum VideoMatrixCoefficients {
  "rgb",
  "bt709",
  "bt470bg",
  "smpte170m",
  "bt2020-ncl",
};

[Exposed=(Window,DedicatedWorker), SecureContext]
interface ImageDecoder {
  constructor(ImageDecoderInit init);

  readonly attribute DOMString type;
  readonly attribute boolean complete;
  readonly attribute Promise<undefined> completed;
  readonly attribute ImageTrackList tracks;

  Promise<ImageDecodeResult> decode(optional ImageDecodeOptions options = {});
  undefined reset();
  undefined close();

  static Promise<boolean> isTypeSupported(DOMString type);
};


typedef (AllowSharedBufferSource or ReadableStream) ImageBufferSource;
dictionary ImageDecoderInit {
  required DOMString type;
  required ImageBufferSource data;
  ColorSpaceConversion colorSpaceConversion = "default";
  [EnforceRange] unsigned long desiredWidth;
  [EnforceRange] unsigned long desiredHeight;
  boolean preferAnimation;
  sequence<ArrayBuffer> transfer = [];
};


dictionary ImageDecodeOptions {
  [EnforceRange] unsigned long frameIndex = 0;
  boolean completeFramesOnly = true;
};


dictionary ImageDecodeResult {
  required VideoFrame image;
  required boolean complete;
};


[Exposed=(Window,DedicatedWorker)]
interface ImageTrackList {
  getter ImageTrack (unsigned long index);

  readonly attribute Promise<undefined> ready;
  readonly attribute unsigned long length;
  readonly attribute long selectedIndex;
  readonly attribute ImageTrack? selectedTrack;
};


[Exposed=(Window,DedicatedWorker)]
interface ImageTrack {
  readonly attribute boolean animated;
  readonly attribute unsigned long frameCount;
  readonly attribute unrestricted float repetitionCount;
  attribute boolean selected;
};


이슈 색인

명세는 SHOULD 인코딩된 크기, 표시 사각형(visible rectangle), 디스플레이 크기에 대한 정의(및 다이어그램)를 제공해야 합니다. #166 참고.