summaryrefslogtreecommitdiff
path: root/gpr/source/lib/vc5_decoder/decoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'gpr/source/lib/vc5_decoder/decoder.h')
-rwxr-xr-xgpr/source/lib/vc5_decoder/decoder.h336
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