1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 #include <schroedinger/schro.h>
6
7
8 void
schro_params_init(SchroParams * params,int video_format)9 schro_params_init (SchroParams * params, int video_format)
10 {
11 int i;
12
13 params->transform_depth = 4;
14
15 if (params->num_refs == 0) {
16 if (video_format < 11) {
17 params->wavelet_filter_index = SCHRO_WAVELET_DESLAURIERS_DUBUC_9_7;
18 } else {
19 params->wavelet_filter_index = SCHRO_WAVELET_FIDELITY;
20 }
21 } else {
22 if (video_format < 11) {
23 params->wavelet_filter_index = SCHRO_WAVELET_LE_GALL_5_3;
24 } else {
25 params->wavelet_filter_index = SCHRO_WAVELET_DESLAURIERS_DUBUC_9_7;
26 }
27 }
28
29 switch (video_format) {
30 case SCHRO_VIDEO_FORMAT_QCIF:
31 case SCHRO_VIDEO_FORMAT_QSIF:
32 params->xblen_luma = 8;
33 params->yblen_luma = 8;
34 params->xbsep_luma = 4;
35 params->ybsep_luma = 4;
36 break;
37
38 default:
39 case SCHRO_VIDEO_FORMAT_CUSTOM:
40 case SCHRO_VIDEO_FORMAT_SIF:
41 case SCHRO_VIDEO_FORMAT_CIF:
42 case SCHRO_VIDEO_FORMAT_4SIF:
43 case SCHRO_VIDEO_FORMAT_4CIF:
44 case SCHRO_VIDEO_FORMAT_SD480I_60:
45 case SCHRO_VIDEO_FORMAT_SD576I_50:
46 params->xblen_luma = 12;
47 params->yblen_luma = 12;
48 params->xbsep_luma = 8;
49 params->ybsep_luma = 8;
50 break;
51
52 case SCHRO_VIDEO_FORMAT_HD720P_60:
53 case SCHRO_VIDEO_FORMAT_HD720P_50:
54 params->xblen_luma = 16;
55 params->yblen_luma = 16;
56 params->xbsep_luma = 12;
57 params->ybsep_luma = 12;
58 break;
59
60 case SCHRO_VIDEO_FORMAT_HD1080I_60:
61 case SCHRO_VIDEO_FORMAT_HD1080I_50:
62 case SCHRO_VIDEO_FORMAT_HD1080P_60:
63 case SCHRO_VIDEO_FORMAT_HD1080P_50:
64 case SCHRO_VIDEO_FORMAT_DC2K_24:
65 case SCHRO_VIDEO_FORMAT_DC4K_24:
66 case SCHRO_VIDEO_FORMAT_UHDTV_4K_60:
67 case SCHRO_VIDEO_FORMAT_UHDTV_4K_50:
68 case SCHRO_VIDEO_FORMAT_UHDTV_8K_60:
69 case SCHRO_VIDEO_FORMAT_UHDTV_8K_50:
70 params->xblen_luma = 24;
71 params->yblen_luma = 24;
72 params->xbsep_luma = 16;
73 params->ybsep_luma = 16;
74 break;
75 }
76 SCHRO_DEBUG ("schro_params_init %i %i %i %i", params->xblen_luma,
77 params->yblen_luma, params->xbsep_luma, params->ybsep_luma);
78
79 params->mv_precision = 2;
80 params->picture_weight_1 = 1;
81 params->picture_weight_2 = 1;
82 params->picture_weight_bits = 1;
83
84 if (params->num_refs == 0) {
85 for (i = 0; i < 3; i++) {
86 params->horiz_codeblocks[i] = 1;
87 params->vert_codeblocks[i] = 1;
88 }
89 for (i = 3; i < SCHRO_LIMIT_TRANSFORM_DEPTH + 1; i++) {
90 params->horiz_codeblocks[i] = 4;
91 params->vert_codeblocks[i] = 3;
92 }
93 } else {
94 for (i = 0; i < 2; i++) {
95 params->horiz_codeblocks[i] = 1;
96 params->vert_codeblocks[i] = 1;
97 }
98 params->horiz_codeblocks[2] = 8;
99 params->vert_codeblocks[2] = 6;
100 for (i = 3; i < SCHRO_LIMIT_TRANSFORM_DEPTH + 1; i++) {
101 params->horiz_codeblocks[i] = 12;
102 params->vert_codeblocks[i] = 8;
103 }
104 }
105
106 /* other initializations */
107
108 params->codeblock_mode_index = 1;
109 params->have_global_motion = FALSE;
110 params->picture_pred_mode = 0;
111 }
112
113 /**
114 * schro_params_calculate_iwt_sizes:
115 * @params: pointer to @SchroParams structure
116 *
117 * Calculates the size of the array used for wavelet transformation
118 * using the current video format and transformation depth in the
119 * @params structure. The @params structure is updated with the new
120 * values.
121 *
122 * The structure fields changed are: iwt_chroma_width, iwt_chroma_height,
123 * iwt_luma_width, iwt_luma_height.
124 */
125 void
schro_params_calculate_iwt_sizes(SchroParams * params)126 schro_params_calculate_iwt_sizes (SchroParams * params)
127 {
128 SchroVideoFormat *video_format = params->video_format;
129 int picture_luma_width, picture_luma_height;
130 int picture_chroma_width, picture_chroma_height;
131
132 schro_video_format_get_picture_luma_size (video_format,
133 &picture_luma_width, &picture_luma_height);
134 params->iwt_luma_width =
135 ROUND_UP_POW2 (picture_luma_width, params->transform_depth);
136 params->iwt_luma_height =
137 ROUND_UP_POW2 (picture_luma_height, params->transform_depth);
138
139 schro_video_format_get_picture_chroma_size (video_format,
140 &picture_chroma_width, &picture_chroma_height);
141 params->iwt_chroma_width =
142 ROUND_UP_POW2 (picture_chroma_width, params->transform_depth);
143 params->iwt_chroma_height =
144 ROUND_UP_POW2 (picture_chroma_height, params->transform_depth);
145
146 SCHRO_DEBUG ("iwt chroma size %d x %d", params->iwt_chroma_width,
147 params->iwt_chroma_height);
148 SCHRO_DEBUG ("iwt luma size %d x %d", params->iwt_luma_width,
149 params->iwt_luma_height);
150 }
151
152 /**
153 * schro_params_calculate_mc_sizes:
154 * @params: pointer to @SchroParams structure
155 *
156 * Calculates the size of the array used for motion compensation
157 * using the current video format and motion compensation paramters
158 * in the @params structure. The @params structure is updated with
159 * the new values.
160 *
161 * The structure fields changed are: x_num_blocks, y_num_blocks,
162 * mc_luma_width, mc_luma_height, mc_chroma_width, mc_chroma_height,
163 * x_offset, y_offset.
164 */
165 void
schro_params_calculate_mc_sizes(SchroParams * params)166 schro_params_calculate_mc_sizes (SchroParams * params)
167 {
168 SchroVideoFormat *video_format = params->video_format;
169 int width, height;
170
171 schro_video_format_get_picture_luma_size (video_format, &width, &height);
172
173 params->x_num_blocks = 4 * DIVIDE_ROUND_UP (width, 4 * params->xbsep_luma);
174 params->y_num_blocks = 4 * DIVIDE_ROUND_UP (height, 4 * params->ybsep_luma);
175
176 SCHRO_DEBUG ("picture %dx%d, num_blocks %dx%d", width, height,
177 params->x_num_blocks, params->y_num_blocks);
178
179 params->x_offset = (params->xblen_luma - params->xbsep_luma) / 2;
180 params->y_offset = (params->yblen_luma - params->ybsep_luma) / 2;
181 }
182
183 typedef struct _SchroBlockParams SchroBlockParams;
184 struct _SchroBlockParams
185 {
186 int xblen_luma;
187 int yblen_luma;
188 int xbsep_luma;
189 int ybsep_luma;
190 };
191
192 static SchroBlockParams schro_block_params[] = {
193 {0, 0, 0, 0},
194 {8, 8, 4, 4},
195 {12, 12, 8, 8},
196 {16, 16, 12, 12},
197 {24, 24, 16, 16}
198 };
199
200 /**
201 * schro_params_set_block_params:
202 * @params: pointer to SchroParams structure
203 * @index: index to standard block parameters
204 *
205 * Sets the block parameters for motion compensation in the parameters
206 * structure pointed to by @params to the
207 * standard block parameters given by @index.
208 */
209 int
schro_params_set_block_params(SchroParams * params,int index)210 schro_params_set_block_params (SchroParams * params, int index)
211 {
212 if (index < 1 || index >= ARRAY_SIZE (schro_block_params)) {
213 SCHRO_ERROR ("illegal block params index");
214 return FALSE;
215 }
216
217 params->xblen_luma = schro_block_params[index].xblen_luma;
218 params->yblen_luma = schro_block_params[index].yblen_luma;
219 params->xbsep_luma = schro_block_params[index].xbsep_luma;
220 params->ybsep_luma = schro_block_params[index].ybsep_luma;
221
222 return TRUE;
223 }
224
225 int
schro_params_get_block_params(SchroParams * params)226 schro_params_get_block_params (SchroParams * params)
227 {
228 int i;
229 for (i = 1; i < ARRAY_SIZE (schro_block_params); i++) {
230 if (schro_block_params[i].xblen_luma == params->xblen_luma &&
231 schro_block_params[i].xbsep_luma == params->xbsep_luma &&
232 schro_block_params[i].yblen_luma == params->yblen_luma &&
233 schro_block_params[i].ybsep_luma == params->ybsep_luma) {
234 return i;
235 }
236 }
237 return 0;
238 }
239
240 int
schro_params_verify_block_params(SchroParams * params)241 schro_params_verify_block_params (SchroParams * params)
242 {
243 if (params->xblen_luma < 0)
244 return FALSE;
245 if (params->yblen_luma < 0)
246 return FALSE;
247 if (params->xbsep_luma < 0)
248 return FALSE;
249 if (params->ybsep_luma < 0)
250 return FALSE;
251 if (params->xblen_luma > SCHRO_LIMIT_BLOCK_SIZE)
252 return FALSE;
253 if (params->yblen_luma > SCHRO_LIMIT_BLOCK_SIZE)
254 return FALSE;
255 if ((params->xblen_luma & 3) != 0)
256 return FALSE;
257 if ((params->xbsep_luma & 3) != 0)
258 return FALSE;
259 if ((params->yblen_luma & 3) != 0)
260 return FALSE;
261 if ((params->ybsep_luma & 3) != 0)
262 return FALSE;
263 if (params->xblen_luma < params->xbsep_luma)
264 return FALSE;
265 if (params->yblen_luma < params->ybsep_luma)
266 return FALSE;
267 if (params->xblen_luma > 2 * params->xbsep_luma)
268 return FALSE;
269 if (params->yblen_luma > 2 * params->ybsep_luma)
270 return FALSE;
271
272 return TRUE;
273 }
274
275 #ifdef unused
276 /**
277 * schro_params_set_default_codeblock:
278 * @params: pointer to SchroParams structure
279 *
280 * Sets the codeblock parameters in the parameters structure pointed to
281 * by @params to the defaults.
282 */
283 void
schro_params_set_default_codeblock(SchroParams * params)284 schro_params_set_default_codeblock (SchroParams * params)
285 {
286 int i;
287
288 for (i = 0; i < SCHRO_LIMIT_TRANSFORM_DEPTH + 1; i++) {
289 params->horiz_codeblocks[i] = 1;
290 params->vert_codeblocks[i] = 1;
291 }
292 /* FIXME default in Dirac is 0 */
293 params->codeblock_mode_index = 1;
294 }
295 #endif
296
297 /**
298 * schro_params_is_default_codeblock:
299 * @params: pointer to SchroParams structure
300 *
301 * Returns: True if the codeblocks in @params are the default codeblocks.
302 */
303 schro_bool
schro_params_is_default_codeblock(SchroParams * params)304 schro_params_is_default_codeblock (SchroParams * params)
305 {
306 int i;
307
308 for (i = 0; i < params->transform_depth + 1; i++) {
309 if (params->horiz_codeblocks[i] != 1 || params->vert_codeblocks[i] != 1) {
310 return FALSE;
311 }
312 }
313 if (params->codeblock_mode_index != 0)
314 return FALSE;
315
316 return TRUE;
317 }
318
319 void
schro_subband_get_frame_data(SchroFrameData * fd,SchroFrame * frame,int component,int position,SchroParams * params)320 schro_subband_get_frame_data (SchroFrameData * fd,
321 SchroFrame * frame, int component, int position, SchroParams * params)
322 {
323 int shift;
324 SchroFrameData *comp = &frame->components[component];
325
326 shift = params->transform_depth - SCHRO_SUBBAND_SHIFT (position);
327
328 fd->format = frame->format;
329 fd->h_shift = comp->h_shift + shift;
330 fd->v_shift = comp->v_shift + shift;
331 fd->stride = comp->stride << shift;
332 if (component == 0) {
333 fd->width = params->iwt_luma_width >> shift;
334 fd->height = params->iwt_luma_height >> shift;
335 } else {
336 fd->width = params->iwt_chroma_width >> shift;
337 fd->height = params->iwt_chroma_height >> shift;
338 }
339
340 fd->data = comp->data;
341 if (position & 2) {
342 fd->data = OFFSET (fd->data, fd->stride >> 1);
343 }
344 if (position & 1) {
345 if (SCHRO_FRAME_FORMAT_DEPTH(fd->format) ==
346 SCHRO_FRAME_FORMAT_DEPTH_S32) {
347 fd->data = OFFSET (fd->data, fd->width * sizeof (int32_t));
348 } else {
349 fd->data = OFFSET (fd->data, fd->width * sizeof (int16_t));
350 }
351 }
352 }
353
354 int
schro_subband_get_position(int index)355 schro_subband_get_position (int index)
356 {
357 const int subband_position[] = {
358 0, 1, 2, 3,
359 5, 6, 7,
360 9, 10, 11,
361 13, 14, 15,
362 17, 18, 19,
363 21, 22, 23,
364 25, 26, 27
365 };
366
367 return subband_position[index];
368 }
369
370 int
schro_params_get_frame_format(int depth,SchroChromaFormat chroma_format)371 schro_params_get_frame_format (int depth, SchroChromaFormat chroma_format)
372 {
373 if (depth == 8) {
374 switch (chroma_format) {
375 case SCHRO_CHROMA_444:
376 return SCHRO_FRAME_FORMAT_U8_444;
377 case SCHRO_CHROMA_422:
378 return SCHRO_FRAME_FORMAT_U8_422;
379 case SCHRO_CHROMA_420:
380 return SCHRO_FRAME_FORMAT_U8_420;
381 default:
382 SCHRO_ASSERT (0);
383 }
384 } else if (depth == 16) {
385 switch (chroma_format) {
386 case SCHRO_CHROMA_444:
387 return SCHRO_FRAME_FORMAT_S16_444;
388 case SCHRO_CHROMA_422:
389 return SCHRO_FRAME_FORMAT_S16_422;
390 case SCHRO_CHROMA_420:
391 return SCHRO_FRAME_FORMAT_S16_420;
392 default:
393 SCHRO_ASSERT (0);
394 }
395 } else if (depth == 32) {
396 switch (chroma_format) {
397 case SCHRO_CHROMA_444:
398 return SCHRO_FRAME_FORMAT_S32_444;
399 case SCHRO_CHROMA_422:
400 return SCHRO_FRAME_FORMAT_S32_422;
401 case SCHRO_CHROMA_420:
402 return SCHRO_FRAME_FORMAT_S32_420;
403 default:
404 SCHRO_ASSERT (0);
405 }
406 }
407
408 SCHRO_ASSERT (0);
409 }
410
411
412 const int schro_tables_lowdelay_quants[7][4][9] = {
413 { /* wavelet 0 */
414 {5, 3, 0},
415 {5, 3, 0, 4, 1},
416 {5, 3, 0, 4, 1, 5, 2},
417 {5, 3, 0, 4, 1, 5, 2, 6, 3},
418 },
419 { /* wavelet 1 */
420 {4, 2, 0},
421 {4, 2, 0, 4, 2},
422 {4, 2, 0, 4, 2, 5, 3},
423 {4, 2, 0, 4, 2, 5, 3, 7, 5},
424 },
425 { /* wavelet 2 */
426 {5, 3, 0},
427 {5, 3, 0, 4, 1},
428 {5, 3, 0, 4, 1, 5, 2},
429 {5, 3, 0, 4, 1, 5, 2, 6, 3},
430 },
431 { /* wavelet 3 */
432 {8, 4, 0},
433 {12, 8, 4, 4, 0},
434 {16, 12, 8, 8, 4, 4, 0},
435 {20, 16, 12, 12, 8, 8, 4, 4, 0},
436 },
437 { /* wavelet 4 */
438 {8, 4, 0},
439 {8, 4, 0, 4, 0},
440 {8, 4, 0, 4, 0, 4, 0},
441 {8, 4, 0, 4, 0, 4, 0, 4, 0},
442 },
443 { /* wavelet 5 */
444 {0, 4, 8},
445 {0, 4, 8, 8, 10},
446 {0, 4, 8, 8, 12, 13, 17},
447 {0, 4, 8, 8, 12, 13, 17, 17, 21},
448 },
449 { /* wavelet 6 */
450 {3, 1, 0},
451 {3, 1, 0, 4, 2},
452 {3, 1, 0, 4, 2, 6, 5},
453 {3, 1, 0, 4, 2, 6, 5, 9, 7},
454 },
455 };
456
457 void
schro_params_set_default_quant_matrix(SchroParams * params)458 schro_params_set_default_quant_matrix (SchroParams * params)
459 {
460 int i;
461 const int *table;
462
463 table = schro_tables_lowdelay_quants[params->wavelet_filter_index]
464 [MAX (0, params->transform_depth - 1)];
465
466 params->quant_matrix[0] = table[0];
467 for (i = 0; i < params->transform_depth; i++) {
468 params->quant_matrix[1 + 3 * i + 0] = table[1 + 2 * i + 0];
469 params->quant_matrix[1 + 3 * i + 1] = table[1 + 2 * i + 0];
470 params->quant_matrix[1 + 3 * i + 2] = table[1 + 2 * i + 1];
471 }
472 }
473
474 schro_bool
schro_params_is_default_quant_matrix(SchroParams * params)475 schro_params_is_default_quant_matrix (SchroParams * params)
476 {
477 int i;
478 const int *table;
479
480 if (params->transform_depth < 1 || params->transform_depth > 4)
481 return FALSE;
482
483 table = schro_tables_lowdelay_quants[params->wavelet_filter_index]
484 [params->transform_depth - 1];
485
486 if (params->quant_matrix[0] != table[0])
487 return FALSE;
488 for (i = 0; i < params->transform_depth; i++) {
489 if (params->quant_matrix[1 + 3 * i + 0] != table[1 + 2 * i + 0] ||
490 params->quant_matrix[1 + 3 * i + 1] != table[1 + 2 * i + 0] ||
491 params->quant_matrix[1 + 3 * i + 2] != table[1 + 2 * i + 1]) {
492 return FALSE;
493 }
494 }
495 return TRUE;
496 }
497