diff options
Diffstat (limited to 'gpr/source/lib/vc5_decoder/decoder.h')
-rwxr-xr-x | gpr/source/lib/vc5_decoder/decoder.h | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/gpr/source/lib/vc5_decoder/decoder.h b/gpr/source/lib/vc5_decoder/decoder.h new file mode 100755 index 0000000..013aa31 --- /dev/null +++ b/gpr/source/lib/vc5_decoder/decoder.h @@ -0,0 +1,336 @@ +/*! @file decoder.h + * + * @brief Core decoder functions and data structure + * + * @version 1.0.0 + * + * (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 DECODER_H +#define DECODER_H + +/*! + Data structure for the buffers and information used by + the decoder. + + The decoder data structure contains information that will be + used by the decoder 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. + + @todo Consider changing the transform data structure to use a + vector of wavelets rather than a vector of wavelet pointers. + + @todo Remove unused substructures + + @todo Dynamically allocate the vector of wavelet trees based on the + actual number of channels rather than the maximum channel count. + + @todo Need to handle the cases where header parameters are provided + by the application instead of being in the bitstream. + */ +typedef struct _decoder +{ + 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 + + //! Parts of the VC-5 standard that are supported at runtime by the codec implementation + ENABLED_PARTS enabled_parts; + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + uint64_t frame_number; //!< Every sample in a clip has a unique frame number +#endif + + uint16_t header_mask; //!< Track which header parameters have been decoded + bool header_finished; //!< Finished decoding the bitstream header? + bool memory_allocated; //!< True if memory for decoding has been allocated + + //! Dimensions of each channel found in the bitstream + struct _channel + { + DIMENSION width; //!< Width of this channel + DIMENSION height; //!< Height of this channnel + + //! Bits per component for the component array corresponding to this channel + uint_least8_t bits_per_component; + + bool initialized; //!< Has the channel information been initialized? + + bool found_first_codeblock; //!< Has the first codeblock in the channel been found? + + } channel[MAX_CHANNEL_COUNT]; //!< Information about each channel in the bitstream + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + //! Dimensions and format of the encoded image + struct _encoded + { + DIMENSION width; //!< Encoded width + DIMENSION height; //!< Encoded height + IMAGE_FORMAT format; //!< Encoded format + + } encoded; //!< Information about the image as represented in the bitstream +#endif + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + //! Dimensions and format of the decoded image + struct _decoded + { + DIMENSION width; //!< Decoded width + DIMENSION height; //!< Decoded height + //RESOLUTION resolution; + + } decoded; //!< Information about the decoded component arrays +#endif + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + //! Dimensions and format of the frame after post-processing (see @ref ImageRepackingProcess) + struct _output + { + DIMENSION width; //!< Output frame width + DIMENSION height; //!< Output frame height + PIXEL_FORMAT format; //!< Output frame pixel format + + } output; //!< Information about the packed image output by the image repacking process +#endif + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + //! Dimensions and format of the image output by the display process + struct _display + { + DIMENSION width; //!< Output frame width + DIMENSION height; //!< Output frame height + PIXEL_FORMAT format; //!< Output frame pixel format + + } display; //!< Information about the displayable image output by the display process +#endif + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + int layer_count; //!< Number of subsamples in each sample +#endif + + int wavelet_count; //!< Number of wavelets in each channel + + int subbands_to_decode; + + //! Wavelet tree for each channel + TRANSFORM transform[MAX_CHANNEL_COUNT]; + + //! Pointer to the active codebook for variable-length codes + CODEBOOK *codebook; + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + uint8_t image_sequence_identifier[16]; //!< UUID for the unique image sequence identifier + uint32_t image_sequence_number; //!< Number of the image in the image sequence +#endif + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + bool progressive; //!< True if the encoded frame is progressive + bool top_field_first; //!< True if the top field is encoded first +#endif + +#if VC5_ENABLED_PART(VC5_PART_SECTIONS) + bool section_flag; //!< Control whether section processing is enabled + FILE *section_logfile; //!< Log file for writing section information +#endif + +} DECODER; + +/*! + @brief Information that can be obtained from an bitstream header + + The bitstream header consists of tag-value pairs that must occur in the bitstream + before the first codeblock if the parameters are present in the bitstream. + + Consider organizing the values obtained from the bitstream into input parameters + and encoded parameters, as is done elsewhere in the decoder, even though the + bitstream does not have such a rigid syntax. + */ +typedef struct _bitstream_header +{ + uint16_t channel_count; //!< Number of channels in the bitstream + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + uint64_t frame_number; //!< Every sample in a clip has a unique frame number + PIXEL_FORMAT input_format; //!< Pixel format of the frame input to the encoder + + // Encoded dimensions and format of the encoded frame (including padding) + DIMENSION encoded_width; //!< Width of the encoded frame + DIMENSION encoded_height; //!< Height of the encoded frame + + IMAGE_FORMAT encoded_format; //!< Encoded format + + // The display aperture within the encoded frame + DIMENSION row_offset; + DIMENSION column_offset; + DIMENSION display_width; //!< Width of the displayable frame (if specified in the sample) + DIMENSION display_height; //!< Height of the displayable frame (if specified in the sample) +#endif +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + DIMENSION video_channel_count; // Number of layers? + DIMENSION current_video_channel; //TODO: Find better way to handle this + int layer_count; //!< Number of layers in the sample + bool progressive; //!< Progressive versus interlaced frames + bool top_field_first; //!< Interlaced frame with top field first +#endif + +} BITSTREAM_HEADER; + +//! Flags that indicate which header parameters have been assigned values +typedef enum _bitstream_header_flags +{ + BITSTREAM_HEADER_FLAGS_IMAGE_WIDTH = (1 << 0), + BITSTREAM_HEADER_FLAGS_IMAGE_HEIGHT = (1 << 1), + BITSTREAM_HEADER_FLAGS_CHANNEL_COUNT = (1 << 2), + BITSTREAM_HEADER_FLAGS_SUBBAND_COUNT = (1 << 3), + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + BITSTREAM_HEADER_FLAGS_IMAGE_FORMAT = (1 << 4), + BITSTREAM_HEADER_FLAGS_PATTERN_WIDTH = (1 << 5), + BITSTREAM_HEADER_FLAGS_PATTERN_HEIGHT = (1 << 6), + BITSTREAM_HEADER_FLAGS_COMPONENTS_PER_SAMPLE = (1 << 7), + BITSTREAM_HEADER_FLAGS_MAX_BITS_PER_COMPONENT = (1 << 8), + + //! Required header parameters + BITSTREAM_HEADER_FLAGS_REQUIRED = (BITSTREAM_HEADER_FLAGS_IMAGE_WIDTH | + BITSTREAM_HEADER_FLAGS_IMAGE_HEIGHT | + BITSTREAM_HEADER_FLAGS_IMAGE_FORMAT | + BITSTREAM_HEADER_FLAGS_PATTERN_WIDTH | + BITSTREAM_HEADER_FLAGS_PATTERN_HEIGHT | + BITSTREAM_HEADER_FLAGS_COMPONENTS_PER_SAMPLE), +#else + + //! Required header parameters + BITSTREAM_HEADER_FLAGS_REQUIRED = (BITSTREAM_HEADER_FLAGS_IMAGE_WIDTH | + BITSTREAM_HEADER_FLAGS_IMAGE_HEIGHT), +#endif + +} BITSTREAM_HEADER_FLAGS; + +#ifdef __cplusplus +extern "C" { +#endif + + CODEC_ERROR InitDecoder(DECODER *decoder, const gpr_allocator *allocator); + + CODEC_ERROR SetDecoderLogfile(DECODER *decoder, FILE *logfile); + + CODEC_ERROR ReleaseDecoder(DECODER *decoder); + + CODEC_ERROR PrepareDecoderState(DECODER *decoder, const DECODER_PARAMETERS *parameters); + + CODEC_ERROR PrepareDecoderTransforms(DECODER *decoder); + + CODEC_ERROR SetOutputImageFormat(DECODER *decoder, + const DECODER_PARAMETERS *parameters, + DIMENSION *width_out, + DIMENSION *height_out, + PIXEL_FORMAT *format_out); + +#if VC5_ENABLED_PART(VC5_PART_IMAGE_FORMATS) + CODEC_ERROR SetDisplayImageFormat(DECODER *decoder, + const DECODER_PARAMETERS *parameters, + DIMENSION *width_out, + DIMENSION *height_out, + PIXEL_FORMAT *format_out); +#endif + + bool ChannelLowpassBandsAllValid(const DECODER *decoder, int wavelet_index); + + PIXEL_FORMAT EncodedPixelFormat(const DECODER *decoder, const DECODER_PARAMETERS *parameters); + + CODEC_ERROR PackOutputImage(void *buffer, size_t pitch, int encoded_format, IMAGE *image); + + CODEC_ERROR ImageRepackingProcess(const UNPACKED_IMAGE *unpacked_image, + PACKED_IMAGE *packed_image, + const DECODER_PARAMETERS *parameters); + + CODEC_ERROR UpdateCodecState(DECODER *decoder, BITSTREAM *stream, TAGVALUE segment); + + bool IsHeaderParameter(TAGWORD tag); + + CODEC_ERROR UpdateHeaderParameter(DECODER *decoder, TAGWORD tag); + + CODEC_ERROR PrepareDecoder(DECODER *decoder, const DECODER_PARAMETERS *parameters); + + CODEC_ERROR AllocDecoderTransforms(DECODER *decoder); + + CODEC_ERROR ReleaseDecoderTransforms(DECODER *decoder); + + CODEC_ERROR AllocDecoderBuffers(DECODER *decoder); + + CODEC_ERROR ReleaseDecoderBuffers(DECODER *decoder); + + CODEC_ERROR AllocateChannelWavelets(DECODER *decoder, int channel); + + CODEC_ERROR DecodeStream(STREAM *stream, UNPACKED_IMAGE *image, const DECODER_PARAMETERS *parameters); + + CODEC_ERROR DecodeImage(STREAM *stream, IMAGE *image, RGB_IMAGE *rgb_image, DECODER_PARAMETERS *parameters); + + CODEC_ERROR DecodingProcess(DECODER *decoder, BITSTREAM *stream, UNPACKED_IMAGE *image, const DECODER_PARAMETERS *parameters); + + CODEC_ERROR DecodeSingleImage(DECODER *decoder, BITSTREAM *input, UNPACKED_IMAGE *image, const DECODER_PARAMETERS *parameters); + + CODEC_ERROR DecodeSampleLayer(DECODER *decoder, BITSTREAM *input, IMAGE *image); + + CODEC_ERROR DecodeChannelSubband(DECODER *decoder, BITSTREAM *input, size_t chunk_size); + + CODEC_ERROR ReconstructWaveletBand(DECODER *decoder, int channel, WAVELET *wavelet, int index); + + CODEC_ERROR ParseChannelIndex(BITSTREAM *stream, uint32_t *channel_size, int channel_count); + + DIMENSION LayerWidth(DECODER *decoder, DIMENSION width); + DIMENSION LayerHeight(DECODER *decoder, DIMENSION height); + + CODEC_ERROR ProcessSampleMarker(DECODER *decoder, BITSTREAM *stream, TAGWORD marker); + + CODEC_ERROR SetDecodedBandMask(CODEC_STATE *codec, int subband); + + CODEC_ERROR DecodeLowpassBand(DECODER *decoder, BITSTREAM *stream, WAVELET *wavelet); + + CODEC_ERROR DecodeHighpassBand(DECODER *decoder, BITSTREAM *stream, WAVELET *wavelet, int band); + + CODEC_ERROR DecodeBandRuns(BITSTREAM *stream, CODEBOOK *codebook, PIXEL *data, + DIMENSION width, DIMENSION height, DIMENSION pitch); + + CODEC_ERROR DecodeBandTrailer(BITSTREAM *stream); + + CODEC_ERROR DecodeSampleChannelHeader(DECODER *decoder, BITSTREAM *stream); + + bool IsHeaderComplete(DECODER *decoder); + + bool EndOfSample(DECODER *decoder); + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + bool EndOfLayer(DECODER *decoder); + bool IsLayerComplete(DECODER *decoder); +#endif + + bool IsDecodingComplete(DECODER *decoder); + + CODEC_ERROR ReconstructUnpackedImage(DECODER *decoder, UNPACKED_IMAGE *image); + +#if VC5_ENABLED_PART(VC5_PART_LAYERS) + CODEC_ERROR ReconstructLayerImage(DECODER *decoder, IMAGE *image); +#endif + + CODEC_ERROR TransformInverseSpatialQuantBuffer(DECODER *decoder, void *output_buffer, DIMENSION output_width, DIMENSION output_pitch); + +#ifdef __cplusplus +} +#endif + +#endif // DECODER_H |