summaryrefslogtreecommitdiff
path: root/gpr/source/lib/vc5_decoder/decoder.h
blob: 013aa314100353e7291f55efa454d947eedcc225 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
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