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
|