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
|
/*! @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
|