// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.media;

// fuchsia.media contains definitions shared by the various fuchsia.media.*
// libraries. Definitions in this file concern the representation of type
// (i.e. format or encoding) for elementary streams.

using fuchsia.images;

/// Describes the type of an elementary stream.
type StreamType = struct {
    /// Medium-specific type information.
    medium_specific MediumSpecificStreamType;

    /// Encoding (see constants below). This value is represented as a string
    /// so that new encodings can be introduced without modifying this file.
    encoding string:255;

    /// Encoding-specific parameters, sometimes referred to as 'out-of-band
    /// data'. Typically, this data is associated with a compressed stream and
    /// provides parameters required to decompress the stream. This data is
    /// generally opaque to all parties except the producer and consumer of the
    /// stream.
    encoding_parameters vector<uint8>:optional;
};

/// A union of all medium-specific stream type structs.
type MediumSpecificStreamType = strict union {
    1: audio AudioStreamType;
    2: video VideoStreamType;
    3: text TextStreamType;
    4: subpicture SubpictureStreamType;
};

/// Audio encodings.
const AUDIO_ENCODING_AAC string = "fuchsia.media.aac";
const AUDIO_ENCODING_AACLATM string = "fuchsia.media.aaclatm";
const AUDIO_ENCODING_AMRNB string = "fuchsia.media.amrnb";
const AUDIO_ENCODING_AMRWB string = "fuchsia.media.amrwb";
const AUDIO_ENCODING_APTX string = "fuchsia.media.aptx";
const AUDIO_ENCODING_FLAC string = "fuchsia.media.flac";
const AUDIO_ENCODING_GSMMS string = "fuchsia.media.gsmms";
const AUDIO_ENCODING_LPCM string = "fuchsia.media.lpcm";
const AUDIO_ENCODING_MP3 string = "fuchsia.media.mp3";
const AUDIO_ENCODING_PCMALAW string = "fuchsia.media.pcmalaw";
const AUDIO_ENCODING_PCMMULAW string = "fuchsia.media.pcmmulaw";
const AUDIO_ENCODING_SBC string = "fuchsia.media.sbc";
const AUDIO_ENCODING_VORBIS string = "fuchsia.media.vorbis";
const AUDIO_ENCODING_OPUS string = "fuchsia.media.opus";

/// Video encodings.
const VIDEO_ENCODING_H263 string = "fuchsia.media.h263";
const VIDEO_ENCODING_H264 string = "fuchsia.media.h264";
const VIDEO_ENCODING_MPEG4 string = "fuchsia.media.mpeg4";
const VIDEO_ENCODING_THEORA string = "fuchsia.media.theora";
const VIDEO_ENCODING_UNCOMPRESSED string = "fuchsia.media.uncompressed_video";
const VIDEO_ENCODING_VP3 string = "fuchsia.media.vp3";
const VIDEO_ENCODING_VP8 string = "fuchsia.media.vp8";
const VIDEO_ENCODING_VP9 string = "fuchsia.media.vp9";

/// Describes the compression applied to a stream. This type can be used in conjunction with
/// `AudioStreamType` or `VideoStreamType` to represent a medium-specific compressed type.
type Compression = struct {
    /// The type of compression applied to the stream. This is generally one of the *_ENCODING_*
    /// values, though `AUDIO_ENCODING_LPCM` and `VIDEO_ENCODING_UNCOMPRESSED` must not be used,
    /// because those encodings are regarded as uncompressed.
    type CompressionType;

    /// Type-specific, opaque 'out-of-band' parameters describing the compression of the stream.
    parameters vector<uint8>:<8192, optional>;
};

/// An identifier for compression types.
alias CompressionType = string:256;

// /////////////////////////////////////////////////////////////////////////////
// Audio

/// Describes the type of an audio elementary stream.
type AudioStreamType = struct {
    sample_format AudioSampleFormat;
    channels uint32;
    frames_per_second uint32;
    // TODO(mpuryear): Add channel config.
};

/// Enumerates the supported audio sample formats.
type AudioSampleFormat = strict enum {
    /// 8-bit unsigned samples, sample size 1 byte.
    UNSIGNED_8 = 1;

    /// 16-bit signed samples, host-endian, sample size 2 bytes.
    SIGNED_16 = 2;

    /// 24-bit signed samples in 32 bits, host-endian, sample size 4 bytes.
    SIGNED_24_IN_32 = 3;

    /// 32-bit floating-point samples, sample size 4 bytes.
    FLOAT = 4;
};

// /////////////////////////////////////////////////////////////////////////////
// Video

/// Describes the type of a video elementary stream.
type VideoStreamType = struct {
    @available(deprecated=13)
    pixel_format fuchsia.images.PixelFormat;
    // TODO(dalesat): Use fuchsia.images.ColorSpace.
    color_space ColorSpace;

    /// Dimensions of the video frames as displayed in pixels.
    width uint32;
    height uint32;

    /// Dimensions of the video frames as encoded in pixels. These values must
    /// be equal to or greater than the respective width/height values.
    coded_width uint32;
    coded_height uint32;

    /// The aspect ratio of a single pixel as frames are intended to be
    /// displayed.
    pixel_aspect_ratio_width uint32;
    pixel_aspect_ratio_height uint32;

    /// The number of bytes per 'coded' row in the primary video plane.
    stride uint32;
};

// TODO(dalesat): Replace with fuchsia.images.ColorSpace.
type ColorSpace = strict enum {
    UNKNOWN = 0;
    NOT_APPLICABLE = 1;
    JPEG = 2;
    HD_REC709 = 3;
    SD_REC601 = 4;
};

// /////////////////////////////////////////////////////////////////////////////
// Text

/// Describes the type of a text elementary stream.
type TextStreamType = struct {
        // TODO(dalesat): Define.
        };

// /////////////////////////////////////////////////////////////////////////////
// Subpicture

/// Describes the type of a subpicture elementary stream.
type SubpictureStreamType = struct {
        // TODO(dalesat): Define.
        };
