diff options
Diffstat (limited to 'gpr/source/lib/vc5_encoder/encoder.h')
-rwxr-xr-x | gpr/source/lib/vc5_encoder/encoder.h | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/gpr/source/lib/vc5_encoder/encoder.h b/gpr/source/lib/vc5_encoder/encoder.h new file mode 100755 index 0000000..1048628 --- /dev/null +++ b/gpr/source/lib/vc5_encoder/encoder.h @@ -0,0 +1,333 @@ +/*! @file encoder.h + * + * @brief Declaration of the data structures and constants used for core encoding. + * + * (C) Copyright 2018 GoPro Inc (http://gopro.com/). + * + * Licensed under either: + * - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0 + * - MIT license, http://opensource.org/licenses/MIT + * at your option. + * + * 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. + */ + +#ifndef ENCODER_H +#define ENCODER_H + +/*! + @brief Data structure for the pixel or picture aspect ratio + + @todo Should the members of the aspect ratio data structure be unsigned? +*/ +typedef struct _aspect_ratio +{ + int16_t x; //!< Numerator of the aspect ratio + int16_t y; //!< Denominator of the aspect ratio + +} ASPECT_RATIO; + +/*! + @brief Data structure for the buffers and information used by the encoder + + The encoder data structure contains information that will be + used by the encoder for decoding every sample in the sequence. + Information that varies during decoding, such as the current + subband index or the dimensions of the bands in the wavelet that + is being decoded, is stored in the codec state. + + The encoded dimensions are the width and height of the array of pixels + for each encoded channel (image plane), including padding added to + satisfy the requirements of the wavelet transforms. In the case + of 4:2:2 sampling, the encoded width and height are for the luma channel. + + The display dimensions are the width and height of the display aperture, + the displayable portion of the decoded image with padding removed. + + The display dimensions can include a row and column offset to trim + top rows and left columns from the decoded image prior to display. + + The decoded dimensions equal the encoded dimensions at full resolution + and are reduced by a power of two if decoded to a lower resolution. + The decoded dimensions are derived from the encoded dimensions and the + decoded resolution. + + The decoded dimensions are used to allocate the wavelet tree for the + lowpass and highpass coefficients decoded from the bitstream. It is + not necessary to allocate wavelets for larger resolutions than the + decoded resolution. + + For Bayer encoded images, the encoded dimensions are half the width + and height of the input dimensions (after windowing). Typically, + media containers report the display dimensions as twice the encoded + dimensions since a demosaic algorithm must be applied to produce a + displayable image that looks right to most people. + + @todo Consider changing the transform data structure to use a + vector of wavelets rather than a vector of wavelet pointers. +*/ +typedef struct _encoder +{ + // CODEC codec; //!< Common fields for both the encoder and decoder + + FILE *logfile; //!< File for writing debugging information + CODEC_ERROR error; //!< Error code from the most recent codec operation + gpr_allocator *allocator; //!< Memory allocator used to allocate all dyynamic data + CODEC_STATE codec; //!< Information gathered while decoding the current sample + VERSION version; //!< Codec version (major, minor, revision, build) + + //! Parts of the VC-5 standard that are supported at runtime by the codec implementation + ENABLED_PARTS enabled_parts; + + uint64_t frame_number; //!< Every sample in a clip has a unique frame number + + //! Number of color channels in the input and encoded images + uint_fast8_t channel_count; + + //! Number of wavelet transforms in each channel + uint_fast8_t wavelet_count; + + //! Internal precision used by this encoder + PRECISION internal_precision; + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + IMAGE_FORMAT image_format; //!< Type of the image represented by the bitstream + DIMENSION image_width; //!< Number of samples per row in the image represented by the bitstream + DIMENSION image_height; //!< Number of rows of samples in the image represented by the bitstream + DIMENSION pattern_width; //!< Number of samples per row in each pattern element + DIMENSION pattern_height; //!< Number of rows of samples in each pattern element + DIMENSION components_per_sample; //!< Number of components per sample in the image + DIMENSION max_bits_per_component; //!< Upper bound on the number of significant bits per component value +#else + DIMENSION image_width; //!< Upper bound on the width of each channel + DIMENSION image_height; //!< Upper bound on the height of each channel +#endif + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + //! Progressive frame flag + BOOLEAN progressive; + + // Interlaced frame with the top field encoded first + BOOLEAN top_field_first; + + // The encoded frame is upside down (not used) + BOOLEAN frame_inverted; +#endif + + struct _channel + { + DIMENSION width; //!< Width of the next channel in the bitstream + DIMENSION height; //!< Height of the next channel in the bitstream + + //! Precision of the component array for the next channel in the bitstream + PRECISION bits_per_component; + + //! Number of bits per lowpass coefficient + PRECISION lowpass_precision; + + } channel[MAX_CHANNEL_COUNT]; //!< Information about each channel + + //! Dimensions and format of the image that was input to the encoder + struct _input + { + DIMENSION width; //!< Width of the image input to the encoder + DIMENSION height; //!< Height of the image input to the encoder + PIXEL_FORMAT format; //!< Pixel format of the image input to the encode + + } input; //!< Information about the image input to the encoder + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + uint_least8_t layer_count; //!< Number of subsamples in each sample +#endif + + //! Wavelet tree for each channel + TRANSFORM transform[MAX_CHANNEL_COUNT]; + + //! Codebook to use for encoding + ENCODER_CODESET *codeset; + + //! Scratch buffer for unpacking the input image + PIXEL *unpacked_buffer[MAX_CHANNEL_COUNT]; + + //! Parameter that controls the amount of rounding before quantization + int midpoint_prequant; + + //! Table for the order in which channels are encoded into the bitstream + CHANNEL channel_order_table[MAX_CHANNEL_COUNT]; + + //! Number of entries in the channel order table (may be less than the channel count) + int channel_order_count; + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + uint8_t image_sequence_identifier[16]; //!< UUID used for the unique image identifier + uint32_t image_sequence_number; //!< Number of the image in the encoded sequence +#endif + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + COMPONENT_TRANSFORM *component_transform; + COMPONENT_PERMUTATION *component_permutation; +#endif + + //! Six rows of horizontal lowpass results for each channel + PIXEL *lowpass_buffer[MAX_WAVELET_COUNT][ROW_BUFFER_COUNT]; + + //! Six rows of horizontal highpass results for each channel + PIXEL *highpass_buffer[MAX_WAVELET_COUNT][ROW_BUFFER_COUNT]; + +#if VC5_ENABLED_PART(VC5_PART_SECTIONS) + ENABLED_SECTIONS enabled_sections; +#endif + +} ENCODER; + +#ifdef __cplusplus +extern "C" { +#endif + + CODEC_ERROR InitEncoder(ENCODER *encoder, const gpr_allocator *allocator, const VERSION *version); + + //TAGWORD PackedEncoderVersion(ENCODER *encoder); + + CODEC_ERROR PrepareEncoder(ENCODER *encoder, + const UNPACKED_IMAGE *image, + const ENCODER_PARAMETERS *parameters); + + CODEC_ERROR PrepareEncoderState(ENCODER *encoder, + const UNPACKED_IMAGE *image, + const ENCODER_PARAMETERS *parameters); + + CODEC_ERROR SetInputChannelFormats(ENCODER *encoder, ENCODER_PARAMETERS *parameters); + + CODEC_ERROR ReleaseEncoder(ENCODER *encoder); + + CODEC_ERROR AllocEncoderTransforms(ENCODER *encoder); + + CODEC_ERROR AllocEncoderBuffers(ENCODER *encoder); + + //CODEC_ERROR EncodeStream(IMAGE *image, STREAM *stream, PARAMETERS *parameters); + CODEC_ERROR EncodeImage(IMAGE *image, STREAM *stream, RGB_IMAGE *rgb_image, ENCODER_PARAMETERS *parameters); + + //CODEC_ERROR EncodeSingleImage(ENCODER *encoder, IMAGE *image, BITSTREAM *stream); + CODEC_ERROR EncodingProcess(ENCODER *encoder, + const UNPACKED_IMAGE *image, + BITSTREAM *stream, + const ENCODER_PARAMETERS *parameters); + + CODEC_ERROR EncodeSingleImage(ENCODER *encoder, const UNPACKED_IMAGE *image, BITSTREAM *stream); + + CODEC_ERROR EncodeSingleChannel(ENCODER *encoder, void *buffer, size_t pitch, BITSTREAM *stream); + + //CODEC_ERROR EncodeMultipleImages(ENCODER *encoder, IMAGE *image_array[], int frame_count, BITSTREAM *stream); + + CODEC_ERROR PrepareEncoderTransforms(ENCODER *encoder); + + //CODEC_ERROR ImageUnpackingProcess(ENCODER *encoder, IMAGE *image); + CODEC_ERROR ImageUnpackingProcess(const PACKED_IMAGE *packed_image, + UNPACKED_IMAGE *unpacked_image, + const ENCODER_PARAMETERS *parameters, + gpr_allocator *allocator); + + CODEC_ERROR UnpackImage(const PACKED_IMAGE *input, UNPACKED_IMAGE *output, ENABLED_PARTS enabled_parts); + + CODEC_ERROR PreprocessImageRow(uint8_t *input, DIMENSION image_width, uint8_t *output); + + CODEC_ERROR UnpackImageRow(uint8_t *input_row_ptr, + DIMENSION image_width, + PIXEL_FORMAT pixel_format, + PIXEL *output_row_ptr[], + PRECISION bits_per_component[], + int channel_count, + ENABLED_PARTS enabled_parts, + int raw_shift); + + CODEC_ERROR EncodeBitstreamHeader(ENCODER *encoder, BITSTREAM *bitstream); + + CODEC_ERROR EncodeBitstreamTrailer(ENCODER *encoder, BITSTREAM *bitstream); + + CODEC_ERROR EncodeExtensionHeader(ENCODER *encoder, BITSTREAM *bitstream); + + CODEC_ERROR EncodeExtensionTrailer(ENCODER *encoder, BITSTREAM *bitstream); + + //CODEC_ERROR EncodeLayer(ENCODER *encoder, void *buffer, size_t pitch, BITSTREAM *stream); + CODEC_ERROR EncodeMultipleChannels(ENCODER *encoder, const UNPACKED_IMAGE *image, BITSTREAM *stream); + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + CODEC_ERROR EncodeLayerHeader(ENCODER *encoder, BITSTREAM *bitstream); + CODEC_ERROR EncodeLayerTrailer(ENCODER *encoder, BITSTREAM *bitstream); +#endif + + CODEC_ERROR SetEncoderQuantization(ENCODER *encoder, + const ENCODER_PARAMETERS *parameters); + + CODEC_ERROR SetTransformQuantTable(ENCODER *encoder, int channel, const QUANT table[], int length); + + CODEC_ERROR GetChannelDimensions(ENCODER *encoder, + int channel_number, + DIMENSION *channel_width_out, + DIMENSION *channel_height_out); + + CODEC_ERROR GetMaximumChannelDimensions(const UNPACKED_IMAGE *image, DIMENSION *width_out, DIMENSION *height_out); + + DIMENSION EncodedLayerHeight(ENCODER *encoder, DIMENSION height); + + CODEC_ERROR SetEncodedBandMask(CODEC_STATE *codec, int subband); + + CODEC_ERROR EncodeChannelSubbands(ENCODER *encoder, int channel, BITSTREAM *stream); + + CODEC_ERROR EncodeChannelHeader(ENCODER *encoder, + int channel_number, + BITSTREAM *stream); + + CODEC_ERROR EncodeChannelTrailer(ENCODER *encoder, int channel, BITSTREAM *stream); + + //CODEC_ERROR EncodeLayerChannels(ENCODER *encoder, BITSTREAM *stream); + CODEC_ERROR EncodeChannelWavelets(ENCODER *encoder, BITSTREAM *stream); + + CODEC_ERROR PutVideoLowpassHeader(ENCODER *encoder, int channel_number, BITSTREAM *stream); + + CODEC_ERROR PutVideoSubbandHeader(ENCODER *encoder, int subband, QUANT quantization, BITSTREAM *stream); + CODEC_ERROR PutVideoSubbandTrailer(ENCODER *encoder, BITSTREAM *stream); + + CODEC_ERROR TransformForwardSpatialQuantFrame(ENCODER *encoder, void *buffer, size_t pitch); + + CODEC_ERROR AllocateEncoderHorizontalBuffers(ENCODER *encoder); + + CODEC_ERROR DeallocateEncoderHorizontalBuffers(ENCODER *encoder); + + CODEC_ERROR AllocateEncoderUnpackingBuffers(ENCODER *encoder, int frame_width); + + CODEC_ERROR DeallocateEncoderUnpackingBuffers(ENCODER *encoder); + + CODEC_ERROR AllocateHorizontalBuffers(gpr_allocator *allocator, + PIXEL *lowpass_buffer[], + PIXEL *highpass_buffer[], + int buffer_width); + + CODEC_ERROR DeallocateHorizontalBuffers(gpr_allocator *allocator, + PIXEL *lowpass_buffer[], + PIXEL *highpass_buffer[]); + + + CODEC_ERROR PadWaveletBands(ENCODER *encoder, WAVELET *wavelet); + + CODEC_ERROR EncodeLowpassBand(ENCODER *encoder, WAVELET *wavelet, int channel_number, BITSTREAM *stream); + + CODEC_ERROR EncodeHighpassBand(ENCODER *encoder, WAVELET *wavelet, int band, int subband, BITSTREAM *stream); + + CODEC_ERROR EncodeHighpassBandLongRuns(BITSTREAM *stream, ENCODER_CODESET *codeset, PIXEL *data, + DIMENSION width, DIMENSION height, DIMENSION pitch); + + CODEC_ERROR EncodeHighpassBandRowRuns(BITSTREAM *stream, ENCODER_CODESET *codeset, PIXEL *data, + DIMENSION width, DIMENSION height, DIMENSION pitch); + + CODEC_ERROR GetSampleOffsetSegment(BITSTREAM *bitstream, uint32_t offset, TAGVALUE *segment_out); + +#ifdef __cplusplus +} +#endif + +#endif // ENCODER_H |