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