Title: WebCodecs
Repository: wicg/web-codecs
Status: CG-DRAFT
ED: https://wicg.github.io/web-codecs/
Shortname: web-codecs
Level: 1
Group: wicg
Editor: Chris Cunningham, w3cid 114832, Google Inc. https://google.com/
Editor: Paul Adenot, w3cid 62410, Mozilla https://www.mozilla.org/
Abstract: This specification defines interfaces for encoding and decoding audio
Abstract: and video. It also includes an interface for retrieving raw video
Abstract: frames from MediaStreamStracks.
Markup Shorthands:css no, markdown yes, dfn yes
!Participate: Git Repository.
!Participate: File an issue.
!
: Key Frame
:: An encoded frame that does not depend on any other frames for decoding.
Codec Processing Model {#codec-processing-model}
================================================
New codec tasks may be scheduled while previous tasks are still pending. For
example, web authors may call `decode()` without waiting for the previous
`decode()` to generate an output. This is facilitated by the following
mechanisms.
Each codec has a single control message queue that is a queue
of control messages.
Queuing a control
message means enqueing the message to the codec’s control
message queue. Invoking codec methods will often queue a control message
to schedule work.
Running a control
message means executing a sequence of steps specified by the method
that enqueued the message.
Running the control message
processing loop means executing these steps.
1. While the control message queue is not empty
1. Let |front message| be the next dequeued control message
2. If |front message| cannot be executed now, return.
The User Agent must decide when further processing is blocked because of
ongoing work as an implementation detail (e.g. the underlying
decoder cannot accept more requests yet). The UA must restart the
processing loop when the blockage is resolved.
NOTE: a blocked processing loop is visible to authors via the
`decodeQueueSize` and `encodeQueueSize` attributes.
3. Dequeue |front message| from the control message queue.
4. Run the |front message| control message steps.
AudioDecoder Interface {#audiodecoder-interface}
================================================
[Exposed=(Window,Worker)]
interface AudioDecoder {
constructor(AudioDecoderInit init);
readonly attribute CodecState state;
readonly attribute long decodeQueueSize;
undefined configure(AudioDecoderConfig config);
undefined decode(EncodedAudioChunk chunk);
Promise flush();
undefined reset();
undefined close();
};
dictionary AudioDecoderInit {
required AudioFrameOutputCallback output;
required WebCodecsErrorCallback error;
};
callback AudioFrameOutputCallback = undefined(AudioFrame output);
Internal Slots {#audiodecoder-internal-slots}
---------------------------------------------
- [[codec implementation]]
- Underlying decoder implementation provided by the User Agent.
- [[output callback]]
- Callback given at construction for decoded outputs.
- [[error callback]]
- Callback given at construction for decode errors.
Constructors {#audiodecoder-constructors}
-----------------------------------------
AudioDecoder(init)
1. Let d be a new {{AudioDecoder}} object.
2. Assign init.output to the {{AudioDecoder/[[output callback]]}} internal slot.
3. Assign init.error to the {{AudioDecoder/[[error callback]]}} internal slot.
4. Assign "unconfigured" to d.state.
4. Return d.
Attributes {#audiodecoder-attributes}
-------------------------------------
-
state
- Describes the current state of the codec.
-
decodeQueueSize
-
The number of pending decode requests. This does not include requests that
have been sent to the underlying codec.
Methods {#audiodecoder-methods}
-------------------------------
- configure(config)
-
Enqueues a control message to configure the audio decoder for
decoding chunks as described by |config|.
When invoked, run these steps:
1. If |config| is not a valid AudioDecoderConfig, throw a
{{TypeError}}.
2. Run the Configure Decoder algorithm with |config|.
- decode(chunk)
-
Enqueues a control message to decode the given |chunk|.
When invoked, run these steps:
1. Let |output algorithm| be the AudioFrame Output algorithm.
2. Run the Decode Chunk algorithm with |chunk| and
|output algorithm|.
- flush()
-
Completes all control messages in the control message queue
and emits all outputs.
When invoked, run these steps:
1. Let |output algorithm| be the AudioFrame Output algorithm.
2. Run the Flush algorithm with |output algorithm|.
- reset()
-
Immediately resets all state including configuration,
control messages in the control message queue, and all pending
callbacks.
When invoked, run the Reset algorithm.
- close()
-
Immediately aborts all pending work and releases system resources. Close is
permanent.
When invoked, run the Close algorithm.
VideoDecoder Interface {#videodecoder-interface}
================================================
[Exposed=(Window,Worker)]
interface VideoDecoder {
constructor(VideoDecoderInit init);
readonly attribute CodecState state;
readonly attribute long decodeQueueSize;
undefined configure(VideoDecoderConfig config);
undefined decode(EncodedVideoChunk chunk);
Promise flush();
undefined reset();
undefined close();
};
dictionary VideoDecoderInit {
required VideoFrameOutputCallback output;
required WebCodecsErrorCallback error;
};
callback VideoFrameOutputCallback = undefined(VideoFrame output);
Internal Slots {#videodecoder-internal-slots}
---------------------------------------------
- [[codec implementation]]
- Underlying decoder implementation provided by the User Agent.
- [[output callback]]
- Callback given at construction for decoded outputs.
- [[error callback]]
- Callback given at construction for decode errors.
Constructors {#videodecoder-constructors}
-----------------------------------------
VideoDecoder(init)
1. Let d be a new VideoDecoder object.
2. Assign `init.output` to the {{VideoDecoder/[[output callback]]}} internal slot.
3. Assign `init.error` to the {{VideoDecoder/[[error callback]]}} internal slot.
4. Assign "unconfigured" to `d.state`.
5. Return d.
Attributes {#videodecoder-attributes}
-------------------------------------
-
state
- Describes the current state of the codec.
-
decodeQueueSize
-
The number of pending decode requests. This does not include requests that
have been sent to the underlying codec.
Methods {#videodecoder-methods}
-------------------------------
- configure(config)
-
Enqueues a control message to configure the video decoder for
decoding chunks as described by |config|.
When invoked, run these steps:
1. If |config| is not a valid VideoDecoderConfig, throw a
{{TypeError}}.
2. Run the Configure Decoder algorithm with |config|.
- decode(chunk)
-
Enqueues a control message to decode the given |chunk|.
When invoked, run these steps:
1. Let |output algorithm| be the VideoFrame Output algorithm.
2. Run the Decode Chunk algorithm with |chunk| and
|output algorithm|.
- flush()
-
Completes all control messages in the control message queue
and emits all outputs.
When invoked, run these steps:
1. Let |output algorithm| be the VideoFrame Output algorithm.
2. Run the Flush algorithm with |output algorithm|.
- reset()
-
Immediately resets all state including configuration,
control messages in the control message queue, and all pending
callbacks.
When invoked, run the Reset algorithm.
- close()
-
Immediately aborts all pending work and releases system resources. Close is
permanent.
When invoked, run the Close algorithm.
AudioEncoder Interface {#audioencoder-interface}
================================================
[Exposed=(Window,Worker)]
interface AudioEncoder {
constructor(AudioEncoderInit init);
readonly attribute CodecState state;
readonly attribute long encodeQueueSize;
undefined configure(AudioEncoderConfig config);
undefined encode(AudioFrame frame);
Promise flush();
undefined reset();
undefined close();
};
dictionary AudioEncoderInit {
required EncodedAudioChunkOutputCallback output;
required WebCodecsErrorCallback error;
};
callback EncodedAudioChunkOutputCallback = undefined(EncodedAudioChunk output);
Internal Slots {#audioencoder-internal-slots}
---------------------------------------------
- [[codec implementation]]
- Underlying encoder implementation provided by the User Agent.
- [[output callback]]
- Callback given at construction for encoded outputs.
- [[error callback]]
- Callback given at construction for encode errors.
Constructors {#audioencoder-constructors}
-----------------------------------------
AudioEncoder(init)
1. Let e be a new AudioEncoder object.
2. Assign `init.output` to the {{AudioEncoder/[[output callback]]}} internal slot.
3. Assign `init.error` to the {{AudioEncoder/[[error callback]]}} internal slot.
4. Assign "unconfigured" to `e.state`.
5. Return e.
Attributes {#audioencoder-attributes}
-------------------------------------
-
state
- Describes the current state of the codec.
-
encodeQueueSize
-
The number of pending encode requests. This does not include requests that
have been sent to the underlying codec.
Methods {#audioencoder-methods}
-------------------------------
- configure(config)
-
Enqueues a control message to configure the audio encoder for
decoding chunks as described by |config|.
When invoked, run these steps:
1. If |config| is not a valid AudioEncoderConfig, throw a
{{TypeError}}.
2. Run the Configure Encoder algorithm with |config|.
- encode(frame)
-
Enqueues a control message to encode the given |frame|.
NOTE: This method will destroy the VideoFrame. Authors who wish to retain a
copy, should call `frame.clone()` prior to calling encode().
When invoked, run these steps:
1. If the value of |frame|'s {{AudioFrame/[[detached]]}} internal slot is
`true`, throw a {{TypeError}}.
2. Let |output algorithm| be the EncodedAudioChunk Output algorithm.
3. Run the Encode Frame algorithm with |frame| and
|output algorithm|.
- flush()
-
Completes all control messages in the control message queue
and emits all outputs.
When invoked, run these steps:
1. Let |output algorithm| be the EncodedAudioChunk Output algorithm.
2. Run the Flush algorithm with |output algorithm|.
- reset()
-
Immediately resets all state including configuration,
control messages in the control message queue, and all pending
callbacks.
When invoked, run the Reset algorithm.
- close()
-
Immediately aborts all pending work and releases system resources. Close is
permanent.
When invoked, run the Close algorithm.
VideoEncoder Interface {#videoencoder-interface}
================================================
[Exposed=(Window,Worker)]
interface VideoEncoder {
constructor(VideoEncoderInit init);
readonly attribute CodecState state;
readonly attribute long encodeQueueSize;
undefined configure(VideoEncoderConfig config);
undefined encode(VideoFrame frame, optional VideoEncoderEncodeOptions options = {});
Promise flush();
undefined reset();
undefined close();
};
dictionary VideoEncoderInit {
required EncodedVideoChunkOutputCallback output;
required WebCodecsErrorCallback error;
};
callback EncodedVideoChunkOutputCallback = undefined(EncodedVideoChunk output);
Internal Slots {#videoencoder-internal-slots}
---------------------------------------------
- [[codec implementation]]
- Underlying encoder implementation provided by the User Agent.
- [[output callback]]
- Callback given at construction for encoded outputs.
- [[error callback]]
- Callback given at construction for encode errors.
Constructors {#videoencoder-constructors}
-----------------------------------------
VideoEncoder(init)
1. Let e be a new VideoEncoder object.
2. Assign `init.output` to the {{VideoEncoder/[[output callback]]}} internal slot.
3. Assign `init.error` to the {{VideoEncoder/[[error callback]]}} internal slot.
4. Assign "unconfigured" to `e.state`.
5. Return e.
Attributes {#videoencoder-attributes}
-------------------------------------
-
state
- Describes the current state of the codec.
-
encodeQueueSize
-
The number of pending encode requests. This does not include requests that
have been sent to the underlying codec.
Methods {#videoencoder-methods}
-------------------------------
- configure(config)
-
Enqueues a control message to configure the video encoder for
decoding chunks as described by |config|.
When invoked, run these steps:
1. If |config| is not a valid VideoEncoderConfig, throw a
{{TypeError}}.
2. Run the Configure Encoder algorithm with |config|.
- encode(frame, options)
-
Enqueues a control message to encode the given |frame|.
NOTE: This method will destroy the VideoFrame. Authors who wish to retain a
copy, should call `frame.clone()` prior to calling encode().
When invoked, run these steps:
1. If the value of |frame|'s {{VideoFrame/[[detached]]}} internal slot is
`true`, throw a {{TypeError}}.
2. Let |output algorithm| be the EncodedVideoChunk Output algorithm.
3. Run the Encode Frame algorithm with |frame| and
|output algorithm|.
- flush()
-
Completes all control messages in the control message queue
and emits all outputs.
When invoked, run these steps:
1. Let |output algorithm| be the EncodedVideoChunk Output algorithm.
2. Run the Flush algorithm with |output algorithm|.
- reset()
-
Immediately resets all state including configuration,
control messages in the control message queue, and all pending
callbacks.
When invoked, run the Reset algorithm.
- close()
-
Immediately aborts all pending work and releases system resources. Close is
permanent.
When invoked, run the Close algorithm.
Decoder and Encoder Algorithms {#decoder-and-encoder-algorithms}
================================================================
The following algorithms run in the scope of the methods that invoke them.
Mentions of attributes and internal slots refer to members of the interface that
owns the invoking method.
Configure Decoder{#configure-decoder-algorithm}
----------------------------------------------------------
Given either an {{AudioDecoderConfig}} or {{VideoDecoderConfig}} |config|, this
algorithm attempts to select a codec implementation that supports |config|.
Run the following steps:
1. If `state` is `“closed”`, throw an {{InvalidStateError}}.
2. If the user agent cannot provide a codec implementation to support config,
throw a {{NotSupportedError}}.
3. Set `state` to `"configured"`.
4. Queue a control message to configure the decoder with |config|.
5. Run the control message processing loop.
Running a control message to configure the decoder means running these
steps:
1. Assign **[[codec implementation]]** with an implementation
supporting |config|.
Decode Chunk (with |chunk| and |output algorithm|) {#decode-chunk-algorithm}
---------------------------------------------------------------------------------------
Run these steps:
1. If `state` is not `"configured"`, throw an {{InvalidStateError}}.
2. Increment `decodeQueueSize`.
3. Queue a control message to decode the |chunk|.
4. Run the control message processing loop.
Running a control message to decode the chunk means running these steps:
1. Decrement `decodeQueueSize`
2. Let |codec implementation queue| be the result of starting a new parallel
queue.
3. Enqueue the following steps to |codec implementation queue|:
1. Attempt to use **[[codec implementation]]** to decode the chunk.
2. If decoding results in an error, queue a task on the media element task
source to run the Codec Error algorithm.
4. Otherwise, for each output, queue a task on the media element task source to
run the provided output algorithm.
Flush{#flush-algorithm}
----------------------------------
Given an |output algorithm|, this algorithm flushes all pending outputs to the
output callback.
Run these steps:
1. If `state` is not `"configured"`, return a Promise rejected with a newly
created {{InvalidStateError}}.
2. Let |promise| be a new Promise.
3. Queue a control message to flush the codec with |promise| and
|output algorithm|
4. Return |promise|.
Running a control message to flush the codec means running these steps
with |promise| and |output algorithm|.
1. Signal **[[codec implementation]]** to emit all pending outputs.
2. For each output, run |output algorithm|.
3. Resolve |promise|.
Codec Error{#codec-error-algorithm}
----------------------------------------------
This algorithm fires the error callback and permanently closes the codec.
Run these steps:
1. Cease processing of control message queue.
2. Run the Close algorithm with {{EncodingError}}.
AudioFrame Output{#audio-frame-output-algorithm}
-----------------------------------------------------------
Run these steps:
1. If `state` is not `“configured”`, abort the following steps.
2. Let |buffer| be an {{AudioBuffer}} containing the decoded audio data.
3. Let |frame| be an {{AudioFrame}} containing |buffer| and a timestamp for the
output.
4. Invoke **[[output callback]]** with frame.
VideoFrame Output{#video-frame-output-algorithm}
-----------------------------------------------------------
Run these steps:
1. If state is not “configured”, abort the following steps.
2. Let |planes| be a sequence of {{Plane}}s containing the decoded video frame
data.
3. Let |pixelFormat| be the {{PixelFormat}} of |planes|.
4. Let |frameInit| be a {{VideoFrameInit}} with the following keys:
1. Let timestamp and duration be the presentation timestamp and duration
from the EncodedVideoChunk associated with this output.
2. Let codedWidth and codedHeight be the width and height of the decoded
video frame in pixels, prior to any cropping or aspect ratio
adjustments.
3. Let cropLeft, cropTop, cropWidth, and cropHeight be the crop region of
the decoded video frame in pixels, prior to any aspect ratio
adjustments.
4. Let displayWidth and displayHeight be the display size of the decoded
video frame in pixels.
9. Let |frame| be a {{VideoFrame}}, constructed with |pixelFormat|, |planes|,
and |frameInit|.
10. Invoke **[[output callback]]** with |frame|.
Reset{#reset-algorithm}
----------------------------------
Run these steps:
1. If `state` is `“closed”`, throw an {{InvalidStateError}}.
2. Set `state` to `“unconfigured”`.
3. Signal **[[codec implementation]]** to cease producing output
for the previous configuration.
NOTE: Some tasks to emit outputs may already be queued in the event loop. These
outputs will be dropped by the output algorithms, which abort if `state` is
not `“configured”`.
4. For each control message in the control message queue:
1. If a control message has an associated promise, reject the promise.
2. Remove the message from the queue.
Close (with error){#close-algorithm}
-----------------------------------------------
Run these steps:
1. Run the Reset algorithm.
2. Set `state` to `“closed”`.
3. Clear **[[codec implementation]]** and release associated system
resources.
4. If |error| is set, invoke **[[error callback]]** with |error|.
Configure Encoder (with config){#configure-encoder-algorithm}
------------------------------------------------------------------------
Run the following steps:
1. If `state` is `"closed"`, throw an {{InvalidStateError}}.
2. If the user agent cannot provide a codec implementation to support |config|,
throw a {{NotSupportedError}}.
3. Set `state` to `"configured"`.
4. Queue a control message to configure the encoder using |config|.
5. Run the control message processing loop.
Running a control message to configure the encoder means running these steps:
1. Assign **[[codec implementation]]** with an implementation
supporting |config|.
Encode Frame (with frame, options, and output algorithm){#encode-frame-algorithm}
--------------------------------------------------------------------------------------------
Run these steps:
1. If `state` is not `"configured"`, throw an {{InvalidStateError}}.
2. Let |frameClone| hold the result of running the Clone Frame algorithm
with |frame|.
3. Destroy the original |frame| by invoking `frame.destroy()`.
4. Increment `encodeQueueSize`.
5. Queue a control message to encode |frameClone| with |options| and
|output algorithm|.
6. Run the control message processing loop.
Running a control message to encode the frame means running these steps.
1. Decrement `encodeQueueSize`.
2. Let |codec implementation queue| be the result of starting a new
parallel queue.
3. Enqueue the following steps to |codec implementation queue|:
1. Attempt to use **[[codec implementation]]** and options to encode
|frameClone|.
2. If encoding results in an error, queue a task on the media element task
source to run the codec error algorithm.
3. Otherwise, for each output, queue a task on the media element task source
to run the provided output algorithm.
EncodedAudioChunk Output{#encodedaudiochunk-output-algorithm}
------------------------------------------------------------------------
Run these steps:
1. If `state` is not `“configured”`, abort the following steps.
2. Let |chunkInit| be an {{EncodedAudioChunkInit}} with the following keys:
1. Let data contain the encoded audio data.
2. Let type be the EnocdedAudioChunkType of the encoded audio data.
3. Let timestamp be the timestamp from the associated input AudioFrame.
4. Let duration be the duration from the associated input AudioFrame.
3. Let |chunk| be a new {{EncodedAudioChunk}} constructed with |chunkInit|.
4. Invoke **[[output callback]]** with |chunk|.
EncodedVideoChunk Output{#encodedvideochunk-output-algorithm}
------------------------------------------------------------------------
Run these steps:
1. If `state` is not `“configured”`, abort the following steps.
2. Let |chunkInit| be an {{EncodedVideoChunkInit}} with the following keys:
1. Let data contain the encoded video data.
2. Let type be the {{EncodedVideoChunkType}} of the encoded video data.
3. Let timestamp be the timestamp from the associated input {{VideoFrame}}.
4. Let duration be the duration from the associated input {{VideoFrame}}.
3. Let |chunk| be a new {{EncodedVideoChunk}} constructed with |chunkInit|.
4. Invoke **[[output callback]]** with chunk.
Configurations{#configurations}
===============================
Codec String{#config-codec-string}
----------------------------------------------------
In other media specifications, codec strings historically accompanied a
MIME type as the “codecs=” parameter
({{MediaSource/isTypeSupported()}}, {{HTMLMediaElement/canPlayType()}})
[[RFC6381]]. In this specification, encoded media is not containerized; hence,
only the value of the codecs parameter is accepted.
A valid codec string must meet the following conditions.
1. Is valid per the relevant codec specification (see examples below).
2. It describes a single codec.
NOTE: Not a comma separated list.
3. It is unambiguous about codec profile and level for codecs that define these
concepts.
Valid examples include:
* 'vp8'
* 'vp<IP_ADDRESS>'
* 'avc1.4D401E',
* 'opus',
* 'mp4a.40.2',
* 'flac'
Invalid examples include:
* 'video/webm; codecs="vp8"' (invalid to supply full mimetype; valid as just
'vp8')
* 'codecs="opus"' (invalid to include codecs= prefix)
* ‘flac,vorbis’ (describes more than one codec)
* ‘vp9’ (ambiguous about profile and level)
* 'video/mp4' (describes a container, not a codec)
AudioDecoderConfig{#audio-decoder-config}
-----------------------------------------
dictionary AudioDecoderConfig {
required DOMString codec;
required unsigned long sampleRate;
required unsigned long numberOfChannels;
BufferSource description;
};
To check if an {{AudioDecoderConfig}} is a valid AudioDecoderConfig,
run these steps:
1. If codec is not a valid codec string, return `false`.
2. Return `true`.
- codec
- Contains a codec string describing the codec.
- sampleRate
- The number of frame samples per second.
- numberOfChannels
- The number of audio channels.
- description
-
A sequence of codec specific bytes, commonly known as extradata.
NOTE: For example, the vorbis “code book”.
VideoDecoderConfig{#video-decoder-config}
-----------------------------------------
dictionary VideoDecoderConfig {
required DOMString codec;
BufferSource description;
required unsigned long codedWidth;
required unsigned long codedHeight;
unsigned long cropLeft;
unsigned long cropTop;
unsigned long cropWidth;
unsigned long cropHeight;
unsigned long displayWidth;
unsigned long displayHeight;
};
To check if a {{VideoDecoderConfig}} is a valid VideoDecoderConfig,
run these steps:
1. If {{VideoDecoderConfig/codec}} is not a valid codec string, return
`false`.
2. If {{VideoDecoderConfig/codedWidth}} = 0 or
{{VideoDecoderConfig/codedHeight}} = 0, return `false`.
3. If {{VideoDecoderConfig/cropWidth}} = 0 or {{VideoDecoderConfig/cropHeight}}
= 0, return `false`.
4. If {{VideoDecoderConfig/cropTop}} + {{VideoDecoderConfig/cropHeight}} >=
{{VideoDecoderConfig/codedHeight}}, return `false`.
5. If {{VideoDecoderConfig/cropLeft}} + {{VideoDecoderConfig/cropWidth}} >=
{{VideoDecoderConfig/codedWidth}}, return `false`.
6. If {{VideoDecoderConfig/displayWidth}} = 0 or
{{VideoDecoderConfig/displayHeight}} = 0, return `false`.
7. Return `true`.
- codec
- Contains a codec string describing the codec.
- description
-
A sequence of codec specific bytes, commonly known as extradata.
NOTE: For example, the VP9 vpcC bytes.
- codedWidth
-
Width of the VideoFrame in pixels, prior to any cropping or aspect ratio
adjustments.
- codedHeight
-
Height of the VideoFrame in pixels, prior to any cropping or aspect ratio
adjustments.
- cropLeft
-
The number of pixels to remove from the left of the VideoFrame, prior to
aspect ratio adjustments. Defaults to zero if not present.
- cropTop
-
The number of pixels to remove from the top of the VideoFrame, prior to
aspect ratio adjustments. Defaults to zero if not present.
- cropWidth
-
The width of pixels to include in the crop, starting from cropLeft.
Defaults to codedWidth if not present.
- cropHeight
-
The height of pixels to include in the crop, starting from cropLeft.
Defaults to codedHeight if not present.
- displayWidth
-
Width of the VideoFrame when displayed. Defaults to cropWidth if not
present.
- displayHeight
-
Height of the VideoFrame when displayed. Defaults to cropHeight if not
present.
AudioEncoderConfig{#audio-encoder-config}
-----------------------------------------
dictionary AudioEncoderConfig {
required DOMString codec;
unsigned long sampleRate;
unsigned long numberOfChannels;
};
To check if an {{AudioEncoderConfig}} is a valid AudioEncoderConfig,
run these steps:
1. If {{AudioEncoderConfig/codec}} is not a valid codec string, return
`false`.
2. Return `true`.
- codec
- Contains a codec string describing the codec.
- sampleRate
- The number of frame samples per second.
- numberOfChannels
- The number of audio channels.
VideoEncoderConfig{#video-encoder-config}
-----------------------------------------
dictionary VideoEncoderConfig {
required DOMString codec;
unsigned long long bitrate;
required unsigned long width;
required unsigned long height;
};
To check if a {{VideoEncoderConfig}} is a valid VideoEncoderConfig,
run these steps:
1. If {{VideoEncoderConfig/codec}} is not a valid codec string, return
`false`.
2. If {{VideoEncoderConfig/width}} = 0 or {{VideoEncoderConfig/height}} = 0,
return `false`.
4. Return `true`.
- width
- The expected cropWidth of input VideoFrames to encode.
- height
- The expected cropHeight of input VideoFrames to encode.
VideoEncoderEncodeOptions{#video-encoder-options}
-------------------------------------------------
dictionary VideoEncoderEncodeOptions {
boolean keyFrame = false;
};
- keyFrame
-
A value of `true` indicates that the given frame MUST be encoded as a key
frame. A value of `false` indicates that the user agent has flexibility to
decide whether the frame will be encoded as a key frame.
CodecState{#codec-state}
------------------------
enum CodecState {
"unconfigured",
"configured",
"closed"
};
- unconfigured
- The codec is not configured for encoding or decoding.
- configured
-
A valid configuration has been provided. The codec is ready for encoding or
decoding.
- closed
-
The codec is no longer usable and underlying system resources have been
released.
WebCodecsErrorCallback{#error-callback}
---------------------------------------
callback WebCodecsErrorCallback = undefined(DOMException error);
Encoded Media Interfaces (Chunks) {#encoded-media-interfaces}
=============================================================
These interfaces represent chunks of encoded media.
EncodedAudioChunk Interface {#encodedaudiochunk-interface}
------------------------------------------------------------
interface EncodedAudioChunk {
constructor(EncodedAudioChunkInit init);
readonly attribute EncodedAudioChunkType type;
readonly attribute unsigned long long timestamp; // microseconds
readonly attribute ArrayBuffer data;
};
dictionary EncodedAudioChunkInit {
required EncodedAudioChunkType type;
required unsigned long long timestamp;
required BufferSource data;
};
enum EncodedAudioChunkType {
"key",
"delta",
};
### Constructors ###{#encodedaudiochunk-constructors}
EncodedAudioChunk(init)
1. Let |chunk| be a new {{EncodedAudioChunk}} object, initialized as follows
1. Assign `init.type` to `chunk.type`.
2. Assign `init.timestamp` to `chunk.timestamp`.
3. Assign a copy of `init.data` to `chunk.data`.
5. Return |chunk|.
### Attributes ###{#encodedaudiochunk-attributes}
- type
- Describes whether the chunk is a key frame.
- timestamp
- The presentation timestamp, given in microseconds.
- data
- A sequence of bytes containing encoded audio data.
EncodedVideoChunk Interface{#encodedvideochunk-interface}
-----------------------------------------------------------
[Exposed=(Window,Worker)]
interface EncodedVideoChunk {
constructor(EncodedVideoChunkInit init);
readonly attribute EncodedVideoChunkType type;
readonly attribute unsigned long long timestamp; // microseconds
readonly attribute unsigned long long? duration; // microseconds
readonly attribute ArrayBuffer data;
};
dictionary EncodedVideoChunkInit {
required EncodedVideoChunkType type;
required unsigned long long timestamp;
unsigned long long duration;
required BufferSource data;
};
enum EncodedVideoChunkType {
"key",
"delta",
};
### Constructors ###{#encodedvideochunk-constructors}
EncodedVideoChunk(init)
1. Let |chunk| be a new {{EncodedVideoChunk}} object, initialized as follows
1. Assign `init.type` to chunk type.
2. Assign `init.timestamp` to `chunk.timestamp`.
3. If duration is present in init, assign `init.duration` to
`chunk.duration`. Otherwise, assign null to `chunk.duration`.
2. Assign a copy of `init.data` to `chunk.data`.
3. Return |chunk|.
### Attributes ###{#encodedvideochunk-attributes}
- type
- Describes whether the chunk is a key frame or not.
- timestamp
- The presentation timestamp, given in microseconds.
- duration
- The presentation duration, given in microseconds.
- data
- A sequence of bytes containing encoded video data.
Raw Media Interfaces (Frames){#raw-media-interfaces}
====================================================
These interfaces represent unencoded (raw) media.
AudioFrame Interface {#audioframe-interface}
---------------------------------------------
[Exposed=(Window,Worker)]
interface AudioFrame {
constructor(AudioFrameInit init);
readonly attribute unsigned long long timestamp;
readonly attribute AudioBuffer? buffer;
undefined close();
};
dictionary AudioFrameInit {
required unsigned long long timestamp;
required AudioBuffer buffer;
};
### Internal Slots ###{#audioframe-internal-slots}
- \[[detached]]
-
Boolean indicating whether close() was invoked and underlying resources
have been released.
### Constructors ###{#audioframe-constructors}
AudioFrame(init)
1. Let |frame| be a new {{AudioFrame}} object.
2. Assign `init.timestamp` to `frame.timestamp`.
3. Assign `init.buffer` to `frame.buffer`.
4. Assign `false` to the {{AudioFrame/[[detached]]}} internal slot.
5. Return |frame|.
### Attributes ###{#audioframe-attributes}
- timestamp
- The presentation timestamp, given in microseconds.
- buffer
- The buffer containing decoded audio data.
### Methods ###{#audioframe-methods}
- close()
-
Immediately frees system resources. When invoked, run these steps:
1. Release system resources for buffer and set its value to null.
2. Assign `true` to the {{AudioFrame/[[detached]]}} internal slot.
NOTE: This section needs work. We should use the name and semantics of
VideoFrame destroy(). Similarly, we should add clone() to make a deep
copy.
VideoFrame Interface {#videoframe-interface}
--------------------------------------------
[Exposed=(Window,Worker)]
interface VideoFrame {
constructor(ImageBitmap imageBitmap, VideoFrameInit frameInit);
constructor(PixelFormat pixelFormat, sequence<(Plane or PlaneInit)> planes,
VideoFrameInit frameInit);
readonly attribute PixelFormat format;
readonly attribute FrozenArray planes;
readonly attribute unsigned long codedWidth;
readonly attribute unsigned long codedHeight;
readonly attribute unsigned long cropLeft;
readonly attribute unsigned long cropTop;
readonly attribute unsigned long cropWidth;
readonly attribute unsigned long cropHeight;
readonly attribute unsigned long displayWidth;
readonly attribute unsigned long displayHeight;
readonly attribute unsigned long long? duration;
readonly attribute unsigned long long? timestamp;
undefined destroy();
VideoFrame clone();
Promise createImageBitmap(
optional ImageBitmapOptions options = {});
};
dictionary VideoFrameInit {
unsigned long codedWidth;
unsigned long codedHeight;
unsigned long cropLeft;
unsigned long cropTop;
unsigned long cropWidth;
unsigned long cropHeight;
unsigned long displayWidth;
unsigned long displayHeight;
unsigned long long duration;
unsigned long long timestamp;
};
### Internal Slots ###{#videoframe-internal-slots}
- \[[detached]]
-
Boolean indicating whether {{destroy()}} was invoked and underlying
resources have been released.
### Constructors ###{#videoframe-constructors}
NOTE: this section needs work. Current wording assumes a VideoFrame can always
be easily represented using one of the known pixel formats. In practice, the
underlying UA resources may be GPU backed or formatted in such a way that
conversion to an allowed pixel format requires expensive copies and
translation. When this occurs, we should allow planes to be null and format
to be “opaque” to avoid early optimization. We should make conversion
explicit and user controlled by offering a `videoFrame.convertTo(format)`
that returns a Promise containing a new VideoFrame for which the
copies/translations are performed.
VideoFrame(imageBitmap, frameInit)
1. If |frameInit| is not a valid VideoFrameInit, throw a {{TypeError}}.
2. If the value of |imageBitmap|'s' {{PlatformObject/[[Detached]]}} internal
slot is set to `true`, then throw an {{InvalidStateError}} DOMException.
3. Let |frame| be a new {{VideoFrame}}.
4. Assign `false` to |frame|’s {{VideoFrame/[[detached]]}} internal slot.
5. Use a copy of the pixel data in |imageBitmap| to initialize to following
frame attributes:
1. Initialize `frame.pixelFormat` be the underlying format of imageBitmap.
2. Initialize `frame.planes` to describe the arrangement of memory of the
copied pixel data.
3. Assign regions of the copied pixel data to the
{{Plane/[[plane buffer]]}} internal slot of each plane as
appropriate for the pixel format.
4. Initialize `frame.codedWidth` and `frame.codedHeight` describe the width
and height of the imageBitamp prior to any cropping or aspect ratio
adjustments.
6. Use |frameInit| to initialize the remaining frame attributes:
1. If `frameInit.cropLeft` is present, initialize it `frame.cropLeft`.
Otherwise, default `frame.cropLeft` to zero.
2. If `frameInit.cropTop` is present, initialize it to `frame.cropTop`.
Otherwise, default `frame.cropTop` to zero.
3. If `frameInit.cropWidth` is present, initialize it to `frame.cropWidth`.
Otherwise, default `frame.cropWidth` to `frame.codedWidth`.
4. If `frameInit.cropHeight` is present, initialize it to
`frame.cropHeight`. Otherwise, default `frame.cropHeight` to
`frame.codedHeight`.
5. If `frameInit.displayWidth` is present, initialize it to
`frame.displayWidth`. Otherwise, default `frame.displayWidth` to
`frame.codedWidth`.
6. If `frameInit.displayHeight` is present, initialize it to
`frame.displayHeight`. Otherwise, default `frame.displayHeight` to
`frame.codedHeight`.
7. If `frameInit.duration` is present, initialize it to `frame.duration`.
Otherwise, default `frame.duration` to null.
8. If `frameInit.timestamp` is present, initialize it to `frame.timestamp`.
Otherwise default `frame.timestamp` to null.
7. Return |frame|.
VideoFrame(pixelFormat, planes, frameInit)
1. If either {{VideoFrameInit/codedWidth}} or {{VideoFrameInit/codedHeight}} is
not present in |frameInit|, throw a {{TypeError}}.
2. If |frameInit| is not a valid VideoFrameInit, throw a {{TypeError}}.
3. If the length of |planes| is incompatible with the given pixelFormat, throw a
TypeError.
4. Let |frame| be a new {{VideoFrame}} object.
5. Assign `false` to |frame|’s {{VideoFrame/[[detached]]}} internal slot.
6. Assign `init.pixelFormat` to `frame.pixelFormat`.
7. For each element |p| in |planes|:
1. If |p| is a {{Plane}}, append a copy of p to `frame.planes`. Continue
processing the next element.
2. If |p| is a {{PlaneInit}}, append a new {{Plane}} q to
`frame.planes` initialized as follows:
2. Assign a copy of `p.src` to q's [[plane buffer]] internal slot.
NOTE: the samples should be copied exactly, but the user agent may add
row padding as needed to improve memory alignment.
3. Assign the width of each row in [[plane buffer]], including any
padding, to `q.stride`.
4. Assign `p.rows` to `q.rows`.
5. Assign the product of (`q.rows` * `q.stride)` to `q.length`
8. Assign `frameInit.codedWidth` to `frame.codedWidth`.
9. Assign `frameInit.codedHeight` to `frame.codedHeight`.
10. If `frameInit.cropLeft` is present, assign it `frame.cropLeft`. Otherwise,
default `frame.cropLeft` to zero.
11. If `frameInit.cropTop` is present, assign it to `frame.cropTop`. Otherwise,
default `frame.cropTop` to zero.
12. If `frameInit.cropWidth` is present, assign it to `frame.cropWidth`.
Otherwise, default `frame.cropWidth` to `frame.codedWidth`.
13. If `frameInit.cropHeight` is present, assign it to `frame.cropHeight`.
Otherwise, default `frame.cropHeight` to `frame.codedHeight`.
14. If `frameInit.displayWidth` is present, assign it to `frame.displayWidth`.
Otherwise, default `frame.displayWidth` to `frame.codedWidth`.
15. If `frameInit.displayHeight` is present, assign it to `frame.displayHeight`.
Otherwise, default `frame.displayHeight` to `frame.codedHeight`.
16. If `frameInit.duration` is present, assign it to `frame.duration`.
Otherwise, default `frame.duration` to null.
17. If `frameInit.timestamp` is present, assign it to `frame.timestamp`.
Otherwise, default `frame.timestamp` to null.
18. Return frame.
### Attributes ###{#videoframe-attributes}
- timestamp
-
The presentation timestamp, given in microseconds. The timestamp is copied
from the EncodedVideoChunk corresponding to this VideoFrame.
- duration
-
The presentation duration, given in microseconds. The duration is copied
from the EncodedVideoChunk corresponding to this VideoFrame.
- format
-
Describes the arrangement of bytes in each plane as well as the number and
order of the planes.
- planes
-
Holds pixel data data, laid out as described by format and Plane
attributes.
- codedWidth
-
Width of the VideoFrame in pixels, prior to any cropping or aspect ratio
adjustments.
- codedHeight
-
Height of the VideoFrame in pixels, prior to any cropping or aspect ratio
adjustments.
- cropLeft
-
The number of pixels to remove from the left of the VideoFrame, prior to
aspect ratio adjustments.
- cropTop
-
The number of pixels to remove from the top of the VideoFrame, prior to
aspect ratio adjustments.
- cropWidth
- The width of pixels to include in the crop, starting from cropLeft.
- cropHeight
- The height of pixels to include in the crop, starting from cropLeft.
- displayWidth
- Width of the VideoFrame when displayed.
- displayHeight
- Height of the VideoFrame when displayed.
### Methods ###{#videoframe-methods}
destroy()
Immediately frees system resources. Destruction applies to all references,
including references that are serialized and passed across Realms.
NOTE: Authors should take care to manage frame lifetimes by calling
{{VideoFrame/destroy()}} immediately when frames are no longer needed.
NOTE: Use clone() to create a deep copy. Cloned frames have their own lifetime
and will not be affected by destroying the original frame.
When invoked, run these steps:
1. If {{VideoFrame/[[detached]]}} is `true`, throw an {{InvalidStateError}}.
2. Remove all {{Plane}}s from {{VideoFrame/planes}} and release associated
memory.
3. Assign `true` to the {{VideoFrame/[[detached]]}} internal slot.
clone()
Creates a new {{VideoFrame}} with a separate lifetime containing a deep copy of
this frame’s resources.
NOTE: VideoFrames may require a large amount of memory. Use
{{VideoFrame/clone()}} sparingly.
When invoked, run the following steps:
1. If the value of the {{VideoFrame/[[detached]]}} slot is `true`, return a
Promise rejected with a newly created {{InvalidStateError}}.
2. Let |p| be a new Promise.
3. In parallel, resolve |p| with the result of running the Clone Frame
algorithm with this.
4. Return |p|.
createImageBitmap(options)
Creates an ImageBitmap from this {{VideoFrame}}.
When invoked, run these steps:
1. Let |p| be a new Promise.
2. If either |options|'s {{ImageBitmapOptions/resizeWidth}} or
{{ImageBitmap/resizeHeight}} is present and is 0, then return |p| rejected
with an {{InvalidStateError}} {{DOMException}}.
3. If the this' {{VideoFrame/[[detached]]}} internal slot is set to
`true`, then return |p| rejected with an {{InvalidStateError}}
{{DOMException}}.
4. Let |imageBitmap| be a new {{ImageBitmap}} object.
5. Set |imageBitmap|'s bitmap data to a copy of the {{VideoFrame}} pixel data,
at the frame's intrinsic width and intrinsic height (`i.e`., after any
aspect-ratio correction has been applied), cropped to the source rectangle
with formatting.
6. If the origin of |imageBitmap|'s image is not same origin with entry settings
object's origin, then set the origin-clean flag of |imageBitmap|'s bitmap to
`false`.
7. Run this step in parallel:
1. Resolve p with imageBitmap.
### Algorithms ###{#videoframe-algorithms}
To check if a {{VideoDecoderConfig}} is a valid VideoFrameInit,
run these steps:
1. If {{VideoFrameInit/codedWidth}} = 0 or {{VideoFrameInit/codedHeight}} = 0,
return `false`.
2. If {{VideoFrameInit/cropWidth}} = 0 or {{VideoFrameInit/cropHeight}} = 0,
return `false`.
3. If {{VideoFrameInit/cropTop}} + {{VideoFrameInit/cropHeight}} >=
{{VideoFrameInit/codedHeight}}, return `false`.
4. If {{VideoFrameInit/cropLeft}} + {{VideoFrameInit/cropWidth}} >=
{{VideoFrameInit/codedWidth}}, return `false`.
5. If {{VideoFrameInit/displayWidth}} = 0 or
{{VideoFrameInit/displayHeight}} = 0, return `false`.
6. Return `true`.
Plane Interface {#plane-interface}
----------------------------------
A {{Plane}} acts like a thin wrapper around an {{ArrayBuffer}}, but may actually
be backed by a texture. {{Plane}}s hide any padding before the first sample
or after the last row.
A {{Plane}} is solely constructed by its {{VideoFrame}}. During construction,
the User Agent may use knowledge of the frame’s {{PixelFormat}} to add
padding to the {{Plane}} to improve memory alignment.
A {{Plane}} cannot be used after the {{VideoFrame}} is destroyed. A new
{{VideoFrame}} can be assembled from existing {{Plane}}s, and the new
{{VideoFrame}} will remain valid when the original is destroyed. This makes
it possible to efficiently add an alpha plane to an existing {{VideoFrame}}.
interface Plane {
readonly attribute unsigned long stride;
readonly attribute unsigned long rows;
readonly attribute unsigned long length;
undefined readInto(ArrayBufferView dst);
};
dictionary PlaneInit {
required BufferSource src;
required unsigned long stride;
required unsigned long rows;
};
### Internal Slots ###{#plane-internal-slots}
- [[parent frame]]
- Refers to the {{VideoFrame}} that constructed and owns this plane.
- [[plane buffer]]
- Internal storage for the plane’s pixel data.
### Attributes ###{#plane-attributes}
- stride
- The width of each row including any padding.
- rows
- The number of rows.
- length
- The total byte length of the plane (stride * rows).
### Methods ###{#plane-methods}
readInto(dst)
Copies the plane data into dst.
When invoked, run these steps:
1. If {{Plane/[[parent frame]]}} has been destroyed, throw an
{{InvalidStateError}}.
2. If {{Plane/length}} is greater than |`dst.byteLength`|, throw a
{{TypeError}}.
3. Copy the {{Plane/[[plane buffer]]}} into dst.
Pixel Format{#pixel-format}
---------------------------
Pixel formats describe the arrangement of bytes in each plane as well as the
number and order of the planes.
NOTE: This section needs work. We expect to add more pixel formats and offer
much more verbose definitions. For now, please see
http://www.fourcc.org/pixel-format/yuv-i420/ for a more complete
description.
enum PixelFormat {
"I420"
};
- I420
-
Planar 4:2:0 YUV.
Algorithms{#raw-media-algorithms}
---------------------------------
Clone Frame (with |frame|)
1. Let |cloneFrame| be a new object of the same type as frame (either
{{AudioFrame}} or {{VideoFrame}}).
2. Initialize each attribute and internal slot of clone with a copy of the value
from the corresponding attribute of this frame.
NOTE: User Agents are encouraged to avoid expensive copies of large objects
(for instance, {{VideoFrame}} pixel data). Frame types are immutable, so the
above step may be implemented using memory sharing techniques such as
reference counting.
3. Return |cloneFrame|.
VideoTrackReader Interface{#videotrackreader-interface}
=======================================================
{{VideoTrackReader}} emits {{VideoFrame}}s from a {{MediaStreamTrack}}. Authors
may use this interface to manipulate, render, or encode streams from
{{mediaDevices/getUserMedia()}} and {{mediaDevices/getDisplayMedia()}}.
[Exposed=Window]
interface VideoTrackReader {
constructor(MediaStreamTrack track);
readonly attribute VideoTrackReaderState readyState;
attribute EventHandler onended;
undefined start(VideoFrameOutputCallback callback);
undefined stop();
};
enum VideoTrackReaderState {
"started",
"stopped",
"ended"
};
VideoTrackReaderState Values{#videotrackreaderreadystate}
--------------------------------------------------------------
- started
-
Indicates that the {{VideoTrackReader/[[track]]}} is
{{MediaStreamTrackState/live}} and {{VideoFrame}}s are being output to
the {{VideoTrackReader/[[callback]]}} provided to
{{VideoTrackReader/start()}}.
- stopped
-
Indicates that the {{VideoTrackReader/[[track]]}} is
{{MediaStreamTrackState/live}}, but the
{{VideoTrackReader/[[callback]]}} is not set, so no {{VideoFrame}}s are
being output.
- ended
-
Indicates that the {{VideoTrackReader/[[track]]}} is
{{MediaStreamTrackState/ended}} and this object can no longer be
{{VideoTrackReaderState/started}} nor {{VideoTrackReaderState/stopped}}.
Internal Slots {#videotrackreader-slots}
----------------------------------------
- \[[track]]
- The {{MediaStreamTrack}} provided at construction.
- \[[callback]]
-
The {{VideoFrameOutputCallback}} assigned by the last call to
{{VideoTrackReader/start()}}.
Constructors{#videotrackreader-constructors}
---------------------------------------------
VideoTrackReader(track)
1. If `track.kind` is not `"video"`, throw a {{TypeError}}.
2. If `track.readyState` is `"ended"`, throw an {{InvalidStateError}}.
3. Let |reader| be a new {{VideoTrackReader}} object.
4. Assign track to the {{VideoTrackReader/[[track]]}} internal
slot.
5. Assign `"stopped"` to `reader.readyState`.
6. Return |reader|.
Attributes{#videotrackreader-attributes}
----------------------------------------
- readyState
-
Indicates the current state of the {{VideoTrackReader}} object.
- onended
- The event handler for the ended event.
Event Summary{#videotrackreader-events}
---------------------------------------
- ended
-
Dispatched when the {{VideoTrackReader/[[track]]}}'s
{{VideoTrackReader/readyState}} becomes `"ended"`, indicating no further
{{VideoFrame}}s will be output.
Methods{#videotrackreader-methods}
----------------------------------
start(callback)
Starts calling the callback with {{VideoFrame}}s from the {{MediaStreamTrack}}.
When invoked, run these steps:
1. If {{VideoTrackReader/readyState}} is not `"stopped"`, throw an
{{InvalidStateError}}.
2. Assign `"started"` to {{VideoTrackReader/readyState}}.
3. Assign callback to the {{VideoTrackReader/[[callback]]}}
internal slot.
4. In parallel, run the track monitor.
stop()
Stops calling the {{VideoFrameOutputCallback}} with {{VideoFrame}}s from the
{{MediaStreamTrack}}.
When invoked, run these steps:
1. If readyState is not `"started"`, throw an {{InvalidStateError}}.
2. Cease running the track monitor.
3. Assign `"stopped"` to the {{VideoTrackReader/readyState}}.
4. Assign `null` to the {{VideoTrackReader/[[callback]]}} internal slot.
MediaStreamTrack Monitoring{#mediastreamtrack-monitoring}
---------------------------------------------------------
The track monitor may be started and stopped by the user to
control the calling of the {{VideoFrameOutputCallback}}.
Running the track
monitor means monitoring {{VideoTrackReader/[[track]]}} for the
arrival of new picture data as well as changes to `[[track]].readyState`.
While `[[track]].readyState` is {{MediaStreamTrackState/live}}, for each new
picture that arrives in {{VideoTrackReader/[[track]]}}, execute the
following steps:
NOTE: Pictures that arrived prior to the start of this loop are not
considered.
NOTE: Video data in a MediaStreamTrack does not have a canonical binary
form. The user agent should tokenize "pictures" by discrete times of
capture. For example, if the source is a camera capturing 60 frames per
second, the UA should construct 60 corresponding VideoFrame's each
second.
1. Let |planes| be a sequence of {{Plane}}s containing the picture data.
2. Let |pixelFormat| be the {{PixelFormat}} of |planes|.
NOTE: This section needs work. The UA should avoid early optimizations to
convert between PixelFormats, but currently only a narrow set of formats
is defined in this spec. We should consider adding an "opaque" format
along with an API coverter API to make pixel format conversion
transparent to authors.
3. Let |frameInit| be an {{VideoFrameInit}} with the following keys:
1. Let timestamp and duration be the
presentation timestamp and (optionally) presentation duration as
determined by the {{VideoTrackReader/[[track]]}} source.
2. Let codedWidth and codedHeight> be the
width and height of the decoded video frame in pixels, prior to any
cropping or aspect ratio adjustments.
3. Let cropLeft, cropTop,
cropWidth, and cropHeight be the
crop region of the decoded video frame in pixels, prior to any aspect
ratio adjustments.
4. Let displayWidth and displayHeight
be the display size of the decoded video frame in pixels.
4. Let |frame| be a {{VideoFrame}}, constructed with |pixelFormat|,
|planes|, and |frameInit|.
5. Invoke {{VideoTrackReader/[[callback]]}} with |frame|.
If {{VideoTrackReader/[[track]]}}.readyState becomes `"ended"`,
queue a task on the media element task source to run the
following steps:
1. Set {{VideoTrackReader/readyState}} to "ended".
2. Queue a task on the media element task source to run a simple
event named {{VideoTrackReader/ended}} at the {{VideoTrackReader}}.


THE LAST DAYS OF DISCO (WARNER BROTHERS) RUNNING TIME: 1 HOUR 53 MINUTES STARRING CHLOE SEVIGNY AND KATE BECKINSALE. DIRECTED BY WHIT STILLMAN
An entertaining 2 hours awaits the audience in this film set in the early 80's. Sevigny and Beckinsale play disco chicks Alice and Charlotte, who are on the lookout for love. Alice is mousy, shy, intellectual, Charlotte is bitchy, out-going and fun. We join their adventures as they go through a variety of adventures, and men, all to the background of the local disco.
Whit Stillman has both written and directed an interesting and believable story. Alice and Charlotte are both well written characters, and the actresses who play them aren't bad aswell. Sevigny delivers an honest performance, and makes the audience feel for her character.  The huge supporting cast also play a part in making sure this movie is thoroughly entertaining. The dialogue is sharp and well written, with many funny set pieces. For example, there's a great discussion about Lady & The Tramp by the main characters. The disco tunes playing in the background also make sure that this admittedly long film is good fun.
The direction is good, bringing out the drama and comedy in the scenes. But their are slight flaws with the movie. Firstly, although it is supposedly set in the 80's, the characters are very, very 90's. The way they dress and act have a very 90's feel to them.  Also, as mentioned above, the film is too long, and some parts do lag. The charm of the characters do help these moments, but generally the editing could of been a bit tighter. The plot also side-tracks into a silly cocaine dealing bust, which seemed out of place in this movie. Finally, their are almost too many characters in the film, and despite the running time, the film never really spends enough time on them. Some of the characters are very slight, which is a shame. The conclusion, while funny, is also surprisingly weak, and certainly not strong enough.
But despite these qualms, The Last Days of Disco is a funny, warm movie, which is certainly worth seeing, and is a fitting homage to the disco era of the 80's. Worth a look.
OVERALL RATING=***1/2 OUT OF *****
REVIEW BY DAVID WILCOCK ©1998
DAVID WILCOCK<EMAIL_ADDRESS>Visit the Wilcock Movie Page! http://wilcockmovie.home.ml.org -OR- http://www.geocities.com/Hollywood/9061 Recieve Wilcock Movie Page Reviews via E-MAIL Send a blank E-MAIL to<EMAIL_ADDRESS>to join the mailing list!
"You know, for kids"- Norville Barnes
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


First-aid workers slam medic arrests at Hong Kong campus
HONG KONG: Hong Kong medical workers on Friday (Nov 22) expressed outrage over the arrests this week of a number of colleagues at a university campus occupied by protesters, and called on the government to allow them to do their jobs.
Darren Mann, a city doctor, said that he and other medical workers had volunteered Sunday to treat injuries at the campus of Hong Kong Polytechnic University (PolyU), which saw fiery clashes between police and protesters.
READ: Handful of Hong Kong protesters surrender as university siege staggers on
READ: Isolated band of protesters holds out on trashed Hong Kong campus
When police that night declared that anyone on the campus was subject to arrest for rioting, those detained included teams of medical workers - even though many wore vests clearly identifying themselves as first-aid personnel.
"If you saw ambulancemen, kneeling with their hands behind their back, and zip-ties around their wrists, you would be rightfully outraged," Mann told a press conference.
Mann said the protest satisfied all international criteria for "a mass casualty incident", with victims suffering injuries such as choking from tear gas, burns, broken bones, and rubber-bullet wounds.
"These are the injuries of warfare. Why was it being managed there? Because that's where the injuries occurred," Mann said.
"Usually you don't want your first-aid providers to leave. In our proud tradition, we are the last people to leave."
READ: China ready to 'fight back' over US Hong Kong Bill
Commentary: This may be the end of Hong Kong as we know it
It was unclear how many medical workers were detained on rioting allegations, but police said they had arrested 51 people at the campus who had claimed to be medics or reporters.
Around 700 people in total were arrested at PolyU.
The university remained under siege on Friday, with a dwindling cohort of perhaps dozens of holdouts still hiding in university buildings.
A registered nurse, who spoke on condition of anonymity, told AFP he had led a team of eight volunteers, but was arrested after complying with a police order to leave Tuesday night.
"I followed the police instructions to leave the campus, but I didn't know that they will go back on their word and arrest us," said the 30-year-old, who is out on bail.
He and around ten other volunteers were forced to kneel on the ground while their hands were zip-tied.
His hands remained restrained the entire night, leaving bruises on his wrists, and police accused him and others of being "fake paramedics".
"I felt very helpless and angry. I did not do anything illegal," he said.
READ: 'Smelly' sewer escape bid by PolyU protesters ends in arrest
READ: Abuse and acrimony as crisis-hit Hong Kong holds district polls
Hong Kong's months of protest began with a now-shelved bill to allow extraditions to mainland China, which revived fears that Beijing was slicing into the city's freedoms.
Millions of angry citizens have taken to the streets in giant marches, and protesters have repeatedly clashed with police in a movement that has widened to include calls for democracy and an inquiry into alleged police brutality.
Hong Kong's Beijing-appointed leaders have rebuffed the demands.
MORE: Our coverage of the Hong Kong protests
Follow us on Telegram for the latest on Hong Kong: https://cna.asia/telegram


menu
Settings
Settings
Date of Session
Rate aspect of session here.
Rate aspect of session here.
Rate aspect of session here.
Notes on Session
Submit


Once the page has loaded some JavaScript into the browser, you can
access it within <script>
tags on the page.
<head> <script src="../js/shCore.js"></script> <script src="../js/shBrushJScript.js"></script> <link href="../css/shCore.css" /> <link href="../css/shThemeDefault.css" /> </head>
You can include the following JavaScript within the <body>
element of this page and refresh the page.
<script type="text/javascript"> SyntaxHighlighter.all(); </script>


this is the
amazing
header section
some content with this on top
and this in the middle
and this on the bottom
and this is the footer, with an awesome copyright symbol with the year next to it - © 2013


--- author: admin blogger_id: tag:blogger.com,1999:blog-15525201.post-6432110195978427215 blogger_orig_url: https://asmaier.blogspot.com/2010/04/instantshift.html date: "2010-04-10T22:10:00Z" modified_time: "2010-04-10T23:54:51.520+02:00" tags: - old_blog - german title: InstantShift ---


{% extends 'logo/home.html' %} {% block body %} Thank you for your entry. Stay tuned to our facebook page for the results :) {% endblock %}
Thank you for your entry. Stay tuned to our facebook page for the results :)


Rock, Paper, Scissors
(Best out of 3 rounds wins!)
Player
Board
Click an image to make your move
Computer


--- layout: post status: publish published: true title: 6th Day Violation author: display_name: Tomas Restrepo login: tomasr email<EMAIL_ADDRESS>url: http://winterdom.com/ author_login: tomasr author_email<EMAIL_ADDRESS>author_url: http://winterdom.com/ wordpress_id: 713 wordpress_url: http://winterdom.com/2003/03/6thdayviolation date: '2003-03-18 20:18:35 +0000' date_gmt: '2003-03-18 20:18:35 +0000' categories: - Blogging tags: [] comments: - id: 482 author: David Stone author_email<EMAIL_ADDRESS>author_url: http://dotnetweblogs.com/dstone date: '2003-03-18 21:42:35 +0000' date_gmt: '2003-03-18 21:42:35 +0000' content: |
They've even left the copyright and your e-mail in there. Too funny.
---Seems like I've been cloned. Any idea what this site is, and why it seems to have an almost complete copy of my website?
UPDATE: Seems I'm not the only one to have been bitten by this...


Introducing Cron AlarmsWe just launched a brand new feature, cron alarms and they are pretty freaking awesome.
Free cron monitoring, all thanks to you.We get some great feedback here at cronasaservice.com, several
users have asked us to add an alarm feature to monitor their jobs. Well here it is, we will…
It seems to be the only thing that web millionaire wanna-be’s care about is growth. It’s true that growth matters but it
isn’t always obvious how you can grow a business without either sooner or later imploding it by running
out of funds or what to do when growth inevitably…
Lecture by Sam Altman from YCombinatorStarting your own Startup is a daunting but exciting task. Luckily,
there are plenty of people before you who've done it all and build billion dollar businesses in the
process. Sam Altman is one of those guys, he quit college to start his own company…
Second lecture by Sam Altman from YCombinator on launching a startupThis lecture discusses choosing a co-founder,
how important it is to choose wisely and why co-founders should be like James Bond. Sam also discusses
how not to hire employees despite how tempting it seems. The cost of getting an early hire…
Third lecure in the series with guest host Paul Graham, co-founder of YCombinatorPaul Graham gives a brilliant
and funny guest lecture. Paul discusses what happens before a startup.
What should you study at college and who should you hire? Paul answers all these…
Fourth lecture in the series, Adora Cheung guest lectures on building a product.Adora Cheung (of now defunct
HomeJoy) talks about techniques for building and growing a product. Readers of The Lean Startup will
be familiar with most of these techniques but there are some valuable lessons listed here. Talk to your…


CURE (Kyua) Not Rated, 115 minutes; in Japanese with subtitles Written and Directed by Kiyoshi Kurosawa WHEN, WHERE: Opens today at The Screen
As I write, smoke and debris envelope lower Manhattan and the Pentagon on a day of incomprehensible horror and unforeseeable implications. We will know more by the time this appears in print, but it seems to be the coordinated work of suicide terrorists, controlled by authorities and allegiances as yet unknown.
Perhaps in the grip of today's context it is difficult not to filter everything through the trauma of this evil. Writer/director Kiyoshi (no relation to Akira) Kurosawa's 1997 film is about a series of grisly, ritualized murders, connected in style but committed by different people. The murderers are all easily found; they know what they've done, but they don't know why. `It seemed like the natural thing to do at the time,' one says. The victims are strangers, friends, loved ones. Detective Takabe (Koji Yakusho of `Shall We Dance') and his psychologist colleague Sakuma (Tsuyoshi Ujiki) grope for theories (`The devil made them do it'), and finally hit upon the answer: the killers seem to have been operating under the hypnotic control of a shadowy stranger, a veritable Johnny Appleseed of murder. The premise is a shaky one in literal terms. Most of what we know about hypnosis from a layman's perspective (which is to say, from movies and TV shows) suggests that people cannot be hypnotized to do something abhorrent to them, and this is touched on but not pursued in `Cure'. And the ease with which people are brought under hypnotic trance also stretches credulity. In the classic `The Manchurian Candidate', Laurence Harvey's hypnotic suggestion is triggered by a playing card, but the groundwork has been laid over months of captivity and treatment. Here the trigger is just a simple, but there's no preparation, and the effects are instantaneous and devastating. But there are many layers of darkness at work here, and Kurosawa may be suggesting that the most unimaginable atrocities are not abhorrent to us at some level. The story cuts away from Takabe's investigation of the murders periodically to follow the wanderings of a rootless young man whose name, from a label in his overcoat, seems to be Mamiya (Masato Hagiwara). He claims to have no idea who he is or where he is. He suffers from amnesia of the `How long have you had this problem?' `What problem?' variety. The suspicion grows from time to time that he may be dissembling, but we never know for sure. There are many things we never know for sure, including who he is, where he comes from, and what he wants. Motives are almost entirely absent from the eerie world Kurosawa creates here; there may even be something supernatural at work. `No one understands what motivates a criminal,' the psychologist Sakuma repeats on several occasions, and while one might take issue with that as blanket truth, it applies here. Complicating Detective Takabe's job and distracting his professional focus is the fact that his wife also suffers from a degenerative amnesia. This personal tragedy ties him with particular force to the man he is investigating, who seems to know more than he should about the detective's situation and even what goes on inside his head. Kurosawa keeps his colors muted and his camera at a distance from the action for the most part, telling the story with dispassionate coolness. He strews the field with questions, but is not generous with answers. You'll leave the theater baffled by things that have no apparent explanation – who is the man in the dry cleaners, and what is his relationship with Takabe? `Cure' is intriguing, frustrating, and sometimes annoying. It's also hypnotic. Even when the crimes are solved and the guilty brought to bay, there is none of the sense of closure that we expect. In a way that disconcertingly reflects the world around us, something ominous and ungraspable still hangs in the air, refusing to be exorcized by the closing credits.
========== X-RAMR-ID: 29457 X-Language: en X-RT-ReviewID: 249829 X-RT-TitleID: 1109442 X-RT-AuthorID: 2779
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Structures
The following structures are available globally.
-
SBALearnInfo
implementation that uses a localizable plist.Declaration
Swift
public struct SBALearnInfoPList : SBALearnInfo
-
SBALearnInfo
implementation that can be decoded from JSON, PList, or Dictionary.Declaration
Swift
public struct SBALearnInfoObject : SBALearnInfo, Codable
-
The learn item object is a concrete, serializable implementation of the
See moreSBALearnItem
protocol.Declaration
Swift
public struct SBALearnItemObject : SBALearnItem, Codable
-
The type of a profile data source. This is used to decode the data source in a factory.
See moreDeclaration
Swift
public struct SBAProfileDataSourceType : RawRepresentable, Codable
-
The type of a profile table section. This is used to decode the section in a factory.
See moreDeclaration
Swift
public struct SBAProfileSectionType : RawRepresentable, Codable
-
The type of the profile item. This is used to decode the item in a factory.
See moreDeclaration
Swift
public struct SBAProfileItemType : RawRepresentable, Codable
-
The type of a profile manager. This is used to decode the manager in a factory.
See moreDeclaration
Swift
public struct SBAProfileManagerType : RawRepresentable, Codable
-
The type of a profile table item. This is used to decode the item in a factory.
See moreDeclaration
Swift
public struct SBAProfileTableItemType : RawRepresentable, Codable
-
A profile table item that displays HTML when selected.
See moreDeclaration
Swift
public struct SBAHTMLProfileTableItem : SBAProfileTableItem, Decodable, RSDResourceTransformer
-
A profile table item that displays, and allows editing, the value of a Profile Item.
See moreDeclaration
Swift
public struct SBAProfileItemProfileTableItem : SBAProfileTableItem, Decodable
-
A profile table item that, when selected, segues to another profile table view.
See moreDeclaration
Swift
public struct SBAProfileViewProfileTableItem : SBAProfileTableItem, Decodable
-
The category type of an object. This is used to decide which decode*(from:) method to call to decode the item.
See moreDeclaration
Swift
public struct SBACategoryType : RawRepresentable, Codable
-
See moreRSDModuleIdentifier
is intended to allow a developer to add a light-weight reference to active task modules (such as a tapping task or hole-in-peg test) by referencing an identifier string that can be used to reference a module defined in a different framework.Declaration
Swift
public struct SBAModuleIdentifier : RawRepresentable, Codable, Hashable
-
SBAActivityGroupObject
is aDecodable
implementation of aSBAActivityGroup
.- example:
“`
// Example activity group using a shared
schedulePlanGuid`. let json ={ "identifier”: “foo”, “title”: “Title”, “journeyTitle”: “Journey title”, “detail”: “A detail about the object”, “imageSource”: “fooImage”, “activityIdentifiers”: [“taskA”, “taskB”, “taskC”], “notificationIdentifier”: “scheduleFoo”, “schedulePlanGuid”: “abcdef12-3456-7890”, }
.data(using: .utf8)! // our data in native (JSON) format
// Example activity group using the
activity.guid
identifiers to map schedules to tasks. let json ={ “identifier”: “foo”, “activityIdentifiers”: [“taskA”, “taskB”, “taskC”], “activityGuidMap”: { “taskA”:“ababab12-3456-7890”, “taskB”:“cdcdcd12-3456-7890”, “taskC”:“efefef12-3456-7890” } }
.data(using: .utf8)! // our data in native (JSON) format// Example activity group where the first schedule matching the given activity identifer is used. let json =
{ “identifier”: “foo”, “activityIdentifiers”: [“taskA”, “taskB”, “taskC”] }
.data(using: .utf8)! // our data in native (JSON) format
See moreDeclaration
Swift
public struct SBAActivityGroupObject : Decodable, SBAOptionalImageVendor, SBAActivityGroup
- example:
“`
-
SBAActivityInfoObject
is aDecodable
implementation of aSBAActivityInfo
.- example:
“”
// Example JSON for a task that references a module id.
let json =
{ “identifier”: “foo”, “title”: “Title”, “subtitle”: “Subtitle”, “detail”: “A detail about the object”, “imageSource”: “fooImage”, “minuteDuration”: 10, “moduleId”: “tapping” }
.data(using: .utf8)! // our data in native (JSON) format
// Example JSON for a task that references an embedded resource file. let json =
{ “identifier”: “foo”, “title”: “Title”, “subtitle”: “Subtitle”, “detail”: “A detail about the object”, “imageSource”: “fooImage”, “minuteDuration”: 10, “resource”: { “resourceName” : “Foo_Task”, “bundleIdentifier” : “org.example.Foo”, “classType” : “FooTask” } }
.data(using: .utf8)! // our data in native (JSON) format
See moreDeclaration
Swift
public struct SBAActivityInfoObject : Decodable, SBAOptionalImageVendor, SBAActivityInfo
- example:
“”
// Example JSON for a task that references a module id.
let json =


How To Make A Website In HTML
P Pilko - Enriched English
Tools You Need
To type up your code you must have a text editor Atom, Notepad++, Nano, etc. You can find these on your web browser. To view your code you must have a web browser, I prefer Google Chrome and Mozilla Firefox. You also need a place you can host your website (I will go into this later).
Essential Files
Some essential files you need are an HTML, CSS, and an assets folder. The HTML file is where your website is created. The CSS file is where you make your webpage look decent. The assets folder is where you keep pictures, backgrounds, pdfs, etc.
Putting your website together with HTML
beginning
To start you website you must do many things. The first thing you must do is
create an HTML file. The folder can be named anything you want but has to end
in .html
The next step you must take is to make your document HTML. To do this you must
type the expression <!doctype html>
.
The next part you must do before you start inserting your information is to
make an HTML tag

.
The Head
The head is the information the computers look at from the tags you put in. To
define the head you must put in the tags
and
.
The tags in the head give the computers different types of information to look at. These tags are called title, base, link, meta, script, and style. They all define information for the computers
The Body
The Body is the information the people who view your website look at. This contains tags that tell the computer how to present your information to the user. For example the body contains headers, paragraphs, images, links, videos, and other types of info.
The tag

means paragraph.
The tag

creates a heading, h1 is a heading but is usually
used for titles, h2 is a subheading for h1, h3 is a subheading for h2, etc. These
headings range from 1 to 6 in size.
The image and video tag are quite obvious what they do. These are harder to make because you have to have the video or image in a folder connected to your website and you can't mess up the link.
Making your website look good with CSS
To make your website look different ways you must have a CSS file. To link a
CSS file to your HTML file you must type the expression <link rel="stylesheet" href="home.css" type="text/css">
.
Lets say you want to change the background of the webpage, to do this in CSS you must create some lines of code like the ones showed below.
You can also indent paragraphs and have other cosmetics, but I won't go into that.
making your website public
To let other people view your webpage you have to host it.  I use GitHub to host websites because it is free, but if you don't want to use GitHub you can use someone else or host it your self.
thank you
Thank you for looking at my website on how to make a website. I hope you learned something!


Mailchimp subscription form
Mailchimp is a marketing automation platform and an email marketing service.
In other words this Mailchimp widget will help you to collect user emails right from you website to run email marketing campaign via Mailchimp web application. Below is the live example of the widget that collects emails for Createx Studio. Switch to HTML tab to see code example and instructions.

Subscribe

<form class="subscription-form validate" action="mailchimp-embedded-form-atcion-link" method="post" name="mc-embedded-subscription-form" target="_blank" novalidate>

<input class="form-control" type="email" name="EMAIL" placeholder="Your email">

<button class="btn btn-primary" type="submit" name="subscribe">Subscribe*</button>

<input class="subscription-form-antispam" type="text" name="mailchimp-embedded-form-antispam-name-attribute" tabindex="-1">

*Subscribe to our newsletter to receive early discount offers, updates and new products info.

</form>


Dashboard
Home
Dashboard
THIS MONTH
$58,356
LAST MONTH
$48,356
A basic message
(Click on image)
Title with a text under
(Click on image)
Success Message
(Click on image)
Warning message
(Click on image)
A basic message
(Click on image)
Alert with Image
(Click on image)
Alert with time
(Click on image)


| 1 |
|
|
| 2 |
|
|
| 3 |
|
|
| 4 |
|
|
| 5 |
|
|
| 6 |
|
|
| 7 |
|
|
| 8 |
|
|
| 9 |
|
|
| 10 |
|
|
| 11 |
|
|
| 12 |
|
|
| 13 |
|
|
| 14 |
|
|
| 15 |
|
|
| 16 |
|
|
| 17 |
|
|
| 18 |
|
|
| 19 |
|
package org.apache.kylin.source.adhocquery; |
| 20 |
|
|
| 21 |
|
import org.junit.Test; |
| 22 |
|
|
| 23 |
|
import junit.framework.TestCase; |
| 24 |
|
|
| |
|
| 100% |
Uncovered Elements: 0 (32) |
Complexity: 8 |
Complexity Density: 0.33 |
|
| 25 |
|
public class HivePushDownConverterTest extends TestCase { |
| |
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
1PASS
|
|
| 26 |
2 |
@Test... |
| 27 |
|
public void testStringReplace() { |
| 28 |
2 |
String originString = "select count(*) as cnt from test_kylin_fact where char_length(lstg_format_name) < 10"; |
| 29 |
2 |
String replacedString = HivePushDownConverter.replaceString(originString, "char_length", "length"); |
| 30 |
2 |
assertEquals("select count(*) as cnt from test_kylin_fact where length(lstg_format_name) < 10", replacedString); |
| 31 |
|
} |
| 32 |
|
|
| |
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
1PASS
|
|
| 33 |
2 |
@Test... |
| 34 |
|
public void testExtractReplace() { |
| 35 |
2 |
String originString = "ignore EXTRACT(YEAR FROM KYLIN_CAL_DT.CAL_DT) ignore"; |
| 36 |
2 |
String replacedString = HivePushDownConverter.extractReplace(originString); |
| 37 |
2 |
assertEquals("ignore YEAR(KYLIN_CAL_DT.CAL_DT) ignore", replacedString); |
| 38 |
|
} |
| 39 |
|
|
| |
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
1PASS
|
|
| 40 |
2 |
@Test... |
| 41 |
|
public void testCastReplace() { |
| 42 |
2 |
String originString = "ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS INTEGER)) ignore"; |
| 43 |
2 |
String replacedString = HivePushDownConverter.castReplace(originString); |
| 44 |
2 |
assertEquals("ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS int)) ignore", replacedString); |
| 45 |
|
} |
| 46 |
|
|
| |
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
1PASS
|
|
| 47 |
2 |
@Test... |
| 48 |
|
public void testSubqueryReplace1() { |
| 49 |
2 |
String originString = "select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) group by seller_id,lstg_format_name"; |
| 50 |
2 |
String replacedString = HivePushDownConverter.subqueryReplace(originString); |
| 51 |
2 |
assertEquals( |
| 52 |
|
"select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) as alias group by seller_id,lstg_format_name", |
| 53 |
|
replacedString); |
| 54 |
|
} |
| 55 |
|
|
| |
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
1PASS
|
|
| 56 |
2 |
@Test... |
| 57 |
|
public void testSubqueryReplace2() { |
| 58 |
2 |
String originString = "select count(*) from ( select test_kylin_fact.lstg_format_name from test_kylin_fact where test_kylin_fact.lstg_format_name='FP-GTC' group by test_kylin_fact.lstg_format_name ) t "; |
| 59 |
2 |
String replacedString = HivePushDownConverter.subqueryReplace(originString); |
| 60 |
2 |
assertEquals(originString, replacedString); |
| 61 |
|
} |
| 62 |
|
|
| |
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
1PASS
|
|
| 63 |
2 |
@Test... |
| 64 |
|
public void testSubqueryReplace3() { |
| 65 |
2 |
String originString = "select fact.lstg_format_name from (select * from test_kylin_fact where cal_dt > date'2010-01-01' ) as fact group by fact.lstg_format_name order by CASE WHEN fact.lstg_format_name IS NULL THEN 'sdf' ELSE fact.lstg_format_name END "; |
| 66 |
2 |
String replacedString = HivePushDownConverter.subqueryReplace(originString); |
| 67 |
2 |
assertEquals(originString, replacedString); |
| 68 |
|
} |
| 69 |
|
|
| |
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
1PASS
|
|
| 70 |
2 |
@Test... |
| 71 |
|
public void testSubqueryReplace4() { |
| 72 |
2 |
String originString = "select t.TRANS_ID from (\n" + |
| 73 |
|
" select * from test_kylin_fact s inner join TEST_ACCOUNT a \n" + |
| 74 |
|
" on s.BUYER_ID = a.ACCOUNT_ID inner join TEST_COUNTRY c on c.COUNTRY = a.ACCOUNT_COUNTRY\n" + |
| 75 |
|
" )t\n" + |
| 76 |
|
"LIMIT 50000"; |
| 77 |
2 |
String replacedString = HivePushDownConverter.subqueryReplace(originString); |
| 78 |
2 |
assertEquals(originString, replacedString); |
| 79 |
|
} |
| 80 |
|
|
| |
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0.33 |
1PASS
|
|
| 81 |
2 |
@Test... |
| 82 |
|
public void testConcatReplace() { |
| 83 |
2 |
String originString = "select count(*) as cnt from test_kylin_fact where lstg_format_name||'a'='ABINa'"; |
| 84 |
2 |
String replacedString = HivePushDownConverter.concatReplace(originString); |
| 85 |
2 |
assertEquals("select count(*) as cnt from test_kylin_fact where concat(lstg_format_name,'a')='ABINa'", |
| 86 |
|
replacedString); |
| 87 |
|
} |
| 88 |
|
|
| 89 |
|
} |


{% extends "soc/models/list.html" %} {% comment %} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. {% endcomment %} {% load ghop_forms_helpers %} {% block stylesheet %} {{ block.super }} {% endblock %} {% block scripts %} {{ block.super }} {% endblock %} {% block body %}
{{ block.super }} {% endblock %}


|
Mackey
V3
A C++ library for computing RO(G) homology
|
Contains the class and methods for multiplying generators. More...
#include "../Green.hpp"
Namespaces | |
| Mackey | |
| The namespace for everything that is group-independent. | |
| Mackey::internal | |
| Contains classes and methods whose user interface is provided by the rest of the library. | |
Functions | |
| template<typename group_t > | |
| group_t::rank_t | Mackey::multiply (const chains_t< group_t > &C, const chains_t< group_t > &D, int level, int degreeC, int degreeD, int selectC=0, int selectD=0) |
Contains the class and methods for multiplying generators.


- valueOf(String) - Static method in enum com.samsungpay.s2p.membership.model.Barcode.Symbology
-
Returns the enum constant of this type with the specified name.
- valueOf(String) - Static method in enum com.samsungpay.s2p.membership.model.MembershipIDType
-
Returns the enum constant of this type with the specified name.
- valueOf(String) - Static method in enum com.samsungpay.s2p.membership.Registration.CardStatus
-
Returns the enum constant of this type with the specified name.
- values() - Static method in enum com.samsungpay.s2p.membership.model.Barcode.Symbology
-
Returns an array containing the constants of this enum type, in
the order they are declared.
- values() - Static method in enum com.samsungpay.s2p.membership.model.MembershipIDType
-
Returns an array containing the constants of this enum type, in
the order they are declared.
- values() - Static method in enum com.samsungpay.s2p.membership.Registration.CardStatus
-
Returns an array containing the constants of this enum type, in
the order they are declared.


None.
Location: Head Uncinate Neck Body
Size:
Characterization: Cystic Solid Mixed
Enhancement:
Connection with the main PD:
Accessory PD secondary branch:
Calcification and pattern:
Fat:
Local extension:
Vascular involvement:
Bile ducts:
Pancreatic duct:
Adjacent nodes:
Distant metastases:


GHANIAN CULTURE NAME
GHANIAN CULTURE NAME is a web application that help Ghanian people to know their Akan Name through to take their birthday date and show the day of the week they were born and then depending on their gender outputs their Akan Name.
Akan names are derived from Ghanian culture. Frequently in Ghana, children are given their first name as a 'day name' which corresponds to the day in the week they were born. Please enter your birth date for know your akan name and day was born.


About you
- you lied 🥺
not only lied
- you cheates🥺
not only cheats
- you pretends🥺
not only pretends
- you are not romantic🥺
not only that
- you got many concubines🥺
if this are the only problem it would have been better
but🥺🥺🥺
you act innocent innocent that you never does anything 😭😭😭😭😭😭😭😭


Implementations of two classical sorting algorithms, with the flexibility of taking
a comparator
as input. This is a predicate able to perform a comparison between
any two elements of the unsorted input list as parameters, and return the atoms
'=', '<', or '>', to indicate whether the first parameter is positionally
identical to, comes before, or comes after, the second parameter, respectively.
The choice of these atoms allows the use of the compare/3 predicate as the
comparator for any of these two sorts.
mergesort
sorting algorithm on generic lists.
Mergesort is an efficient, general-purpose, and comparison-based sorting algorithm.
This is a stable sort implementation, meaning that the relative order of equal
sort items is preserved. For a description of the mergesort algorithm, see
https://en.wikipedia.org/wiki/Merge_sort .<Comparator>(-Result:atom, +ValueX, +ValueY) is det where Result is unified with a) = ('equal' sign) - ValueX is positionally identical to ValueY b) < ('less than' sign) - ValueX comes before ValueY c) > ('greater than' sign) - ValueX comes after ValueY
The criteria that will determine the results of the comparisons are entirely up to Comparator, and as such it must be able to handle the values it will receive. In most cases, the built-in predicate compare/3 may be readily used as the comparator for the sort. Nothing is done if List has less than 2 elements.
<Comparator>(-Result:atom, +ValueX, +ValueY) is det where Result is unified with a) = ('equal' sign) - ValueX is positionally identical to ValueY b) < ('less than' sign) - ValueX comes before ValueY c) > ('greater than' sign) - ValueX comes after ValueY
The criteria that will determine the results of the comparisons are entirely up to Comparator, and as such it must be able to handle the values it will receive. In most cases, the built-in predicate compare/3 may be readily used as the comparator for the sort. Nothing is done if List has less than 2 elements.


LICENSE¶
Except when noted in individual files, this project is distributed under BSD 3-Clause License.
Note
If this file is changed, “LICENSE.txt” and “licenses.txt” must be updated too.
License Text (BSD 3-Clause License)¶
Copyright (c) 2008-2015, Jesus Cea Avion<EMAIL_ADDRESS>All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of Jesus Cea Avion nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

License of individual files¶
The history of this project is long and complicated, and so are their copyrights and licenses. I (Jesus Cea) write this document in orden to clarify the situation.
This code was integrated once in Python 2.x, so I guess somebody did the paperwork related to contributor agreement. This code is derived from that version, so that could be a license checkpoint/blank sheet. I must verify that.
New files will be covered by the 3-clause BSD license.
License of Python files¶
- Except the following files, license is 3-clause BSD license. Jesus Cea Avion.
- test2.py, test3.py: Zope Public License, version 2.0. Zope Corporation and contributors.
- Lib*/bsddb/dbrecio.py: Itamar Shtull-Trauring<EMAIL_ADDRESS>- Lib*/bsddb/__init__.py: 3-clause BSD license. Digital Creations and Andrew Kuchling.
- Lib*/bsddb/db.py: 3-clause BSD license. Digital Creations and Andrew Kuchling.
- Lib*/bsddb/dbobj.py, dbutils.py: Free software. Autonomous Zone Industries, Gregory P. Smith.
- Lib*/bsddb/dbtables.py: Free software. Autonomous Zone Industries, Gregory P. Smith.
- Lib*/bsddb/test/test_dbtables.py: Free software. Autonomous Zone Industries, Gregory P. Smith.
- Lib*/bsddb/dbshelve.py: Free software. Total Control Software.
License of C files¶
- Modules/bsddb.h, _bsddb.c: 3-clause BSD license. Digital Creations, Andrew Kuchling, Robin Dunn, Gregory P. Smith, Duncan Grisby, Jesus Cea Avion.


Holonix
The development commons for Holochain.
Workflows and dependencies for all major operating systems.
The development commons for Holochain.
Workflows and dependencies for all major operating systems.
We designed Holonix to enable developer productivity in a FOSS and extensible way based on the assumption that productivity comes from …
Holonix works on all major operating systems (mostly) without VMs. This is possible thanks to the awesome work by the NixOS Foundation and …
We designed Holonix to avoid common and fundamental “works on my machine” style frustrations, by focusing on predictability. It embodies …
Linux/Mac Mac system dependencies Holonix assumes Xcode is installed. Xcode is the official Mac developer toolkit so is likely to already …

Writing a bash script Most repositories benefit from a set of “quality of life” scripts. Bash is by far the lowest common denominator. It …
Holochain rust components There are three main artifacts provided by holochain. The rust conductor The holochain development kit (hdk) The …
@todo https://forum.holochain.org/t/im-spinning-up-some-docs-for-holonix-feedback-welcome/451/12?u=thedavidmeister An old but mostly still …
@todo https://forum.holochain.org/t/im-spinning-up-some-docs-for-holonix-feedback-welcome/451/12?u=thedavidmeister npm binaries There is a …
@todo https://forum.holochain.org/t/im-spinning-up-some-docs-for-holonix-feedback-welcome/451/12?u=thedavidmeister
@todo https://forum.holochain.org/t/im-spinning-up-some-docs-for-holonix-feedback-welcome/451/12?u=thedavidmeister
@todo https://forum.holochain.org/t/im-spinning-up-some-docs-for-holonix-feedback-welcome/451/12?u=thedavidmeister
@todo https://forum.holochain.org/t/im-spinning-up-some-docs-for-holonix-feedback-welcome/451/12?u=thedavidmeister
workflow Holonix defines a simple, language agnostic release workflow. It assumes a develop and master branch. It assumes a changelog. The …
Overview Every IDE has different functionality, assumptions and audience. Even ignoring nix we need to deal with interactions between …
@todo https://forum.holochain.org/t/im-spinning-up-some-docs-for-holonix-feedback-welcome/451/12?u=thedavidmeister
Holochain forum The forum is the best place to seek help for all things holochain. There is a category dedicated to holonix discussion. …
@todo https://forum.holochain.org/t/im-spinning-up-some-docs-for-holonix-feedback-welcome/451/12?u=thedavidmeister below all pulled …


| uvm_reg_item.svh | |
| Variables | |
| kind | Kind of access: READ or WRITE. |
| value | The value to write to, or after completion, the value read from the DUT. |
| offset | For memory accesses, the offset address. |
| parent | The sequence from which the operation originated. |
| extension | Handle to optional user data, as conveyed in the call to write(), read(), mirror(), or update() used to trigger the operation. |
| Methods | |
| do_copy | Copy the rhs object into this object. |
rand uvm_access_e kind
Kind of access: READ or WRITE.
Access to this variable is provided for randomization, otherwise interactions with it shall be via the set_kind() and get_kind() accessor methods
@uvm-contrib This variable is being considered for potential contribution to 1800.2
rand uvm_reg_data_t value[]
The value to write to, or after completion, the value read from the DUT. Burst operations use the values property.
Access to this variable is provided for randomization, otherwise interactions with it shall be via the set_value_array() and get_value_array() accessor methods
@uvm-contrib This variable is being considered for potential contribution to 1800.2
rand uvm_reg_addr_t offset
For memory accesses, the offset address. For bursts, the starting offset address.
Access to this variable is provided for randomization, otherwise interactions with it shall be via the set_offset() and get_offset() accessor methods
@uvm-contrib This variable is being considered for potential contribution to 1800.2
rand uvm_sequence_base parent
The sequence from which the operation originated.
Access to this variable is provided for randomization, otherwise interactions with it shall be via the set_parent() and get_parent() accessor methods
@uvm-contrib This variable is being considered for potential contribution to 1800.2
rand uvm_object extension
Handle to optional user data, as conveyed in the call to write(), read(), mirror(), or update() used to trigger the operation.
virtual function void do_copy( uvm_object rhs )
Copy the rhs object into this object. The rhs object must derive from <uvm_reg_item>.
@uvm-contrib This API is being considered for potential contribution to 1800.2
Kind of access: READ or WRITE.
rand uvm_access_e kind
The value to write to, or after completion, the value read from the DUT.
rand uvm_reg_data_t value[]
For memory accesses, the offset address.
rand uvm_reg_addr_t offset
The sequence from which the operation originated.
rand uvm_sequence_base parent
Handle to optional user data, as conveyed in the call to write(), read(), mirror(), or update() used to trigger the operation.
rand uvm_object extension
Copy the rhs object into this object.
virtual function void do_copy( uvm_object rhs )


Achievement Unlocked!
Visit the main menu to see!
YOU WON
CONGRATULATIONS!
YOU HAVE SURVIVED ALL 10 WAVES
Play Again
Leaderboard
Main Menu


Asteroids
Asteroids Bullet Wrap
Bullet Angle Variance
Bullet Frame Cycle
Bullet Speed Variance
Fire Rate
Single Bullet
Track Pointer
Physics Overlap
On Fire Event


The article also shows that the resentment towards desegregation and the deliberate delays and avoidance of the process of desegregation in schools was far more common than just the few instances that are discussed in the textbook. In the textbook its self we see far more extreme instances where states called in the nation guard to prevent colored children from attending schools and even schools closing all together. It is shocking that during this time, some states and counties would rather shut down their schools completely than allow colored children to attend.
This article showed me that desegregation was not as simple as the supreme court telling states that they had to integrate schools. It showed me that it was a lot of fighting from both sides, both for and against, and that it took years for colored people to achieve the equality they deserved. I think that this translates into many aspects of the civil rights movement. It proved that just because it’s the law, doesn’t mean people with abide by it. This can be seen in situations such as the desegregation of public areas where colored people would be physically assaulted and in some places were even arrested for doing things that federal law and the constitution stated they could do.


Highlight the array element containing the largest value
Choose something between 0 and index lastIndex
This problem is really too easy for a second hint