1 
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 #include <schroedinger/schro.h>
6 #include <schroedinger/schrophasecorrelation.h>
7 #include <string.h>
8 #include <math.h>
9 
10 #define DC_BIAS 50
11 #define DC_METRIC 50
12 #define BIDIR_LIMIT (10*8*8)
13 
14 #define SCHRO_METRIC_INVALID_2 0x7fffffff
15 
16 #define motion_field_get(mf,x,y) \
17   ((mf)->motion_vectors + (y)*(mf)->x_num_blocks + (x))
18 
19 void schro_encoder_bigblock_estimation (SchroMotionEst * me);
20 static SchroFrame *get_downsampled (SchroEncoderFrame * frame, int i);
21 
22 
23 SchroMotionEst *
schro_motionest_new(SchroEncoderFrame * frame)24 schro_motionest_new (SchroEncoderFrame * frame)
25 {
26   SchroMotionEst *me;
27 
28   me = schro_malloc0 (sizeof (SchroMotionEst));
29 
30   me->encoder_frame = frame;
31   me->params = &frame->params;
32 
33   me->downsampled_src0[0] = frame->ref_frame[0]->filtered_frame;
34   me->downsampled_src0[1] = frame->ref_frame[0]->downsampled_frames[0];
35   me->downsampled_src0[2] = frame->ref_frame[0]->downsampled_frames[1];
36   me->downsampled_src0[3] = frame->ref_frame[0]->downsampled_frames[2];
37   me->downsampled_src0[4] = frame->ref_frame[0]->downsampled_frames[3];
38 
39   if (me->params->num_refs > 1) {
40     me->downsampled_src1[0] = frame->ref_frame[1]->filtered_frame;
41     me->downsampled_src1[1] = frame->ref_frame[1]->downsampled_frames[0];
42     me->downsampled_src1[2] = frame->ref_frame[1]->downsampled_frames[1];
43     me->downsampled_src1[3] = frame->ref_frame[1]->downsampled_frames[2];
44     me->downsampled_src1[4] = frame->ref_frame[1]->downsampled_frames[3];
45   }
46 
47   me->scan_distance = frame->encoder->magic_scan_distance;
48 
49   return me;
50 }
51 
52 void
schro_motionest_free(SchroMotionEst * me)53 schro_motionest_free (SchroMotionEst * me)
54 {
55   schro_free (me);
56 }
57 
58 
59 void
schro_encoder_motion_predict_rough(SchroEncoderFrame * frame)60 schro_encoder_motion_predict_rough (SchroEncoderFrame * frame)
61 {
62   SchroParams *params = &frame->params;
63   SchroEncoder *encoder = frame->encoder;
64   int ref;
65 
66   SCHRO_ASSERT (params->x_num_blocks != 0);
67   SCHRO_ASSERT (params->y_num_blocks != 0);
68   SCHRO_ASSERT (params->num_refs > 0);
69 
70   if (encoder->enable_hierarchical_estimation) {
71     for (ref = 0; ref < params->num_refs; ref++) {
72       if (encoder->enable_bigblock_estimation) {
73         frame->rme[ref] = schro_rough_me_new (frame, frame->ref_frame[ref]);
74         schro_rough_me_heirarchical_scan (frame->rme[ref]);
75       } else if (encoder->enable_deep_estimation) {
76         frame->hier_bm[ref] = schro_hbm_new (frame, ref);
77         schro_hbm_scan (frame->hier_bm[ref]);
78       }
79 
80       if (encoder->enable_phasecorr_estimation) {
81         frame->phasecorr[ref] = schro_phasecorr_new (frame,
82             frame->ref_frame[ref]);
83         schro_encoder_phasecorr_estimation (frame->phasecorr[ref]);
84       }
85     }
86     if (encoder->enable_global_motion) {
87       schro_encoder_global_estimation (frame);
88     }
89   }
90 
91   if (encoder->enable_bigblock_estimation) {
92     frame->me = schro_motionest_new (frame);
93   } else if (encoder->enable_deep_estimation) {
94     frame->deep_me = schro_me_new (frame);
95   }
96 
97   frame->motion = schro_motion_new (params, NULL, NULL);
98   if (encoder->enable_bigblock_estimation) {
99     frame->me->motion = frame->motion;
100   }
101 
102 }
103 
104 void
schro_encoder_motion_predict_pel(SchroEncoderFrame * frame)105 schro_encoder_motion_predict_pel (SchroEncoderFrame * frame)
106 {
107   SchroParams *params = &frame->params;
108   int ref;
109 
110   SCHRO_ASSERT (params->x_num_blocks != 0);
111   SCHRO_ASSERT (params->y_num_blocks != 0);
112   SCHRO_ASSERT (params->num_refs > 0);
113 
114   if (frame->encoder->enable_bigblock_estimation) {
115     schro_encoder_bigblock_estimation (frame->me);
116 
117     schro_motion_calculate_stats (frame->motion, frame);
118     frame->estimated_mc_bits = schro_motion_estimate_entropy (frame->motion);
119 
120     frame->badblock_ratio =
121         (double) frame->me->badblocks / (params->x_num_blocks *
122         params->y_num_blocks / 16);
123   } else if (frame->encoder->enable_deep_estimation) {
124     for (ref = 0; params->num_refs > ref; ++ref) {
125       SCHRO_ASSERT (frame->hier_bm[ref]);
126       schro_hierarchical_bm_scan_hint (frame->hier_bm[ref], 0, 3);
127     }
128   } else
129     SCHRO_ASSERT (0);
130 }
131 
132 static void
schro_encoder_motion_refine_block_subpel(SchroEncoderFrame * frame,SchroBlock * block,int i,int j)133 schro_encoder_motion_refine_block_subpel (SchroEncoderFrame * frame,
134     SchroBlock * block, int i, int j)
135 {
136   SchroParams *params = &frame->params;
137   int skip;
138   int ii, jj;
139 
140   skip = 4 >> block->mv[0][0].split;
141   for (jj = 0; jj < 4; jj += skip) {
142     for (ii = 0; ii < 4; ii += skip) {
143       if (block->mv[jj][ii].pred_mode & 1) {
144         block->mv[jj][ii].u.vec.dx[0] <<= params->mv_precision;
145         block->mv[jj][ii].u.vec.dy[0] <<= params->mv_precision;
146       }
147       if (block->mv[jj][ii].pred_mode & 2) {
148         block->mv[jj][ii].u.vec.dx[1] <<= params->mv_precision;
149         block->mv[jj][ii].u.vec.dy[1] <<= params->mv_precision;
150       }
151     }
152   }
153 
154   if (block->mv[0][0].split < 3) {
155     for (jj = 0; jj < 4; jj += skip) {
156       for (ii = 0; ii < 4; ii += skip) {
157         if (SCHRO_METRIC_INVALID == block->mv[jj][ii].metric) {
158           continue;
159         }
160         if (block->mv[jj][ii].pred_mode == 1
161             || block->mv[jj][ii].pred_mode == 2) {
162           SchroUpsampledFrame *ref_upframe;
163           SchroFrameData orig;
164           SchroFrameData ref_fd;
165           int dx, dy;
166           int x, y;
167           int metric = SCHRO_METRIC_INVALID_2;
168           int width, height;
169           int min_metric;
170           int min_dx, min_dy;
171           int ref;
172 
173           ref = block->mv[jj][ii].pred_mode - 1;
174           ref_upframe = frame->ref_frame[ref]->upsampled_original_frame;
175 
176           x = MAX ((i + ii) * frame->params.xbsep_luma, 0);
177           y = MAX ((j + jj) * frame->params.ybsep_luma, 0);
178 
179           schro_frame_get_subdata (get_downsampled (frame, 0), &orig, 0, x, y);
180 
181           width = MIN (skip * frame->params.xbsep_luma, orig.width);
182           height = MIN (skip * frame->params.ybsep_luma, orig.height);
183 
184 
185           min_metric = 0x7fffffff;
186           min_dx = 0;
187           min_dy = 0;
188           for (dx = -1; dx <= 1; dx++) {
189             for (dy = -1; dy <= 1; dy++) {
190               schro_upsampled_frame_get_subdata_prec1 (ref_upframe, 0,
191                   2 * x + block->mv[jj][ii].u.vec.dx[ref] + dx,
192                   2 * y + block->mv[jj][ii].u.vec.dy[ref] + dy, &ref_fd);
193 
194               metric = schro_metric_get (&orig, &ref_fd, width, height);
195               if (metric < min_metric) {
196                 min_dx = dx;
197                 min_dy = dy;
198                 min_metric = metric;
199               }
200             }
201           }
202           if (SCHRO_METRIC_INVALID > min_metric) {
203             block->mv[ii][ii].u.vec.dx[ref] += min_dx;
204             block->mv[jj][ii].u.vec.dy[ref] += min_dy;
205             block->mv[jj][ii].metric = min_metric;
206           }
207         }
208       }
209     }
210   }
211 
212 }
213 
214 void
schro_encoder_motion_predict_subpel(SchroEncoderFrame * frame)215 schro_encoder_motion_predict_subpel (SchroEncoderFrame * frame)
216 {
217   SchroParams *params = &frame->params;
218   int i;
219   int j;
220 
221   SCHRO_ASSERT (frame->upsampled_original_frame);
222   SCHRO_ASSERT (frame->ref_frame[0]->upsampled_original_frame);
223   if (frame->ref_frame[1]) {
224     SCHRO_ASSERT (frame->ref_frame[1]->upsampled_original_frame);
225   }
226 
227   for (j = 0; j < params->y_num_blocks; j += 4) {
228     for (i = 0; i < params->x_num_blocks; i += 4) {
229       SchroBlock block = { 0 };
230 
231       schro_motion_copy_from (frame->me->motion, i, j, &block);
232       schro_encoder_motion_refine_block_subpel (frame, &block, i, j);
233       schro_block_fixup (&block);
234       schro_motion_copy_to (frame->me->motion, i, j, &block);
235     }
236   }
237 }
238 
239 typedef struct
240 {
241   int dx;
242   int dy;
243 } MatchPos;
244 
245 
246 void
schro_encoder_motion_predict_subpel_deep(SchroMe * me)247 schro_encoder_motion_predict_subpel_deep (SchroMe * me)
248 {
249   SchroParams *params = schro_me_params (me);
250   double lambda = schro_me_lambda (me);
251   int mvprec = 0, ref;
252   int xblen = params->xbsep_luma, yblen = params->ybsep_luma;
253   int i, j;
254   int x_min, x_max, y_min, y_max;
255   SchroMotionField *mf = NULL;
256   SchroMotionVector *mv;
257   SchroFrameData fd;
258   SchroFrame *orig_frame = schro_me_src (me);
259   const MatchPos sp_matches[] = { {-1, -1}, {0, -1}, {1, -1}
260   , {-1, 0}, {1, 0}
261   , {-1, 1}, {0, 1}, {1, 1}
262   };
263 
264 
265   x_min = y_min = -orig_frame->extension;
266 
267   if (1 < params->mv_precision) {
268     fd.data = schro_malloc (xblen * yblen * sizeof (uint8_t));
269     fd.stride = xblen;
270     fd.height = yblen;
271     fd.width = xblen;
272     fd.format = SCHRO_FRAME_FORMAT_U8_420;
273 
274   }
275 
276   while (!(params->mv_precision < ++mvprec)) {
277     x_max = (orig_frame->width << mvprec) + orig_frame->extension;
278     y_max = (orig_frame->height << mvprec) + orig_frame->extension;
279     for (ref = 0; ref < params->num_refs; ++ref) {
280       SchroUpsampledFrame *upframe = schro_me_ref (me, ref);
281       mf = schro_me_subpel_mf (me, ref);
282       for (j = 0; params->y_num_blocks > j; ++j) {
283         for (i = 0; params->x_num_blocks > i; ++i) {
284           int error, entropy, min_error = INT_MAX, m = -1;
285           double score, min_score = HUGE_VAL;
286           int x, y, k;
287           int dx, dy;
288           int pred_x, pred_y;
289           SchroFrameData orig, ref_data;
290           int width, height;
291 
292           mv = &mf->motion_vectors[j * params->x_num_blocks + i];
293 
294           /* fetch source data (only process valid MVs) */
295           if (!schro_frame_get_data (orig_frame, &orig, 0, i * xblen,
296                   j * yblen)) {
297             continue;
298           }
299           width = MIN (xblen, orig.width);
300           height = MIN (yblen, orig.height);
301           /* adjust MV precision */
302           mv->u.vec.dx[ref] <<= 1;
303           mv->u.vec.dy[ref] <<= 1;
304 
305           /* calculate score for current MV */
306           schro_mf_vector_prediction (mf, i, j, &pred_x, &pred_y, ref + 1);
307           entropy = schro_pack_estimate_sint (mv->u.vec.dx[ref] - pred_x);
308           entropy += schro_pack_estimate_sint (mv->u.vec.dy[ref] - pred_y);
309           min_score = entropy + lambda * mv->metric;
310           x = i * (xblen << mvprec) + mv->u.vec.dx[ref];
311           y = j * (yblen << mvprec) + mv->u.vec.dy[ref];
312           /* check what matches are valid */
313           for (k = 0; sizeof (sp_matches) / sizeof (sp_matches[0]) > k; ++k) {
314             dx = x + sp_matches[k].dx;
315             dy = y + sp_matches[k].dy;
316             if (!(x_min < dx) || !(x_max > dx + xblen - 1)
317                 || !(y_min < dy) || !(y_max > dy + yblen - 1)) {
318               continue;
319             }
320             fd.width = width;
321             fd.height = height;
322             schro_upsampled_frame_get_block_fast_precN (upframe, 0, dx, dy,
323                 mvprec, &ref_data, &fd);
324             error =
325                 schro_metric_absdiff_u8 (orig.data, orig.stride, ref_data.data,
326                 ref_data.stride, width, height);
327             /* calculate score */
328             entropy =
329                 schro_pack_estimate_sint (mv->u.vec.dx[ref] + sp_matches[k].dx -
330                 pred_x);
331             entropy +=
332                 schro_pack_estimate_sint (mv->u.vec.dy[ref] + sp_matches[k].dy -
333                 pred_y);
334             score = entropy + lambda * error;
335             if (min_score > score) {
336               min_score = score;
337               min_error = error;
338               m = k;
339             }
340           }
341           if (-1 != m) {
342             mv->u.vec.dx[ref] += sp_matches[m].dx;
343             mv->u.vec.dy[ref] += sp_matches[m].dy;
344             mv->metric = min_error;
345           }
346         }
347       }
348 
349     }
350   }
351   if (1 < params->mv_precision) {
352     schro_free (fd.data);
353   }
354 }
355 
356 void
schro_motion_calculate_stats(SchroMotion * motion,SchroEncoderFrame * frame)357 schro_motion_calculate_stats (SchroMotion * motion, SchroEncoderFrame * frame)
358 {
359   int i, j;
360   SchroMotionVector *mv;
361   int ref1 = 0;
362   int ref2 = 0;
363   int bidir = 0;
364 
365   frame->stats_dc = 0;
366   frame->stats_global = 0;
367   frame->stats_motion = 0;
368   for (j = 0; j < motion->params->y_num_blocks; j++) {
369     for (i = 0; i < motion->params->x_num_blocks; i++) {
370       mv = SCHRO_MOTION_GET_BLOCK (motion, i, j);
371       if (mv->pred_mode == 0) {
372         frame->stats_dc++;
373       } else {
374         if (mv->using_global) {
375           frame->stats_global++;
376         } else {
377           frame->stats_motion++;
378         }
379         if (mv->pred_mode == 1) {
380           ref1++;
381         } else if (mv->pred_mode == 2) {
382           ref2++;
383         } else {
384           bidir++;
385         }
386       }
387     }
388   }
389   SCHRO_DEBUG ("dc %d global %d motion %d ref1 %d ref2 %d bidir %d",
390       frame->stats_dc, frame->stats_global, frame->stats_motion,
391       ref1, ref2, bidir);
392 }
393 
394 
395 SchroMotionField *
schro_motion_field_new(int x_num_blocks,int y_num_blocks)396 schro_motion_field_new (int x_num_blocks, int y_num_blocks)
397 {
398   SchroMotionField *mf;
399 
400   mf = schro_malloc0 (sizeof (SchroMotionField));
401   mf->x_num_blocks = x_num_blocks;
402   mf->y_num_blocks = y_num_blocks;
403   mf->motion_vectors = schro_malloc0 (sizeof (SchroMotionVector) *
404       x_num_blocks * y_num_blocks);
405 
406   return mf;
407 }
408 
409 void
schro_motion_field_free(SchroMotionField * field)410 schro_motion_field_free (SchroMotionField * field)
411 {
412   schro_free (field->motion_vectors);
413   schro_free (field);
414 }
415 
416 void
schro_motion_field_set(SchroMotionField * field,int split,int pred_mode)417 schro_motion_field_set (SchroMotionField * field, int split, int pred_mode)
418 {
419   SchroMotionVector *mv;
420   int i;
421   int j;
422 
423   for (j = 0; j < field->y_num_blocks; j++) {
424     for (i = 0; i < field->x_num_blocks; i++) {
425       mv = field->motion_vectors + j * field->x_num_blocks + i;
426       memset (mv, 0, sizeof (*mv));
427       mv->split = split;
428       mv->pred_mode = pred_mode;
429       mv->metric = 0;
430     }
431   }
432 }
433 
434 void
schro_motion_field_copy(SchroMotionField * field,SchroMotionField * parent)435 schro_motion_field_copy (SchroMotionField * field, SchroMotionField * parent)
436 {
437   SchroMotionVector *mv;
438   SchroMotionVector *pv;
439   int i;
440   int j;
441 
442   for (j = 0; j < field->y_num_blocks; j++) {
443     for (i = 0; i < field->x_num_blocks; i++) {
444       mv = field->motion_vectors + j * field->x_num_blocks + i;
445       pv = parent->motion_vectors + (j >> 1) * parent->x_num_blocks + (i >> 1);
446       *mv = *pv;
447     }
448   }
449 }
450 
451 #if 0
452 void
453 schro_motion_field_dump (SchroMotionField * field)
454 {
455   SchroMotionVector *mv;
456   int i;
457   int j;
458 
459   for (j = 0; j < field->y_num_blocks; j++) {
460     for (i = 0; i < field->x_num_blocks; i++) {
461       mv = field->motion_vectors + j * field->x_num_blocks + i;
462       printf ("%d %d %d %d\n", i, j, mv->u.vec.dx[0], mv->u.vec.dy[0]);
463     }
464   }
465   exit (0);
466 }
467 #endif
468 
469 static SchroFrame *
get_downsampled(SchroEncoderFrame * frame,int i)470 get_downsampled (SchroEncoderFrame * frame, int i)
471 {
472   SCHRO_ASSERT (frame->have_downsampling);
473 
474   if (i == 0) {
475     return frame->filtered_frame;
476   }
477   return frame->downsampled_frames[i - 1];
478 }
479 
480 static int
schro_block_average(int16_t * dest,SchroFrameData * comp,int x,int y,int w,int h)481 schro_block_average (int16_t * dest, SchroFrameData * comp,
482     int x, int y, int w, int h)
483 {
484   int xmax = MIN (x + w, comp->width);
485   int ymax = MIN (y + h, comp->height);
486   int i, j;
487   int n = 0;
488   int sum = 0;
489   int ave;
490 
491   if (x >= comp->width || y >= comp->height)
492     return SCHRO_METRIC_INVALID_2;
493 
494   for (j = y; j < ymax; j++) {
495     for (i = x; i < xmax; i++) {
496       sum += SCHRO_GET (comp->data, j * comp->stride + i, uint8_t);
497     }
498     n += xmax - x;
499   }
500 
501   if (n == 0) {
502     return SCHRO_METRIC_INVALID_2;
503   }
504 
505   ave = (sum + n / 2) / n;
506 
507   sum = 0;
508   for (j = y; j < ymax; j++) {
509     for (i = x; i < xmax; i++) {
510       sum += abs (ave - SCHRO_GET (comp->data, j * comp->stride + i, uint8_t));
511     }
512   }
513 
514   *dest = ave - 128;
515   return sum;
516 }
517 
518 
519 static void
schro_motionest_superblock_scan_one(SchroMotionEst * me,int ref,int distance,SchroBlock * block,int i,int j)520 schro_motionest_superblock_scan_one (SchroMotionEst * me, int ref, int distance,
521     SchroBlock * block, int i, int j)
522 {
523   SchroParams *params = me->params;
524   SchroMotionVector *mv;
525   SchroMetricScan scan;
526   SchroMotionField *hint_mf;
527   SchroMotionVector *hint_mv;
528   int dx, dy;
529   uint32_t dummy;
530 
531   scan.frame = get_downsampled (me->encoder_frame, 0);
532   scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], 0);
533 
534   //hint_mf = me->downsampled_mf[ref][2];
535   hint_mf = me->encoder_frame->rme[ref]->motion_fields[2];
536 
537   scan.x = i * params->xbsep_luma;
538   scan.y = j * params->ybsep_luma;
539   scan.block_width = MIN (4 * params->xbsep_luma, scan.frame->width - scan.x);
540   scan.block_height = MIN (4 * params->ybsep_luma, scan.frame->height - scan.y);
541   scan.gravity_scale = 0;
542   scan.gravity_x = 0;
543   scan.gravity_y = 0;
544 
545   mv = &block->mv[0][0];
546   hint_mv = motion_field_get (hint_mf, i, j);
547 
548   dx = hint_mv->u.vec.dx[ref];
549   dy = hint_mv->u.vec.dy[ref];
550   scan.gravity_x = dx;
551   scan.gravity_y = dy;
552 
553   schro_metric_scan_setup (&scan, dx, dy, distance, FALSE);
554   if (scan.scan_width <= 0 || scan.scan_height <= 0) {
555     mv->u.vec.dx[ref] = 0;
556     mv->u.vec.dy[ref] = 0;
557     mv->metric = SCHRO_METRIC_INVALID;
558     block->valid = FALSE;
559     return;
560   }
561 
562   schro_metric_scan_do_scan (&scan);
563   block->error = schro_metric_scan_get_min (&scan, &dx, &dy, &dummy);
564   mv->metric = block->error / 16;
565 
566   mv->split = 0;
567   mv->pred_mode = 1 << ref;
568   mv->using_global = 0;
569   mv->u.vec.dx[ref] = dx;
570   mv->u.vec.dy[ref] = dy;
571 
572   schro_block_fixup (block);
573   block->entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
574       i, j, block);
575   block->valid = TRUE;
576 }
577 
578 static void
schro_motionest_superblock_predicted(SchroMotionEst * me,int ref,SchroBlock * block,int i,int j)579 schro_motionest_superblock_predicted (SchroMotionEst * me, int ref,
580     SchroBlock * block, int i, int j)
581 {
582   SchroMotionVector *mv;
583   int pred_x, pred_y;
584 
585   schro_motion_vector_prediction (me->motion, i, j, &pred_x, &pred_y,
586       (1 << ref));
587 
588   mv = &block->mv[0][0];
589   mv->split = 0;
590   mv->pred_mode = 1 << ref;
591   mv->using_global = 0;
592   mv->u.vec.dx[ref] = pred_x;
593   mv->u.vec.dy[ref] = pred_y;
594   block->error = schro_motionest_superblock_get_metric (me, block, i, j);
595   block->entropy = 0;
596   schro_block_fixup (block);
597 
598   block->valid = (block->error != SCHRO_METRIC_INVALID_2);
599 }
600 
601 static void
schro_motionest_superblock_biref_zero(SchroMotionEst * me,SchroBlock * block,int i,int j)602 schro_motionest_superblock_biref_zero (SchroMotionEst * me,
603     SchroBlock * block, int i, int j)
604 {
605   SchroMotionVector *mv;
606 
607   mv = &block->mv[0][0];
608   mv->split = 0;
609   mv->pred_mode = 3;
610   mv->using_global = 0;
611   mv->u.vec.dx[0] = 0;
612   mv->u.vec.dy[0] = 0;
613   mv->u.vec.dx[1] = 0;
614   mv->u.vec.dy[1] = 0;
615   block->error = schro_motionest_superblock_get_metric (me, block, i, j);
616   schro_block_fixup (block);
617   block->entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
618       i, j, block);
619   block->valid = (block->error != SCHRO_METRIC_INVALID_2);
620 }
621 
622 static void
schro_motionest_superblock_dc(SchroMotionEst * me,SchroBlock * block,int i,int j)623 schro_motionest_superblock_dc (SchroMotionEst * me,
624     SchroBlock * block, int i, int j)
625 {
626   SchroParams *params = me->params;
627   SchroMotionVector *mv;
628   int chroma_w, chroma_h;
629   SchroFrame *frame;
630   int metric;
631 
632   frame = get_downsampled (me->encoder_frame, 0);
633 
634   mv = &block->mv[0][0];
635   mv->split = 0;
636   mv->pred_mode = 0;
637 
638   metric = schro_block_average (&mv->u.dc.dc[0], frame->components + 0,
639       i * params->xbsep_luma, j * params->ybsep_luma,
640       4 * params->xbsep_luma, 4 * params->ybsep_luma);
641   if (metric == SCHRO_METRIC_INVALID_2) {
642     block->valid = FALSE;
643     return;
644   }
645   chroma_w =
646       params->xbsep_luma >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
647       video_format->chroma_format);
648   chroma_h =
649       params->ybsep_luma >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
650       video_format->chroma_format);
651   schro_block_average (&mv->u.dc.dc[1], frame->components + 1, i * chroma_w,
652       j * chroma_h, 4 * chroma_w, 4 * chroma_h);
653   schro_block_average (&mv->u.dc.dc[2], frame->components + 2, i * chroma_w,
654       j * chroma_h, 4 * chroma_w, 4 * chroma_h);
655 
656   mv->metric = metric;
657   block->error = metric;
658   block->error += 4 * 2 * me->params->xbsep_luma *
659       me->encoder_frame->encoder->magic_dc_metric_offset;
660 
661   schro_block_fixup (block);
662 
663   block->entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
664       i, j, block);
665   block->valid = TRUE;
666 }
667 
668 static void
schro_motionest_superblock_dc_predicted(SchroMotionEst * me,SchroBlock * block,int i,int j)669 schro_motionest_superblock_dc_predicted (SchroMotionEst * me,
670     SchroBlock * block, int i, int j)
671 {
672   SchroMotionVector *mv;
673   int pred[3];
674 
675   schro_motion_dc_prediction (me->motion, i, j, pred);
676 
677   mv = &block->mv[0][0];
678   mv->split = 0;
679   mv->pred_mode = 0;
680   mv->u.dc.dc[0] = pred[0];
681   mv->u.dc.dc[1] = pred[1];
682   mv->u.dc.dc[2] = pred[2];
683 
684   block->error = schro_motionest_superblock_get_metric (me, block, i, j);
685   mv->metric = block->error;
686   block->error += 4 * 2 * me->params->xbsep_luma *
687       me->encoder_frame->encoder->magic_dc_metric_offset;
688 
689   schro_block_fixup (block);
690   block->entropy = 0;
691   block->valid = TRUE;
692 }
693 
694 #ifdef unused
695 static void
schro_motion_splat_4x4(SchroMotion * motion,int i,int j)696 schro_motion_splat_4x4 (SchroMotion * motion, int i, int j)
697 {
698   SchroMotionVector *mv;
699 
700   mv = SCHRO_MOTION_GET_BLOCK (motion, i, j);
701   mv[1] = mv[0];
702   mv[2] = mv[0];
703   mv[3] = mv[0];
704   memcpy (SCHRO_MOTION_GET_BLOCK (motion, i, j + 1), mv, 4 * sizeof (*mv));
705   memcpy (SCHRO_MOTION_GET_BLOCK (motion, i, j + 2), mv, 4 * sizeof (*mv));
706   memcpy (SCHRO_MOTION_GET_BLOCK (motion, i, j + 3), mv, 4 * sizeof (*mv));
707 }
708 #endif
709 
710 #ifdef unused
711 static void
motion_field_splat_4x4(SchroMotionField * mf,int i,int j)712 motion_field_splat_4x4 (SchroMotionField * mf, int i, int j)
713 {
714   SchroMotionVector *mv;
715 
716   mv = motion_field_get (mf, i, j);
717   mv[1] = mv[0];
718   mv[2] = mv[0];
719   mv[3] = mv[0];
720   memcpy (motion_field_get (mf, i, j + 1), mv, 4 * sizeof (*mv));
721   memcpy (motion_field_get (mf, i, j + 2), mv, 4 * sizeof (*mv));
722   memcpy (motion_field_get (mf, i, j + 3), mv, 4 * sizeof (*mv));
723 }
724 #endif
725 
726 #ifdef unused
727 static void
schro_motionest_block_scan_one(SchroMotionEst * me,int ref,int distance,SchroBlock * block,int i,int j)728 schro_motionest_block_scan_one (SchroMotionEst * me, int ref, int distance,
729     SchroBlock * block, int i, int j)
730 {
731   SchroParams *params = me->params;
732   SchroMotionVector *mv;
733   SchroMetricScan scan;
734   SchroMotionField *hint_mf;
735   SchroMotionVector *hint_mv;
736   int dx, dy;
737   int ii, jj;
738 
739   scan.frame = get_downsampled (me->encoder_frame, 0);
740   scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], 0);
741 
742   hint_mf = me->encoder_frame->rme[ref]->motion_fields[1];
743 
744   scan.block_width = params->xbsep_luma;
745   scan.block_height = params->ybsep_luma;
746   scan.gravity_scale = 0;
747   scan.gravity_x = 0;
748   scan.gravity_y = 0;
749 
750   block->error = 0;
751   block->valid = TRUE;
752   for (jj = 0; jj < 4; jj++) {
753     for (ii = 0; ii < 4; ii++) {
754       mv = &block->mv[jj][ii];
755       hint_mv = motion_field_get (hint_mf, i + (ii & 2), j + (jj & 2));
756 
757       dx = hint_mv->u.vec.dx[ref];
758       dy = hint_mv->u.vec.dy[ref];
759       scan.gravity_x = dx;
760       scan.gravity_y = dy;
761 
762       scan.x = (i + ii) * params->xbsep_luma;
763       scan.y = (j + jj) * params->ybsep_luma;
764       schro_metric_scan_setup (&scan, dx, dy, distance, FALSE);
765       if (scan.scan_width <= 0 || scan.scan_height <= 0) {
766         mv->u.vec.dx[ref] = 0;
767         mv->u.vec.dy[ref] = 0;
768         mv->metric = SCHRO_METRIC_INVALID;
769         block->error += mv->metric;
770         block->valid = FALSE;
771         continue;
772       }
773 
774       schro_metric_scan_do_scan (&scan);
775       uint32_t dummy;
776       mv->metric = schro_metric_scan_get_min (&scan, &dx, &dy, &dummy);
777       block->error += mv->metric;
778       block->valid &= (mv->metric != SCHRO_METRIC_INVALID);
779 
780       mv->split = 2;
781       mv->pred_mode = 1 << ref;
782       mv->using_global = 0;
783       mv->u.vec.dx[ref] = dx;
784       mv->u.vec.dy[ref] = dy;
785     }
786   }
787 
788   schro_block_fixup (block);
789   block->entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
790       i, j, block);
791 }
792 #endif
793 
794 
795 #define MAGIC_SUPERBLOCK_METRIC 5
796 #define MAGIC_BLOCK_METRIC 50
797 
798 #define TRYBLOCK \
799       score = tryblock.entropy + me->lambda * tryblock.error; \
800       if (tryblock.valid && score < min_score) { \
801         memcpy (&block, &tryblock, sizeof(block)); \
802         min_score = score; \
803       }
804 
805 static void
schro_motionest_block_scan(SchroMotionEst * me,int ref,int distance,SchroBlock * block,int i,int j,int ii,int jj)806 schro_motionest_block_scan (SchroMotionEst * me, int ref, int distance,
807     SchroBlock * block, int i, int j, int ii, int jj)
808 {
809   SchroParams *params = me->params;
810   SchroMotionVector *mv;
811   SchroMetricScan scan;
812   SchroMotionField *hint_mf;
813   SchroMotionVector *hint_mv;
814   int dx, dy;
815   uint32_t dummy;
816 
817   scan.frame = get_downsampled (me->encoder_frame, 0);
818   scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], 0);
819 
820   hint_mf = me->encoder_frame->rme[ref]->motion_fields[1];
821 
822   scan.block_width = params->xbsep_luma;
823   scan.block_height = params->ybsep_luma;
824 
825   scan.gravity_scale = 0;
826   scan.gravity_x = 0;
827   scan.gravity_y = 0;
828 
829   mv = &block->mv[jj][ii];
830   hint_mv = motion_field_get (hint_mf, i + (ii & 2), j + (jj & 2));
831 
832   dx = hint_mv->u.vec.dx[ref];
833   dy = hint_mv->u.vec.dy[ref];
834   scan.gravity_x = dx;
835   scan.gravity_y = dy;
836 
837   scan.x = (i + ii) * params->xbsep_luma;
838   scan.y = (j + jj) * params->ybsep_luma;
839   if (!(scan.x < scan.frame->width) || !(scan.y < scan.frame->height)) {
840     mv->u.vec.dx[ref] = 0;
841     mv->u.vec.dy[ref] = 0;
842     mv->metric = SCHRO_METRIC_INVALID;
843     block->error += mv->metric;
844     block->valid = FALSE;
845     return;
846   }
847   scan.block_width = MIN (params->xbsep_luma, scan.frame->width - scan.x);
848   scan.block_height = MIN (params->ybsep_luma, scan.frame->height - scan.y);
849   schro_metric_scan_setup (&scan, dx, dy, distance, FALSE);
850   if (scan.scan_width <= 0 || scan.scan_height <= 0) {
851     mv->u.vec.dx[ref] = 0;
852     mv->u.vec.dy[ref] = 0;
853     mv->metric = SCHRO_METRIC_INVALID;
854     block->error += mv->metric;
855     block->valid = FALSE;
856     return;
857   }
858 
859   schro_metric_scan_do_scan (&scan);
860   mv->metric = schro_metric_scan_get_min (&scan, &dx, &dy, &dummy);
861   block->error = mv->metric;
862   block->valid = (mv->metric != SCHRO_METRIC_INVALID);
863 
864   mv->split = 2;
865   mv->pred_mode = 1 << ref;
866   mv->using_global = 0;
867   mv->u.vec.dx[ref] = dx;
868   mv->u.vec.dy[ref] = dy;
869 
870   schro_block_fixup (block);
871 
872   mv = SCHRO_MOTION_GET_BLOCK (me->motion, i + ii, j + jj);
873   *mv = block->mv[jj][ii];
874   block->entropy = schro_motion_block_estimate_entropy (me->motion,
875       i + ii, j + jj);
876 }
877 
878 static void
schro_motionest_block_dc(SchroMotionEst * me,SchroBlock * block,int i,int j,int ii,int jj)879 schro_motionest_block_dc (SchroMotionEst * me,
880     SchroBlock * block, int i, int j, int ii, int jj)
881 {
882   SchroParams *params = me->params;
883   SchroMotionVector *mv;
884   int chroma_w, chroma_h;
885   SchroFrame *frame;
886   int metric;
887 
888   frame = get_downsampled (me->encoder_frame, 0);
889 
890   mv = &(block->mv[jj][ii]);
891   mv->split = 2;
892   mv->pred_mode = 0;
893 
894   metric = schro_block_average (&mv->u.dc.dc[0], frame->components + 0,
895       (i + ii) * params->xbsep_luma, (j + jj) * params->ybsep_luma,
896       params->xbsep_luma, params->ybsep_luma);
897   if (metric == SCHRO_METRIC_INVALID_2) {
898     block->valid = FALSE;
899     return;
900   }
901   chroma_w =
902       params->xbsep_luma >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
903       video_format->chroma_format);
904   chroma_h =
905       params->ybsep_luma >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
906       video_format->chroma_format);
907   schro_block_average (&mv->u.dc.dc[1], frame->components + 1,
908       (i + ii) * chroma_w, (j + jj) * chroma_h, chroma_w, chroma_h);
909   schro_block_average (&mv->u.dc.dc[2], frame->components + 2,
910       (i + ii) * chroma_w, (j + jj) * chroma_h, chroma_w, chroma_h);
911 
912   mv->metric = metric;
913   block->error = metric;
914   block->error += 4 * 2 * me->params->xbsep_luma *
915       me->encoder_frame->encoder->magic_dc_metric_offset;
916 
917   block->entropy = schro_motion_block_estimate_entropy (me->motion,
918       i + ii, j + jj);
919   block->valid = TRUE;
920 }
921 
922 static void
schro_motionest_superblock_block(SchroMotionEst * me,SchroBlock * p_block,int i,int j)923 schro_motionest_superblock_block (SchroMotionEst * me,
924     SchroBlock * p_block, int i, int j)
925 {
926   SchroParams *params = me->params;
927   int ii, jj;
928   SchroBlock block = { 0 };
929   int total_error = 0;
930 
931   for (jj = 0; jj < 4; jj++) {
932     for (ii = 0; ii < 4; ii++) {
933       block.mv[jj][ii].split = 2;
934       block.mv[jj][ii].pred_mode = 1;
935       block.mv[jj][ii].u.vec.dx[0] = 0;
936       block.mv[jj][ii].u.vec.dy[0] = 0;
937     }
938   }
939   schro_motion_copy_to (me->motion, i, j, &block);
940 
941   for (jj = 0; jj < 4; jj++) {
942     for (ii = 0; ii < 4; ii++) {
943       SchroBlock tryblock = { 0 };
944       double score;
945       double min_score;
946 
947       /* FIXME use better default than DC */
948       schro_motionest_block_dc (me, &tryblock, i, j, ii, jj);
949       min_score = block.entropy + me->lambda * block.error;
950 
951       if (me->encoder_frame->encoder->enable_hierarchical_estimation) {
952         memcpy (&tryblock, &block, sizeof (block));
953         schro_motionest_block_scan (me, 0, me->scan_distance, &block, i, j, ii,
954             jj);
955         min_score = block.entropy + me->lambda * block.error;
956 
957         if (params->num_refs > 1) {
958           memcpy (&tryblock, &block, sizeof (block));
959           schro_motionest_block_scan (me, 1, me->scan_distance, &tryblock, i, j,
960               ii, jj);
961         TRYBLOCK}
962       }
963 
964       memcpy (&tryblock, &block, sizeof (block));
965       schro_motionest_block_dc (me, &tryblock, i, j, ii, jj);
966       TRYBLOCK total_error += block.error;
967     }
968   }
969   block.entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
970       i, j, &block);
971   block.error = total_error;
972 
973   memcpy (p_block, &block, sizeof (block));
974 }
975 
976 static void
schro_motionest_subsuperblock_scan(SchroMotionEst * me,int ref,int distance,SchroBlock * block,int i,int j,int ii,int jj)977 schro_motionest_subsuperblock_scan (SchroMotionEst * me, int ref, int distance,
978     SchroBlock * block, int i, int j, int ii, int jj)
979 {
980   SchroParams *params = me->params;
981   SchroMotionVector *mv;
982   SchroMetricScan scan;
983   SchroMotionField *hint_mf;
984   SchroMotionVector *hint_mv;
985   int dx, dy;
986   uint32_t dummy;
987 
988   scan.frame = get_downsampled (me->encoder_frame, 0);
989   scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], 0);
990 
991   hint_mf = me->encoder_frame->rme[ref]->motion_fields[1];
992 
993   scan.block_width = 2 * params->xbsep_luma;
994   scan.block_height = 2 * params->ybsep_luma;
995 
996   scan.gravity_scale = 0;
997   scan.gravity_x = 0;
998   scan.gravity_y = 0;
999 
1000   mv = &block->mv[jj][ii];
1001   hint_mv = motion_field_get (hint_mf, i + (ii & 2), j + (jj & 2));
1002 
1003   dx = hint_mv->u.vec.dx[ref];
1004   dy = hint_mv->u.vec.dy[ref];
1005   scan.gravity_x = dx;
1006   scan.gravity_y = dy;
1007 
1008   scan.x = (i + ii) * params->xbsep_luma;
1009   scan.y = (j + jj) * params->ybsep_luma;
1010   if (!(scan.x < scan.frame->width) || !(scan.y < scan.frame->height)) {
1011     mv->u.vec.dx[ref] = mv->u.vec.dy[ref] = 0;
1012     mv->metric = SCHRO_METRIC_INVALID;
1013     block->error += mv->metric;
1014     block->valid = FALSE;
1015     return;
1016   }
1017   scan.block_width = MIN (2 * params->xbsep_luma, scan.frame->width - scan.x);
1018   scan.block_height = MIN (2 * params->ybsep_luma, scan.frame->height - scan.y);
1019   schro_metric_scan_setup (&scan, dx, dy, distance, FALSE);
1020   if (scan.scan_width <= 0 || scan.scan_height <= 0) {
1021     mv->u.vec.dx[ref] = 0;
1022     mv->u.vec.dy[ref] = 0;
1023     mv->metric = SCHRO_METRIC_INVALID;
1024     block->error += mv->metric;
1025     block->valid = FALSE;
1026     return;
1027   }
1028 
1029   schro_metric_scan_do_scan (&scan);
1030   mv->metric = schro_metric_scan_get_min (&scan, &dx, &dy, &dummy);
1031   block->error = mv->metric;
1032   block->valid = (mv->metric != SCHRO_METRIC_INVALID);
1033 
1034   mv->split = 1;
1035   mv->pred_mode = 1 << ref;
1036   mv->using_global = 0;
1037   mv->u.vec.dx[ref] = dx;
1038   mv->u.vec.dy[ref] = dy;
1039 
1040   schro_block_fixup (block);
1041 
1042   mv = SCHRO_MOTION_GET_BLOCK (me->motion, i + ii, j + jj);
1043   *mv = block->mv[jj][ii];
1044   block->entropy = schro_motion_block_estimate_entropy (me->motion,
1045       i + ii, j + jj);
1046 }
1047 
1048 static void
schro_motionest_subsuperblock_dc(SchroMotionEst * me,SchroBlock * block,int i,int j,int ii,int jj)1049 schro_motionest_subsuperblock_dc (SchroMotionEst * me,
1050     SchroBlock * block, int i, int j, int ii, int jj)
1051 {
1052   SchroParams *params = me->params;
1053   SchroMotionVector *mv;
1054   int chroma_w, chroma_h;
1055   SchroFrame *frame;
1056   int metric;
1057 
1058   frame = get_downsampled (me->encoder_frame, 0);
1059 
1060   mv = (SchroMotionVector *) & block->mv[jj][ii];
1061   mv->split = 1;
1062   mv->pred_mode = 0;
1063 
1064   metric = schro_block_average (&mv->u.dc.dc[0], frame->components + 0,
1065       (i + ii) * params->xbsep_luma, (j + jj) * params->ybsep_luma,
1066       2 * params->xbsep_luma, 2 * params->ybsep_luma);
1067   if (metric == SCHRO_METRIC_INVALID_2) {
1068     block->valid = FALSE;
1069     return;
1070   }
1071   chroma_w =
1072       params->xbsep_luma >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
1073       video_format->chroma_format);
1074   chroma_h =
1075       params->ybsep_luma >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
1076       video_format->chroma_format);
1077   schro_block_average (&mv->u.dc.dc[1], frame->components + 1,
1078       (i + ii) * chroma_w, (j + jj) * chroma_h, 2 * chroma_w, 2 * chroma_h);
1079   schro_block_average (&mv->u.dc.dc[2], frame->components + 2,
1080       (i + ii) * chroma_w, (j + jj) * chroma_h, 2 * chroma_w, 2 * chroma_h);
1081 
1082   mv->metric = metric;
1083   block->error = metric;
1084   block->error += 4 * 2 * me->params->xbsep_luma *
1085       me->encoder_frame->encoder->magic_dc_metric_offset;
1086 
1087   block->entropy = schro_motion_block_estimate_entropy (me->motion,
1088       i + ii, j + jj);
1089   block->valid = TRUE;
1090 }
1091 
1092 static void
schro_motionest_superblock_subsuperblock(SchroMotionEst * me,SchroBlock * p_block,int i,int j)1093 schro_motionest_superblock_subsuperblock (SchroMotionEst * me,
1094     SchroBlock * p_block, int i, int j)
1095 {
1096   SchroParams *params = me->params;
1097   int ii, jj;
1098   SchroBlock block = { 0 };
1099   int total_error = 0;
1100 
1101   for (jj = 0; jj < 4; jj++) {
1102     for (ii = 0; ii < 4; ii++) {
1103       block.mv[jj][ii].split = 1;
1104       block.mv[jj][ii].pred_mode = 1;
1105       block.mv[jj][ii].u.vec.dx[0] = 0;
1106       block.mv[jj][ii].u.vec.dy[0] = 0;
1107     }
1108   }
1109   schro_motion_copy_to (me->motion, i, j, &block);
1110 
1111   for (jj = 0; jj < 4; jj += 2) {
1112     for (ii = 0; ii < 4; ii += 2) {
1113       SchroBlock tryblock = { 0 };
1114       double score;
1115       double min_score;
1116 
1117       /* FIXME use better default than DC */
1118       schro_motionest_subsuperblock_dc (me, &block, i, j, ii, jj);
1119       min_score = block.entropy + me->lambda * block.error;
1120 
1121       if (me->encoder_frame->encoder->enable_hierarchical_estimation) {
1122         memcpy (&tryblock, &block, sizeof (block));
1123         schro_motionest_subsuperblock_scan (me, 0, me->scan_distance, &tryblock,
1124             i, j, ii, jj);
1125         TRYBLOCK if (params->num_refs > 1)
1126         {
1127           memcpy (&tryblock, &block, sizeof (block));
1128           schro_motionest_subsuperblock_scan (me, 1, me->scan_distance,
1129               &tryblock, i, j, ii, jj);
1130           TRYBLOCK
1131 #if 0
1132               memcpy (&tryblock, &block, sizeof (block));
1133           schro_motionest_block_biref_zero (me, 1, &tryblock, i, j, ii, jj);
1134           TRYBLOCK
1135 #endif
1136         }
1137       }
1138 
1139       memcpy (&tryblock, &block, sizeof (block));
1140       schro_motionest_subsuperblock_dc (me, &tryblock, i, j, ii, jj);
1141       TRYBLOCK total_error += block.error;
1142     }
1143   }
1144   block.entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
1145       i, j, &block);
1146   block.error = total_error;
1147 
1148   memcpy (p_block, &block, sizeof (block));
1149 }
1150 
1151 
1152 void
schro_encoder_bigblock_estimation(SchroMotionEst * me)1153 schro_encoder_bigblock_estimation (SchroMotionEst * me)
1154 {
1155   SchroParams *params = me->params;
1156   int i, j;
1157   double total_error = 0;
1158   int block_size;
1159   int block_threshold;
1160 
1161   me->lambda = me->encoder_frame->frame_me_lambda;
1162 
1163   block_size = 16 * params->xbsep_luma * params->ybsep_luma;
1164   block_threshold = params->xbsep_luma * params->ybsep_luma *
1165       me->encoder_frame->encoder->magic_block_search_threshold;
1166 
1167   for (j = 0; j < params->y_num_blocks; j += 4) {
1168     for (i = 0; i < params->x_num_blocks; i += 4) {
1169       SchroBlock block = { 0 };
1170       SchroBlock tryblock = { 0 };
1171       double score;
1172       double min_score;
1173 
1174       /* base 119 s */
1175       schro_motionest_superblock_predicted (me, 0, &block, i, j);
1176       min_score = block.entropy + me->lambda * block.error;
1177       if (params->num_refs > 1) {
1178         schro_motionest_superblock_predicted (me, 1, &tryblock, i, j);
1179       TRYBLOCK}
1180 
1181       if (me->encoder_frame->encoder->enable_hierarchical_estimation) {
1182         /* 16 s */
1183         schro_motionest_superblock_scan_one (me, 0, me->scan_distance,
1184             &tryblock, i, j);
1185         TRYBLOCK if (params->num_refs > 1)
1186         {
1187           schro_motionest_superblock_scan_one (me, 1, me->scan_distance,
1188               &tryblock, i, j);
1189         TRYBLOCK}
1190       }
1191 
1192       /* 2.5 s */
1193       schro_motionest_superblock_dc_predicted (me, &tryblock, i, j);
1194       TRYBLOCK schro_motionest_superblock_dc (me, &tryblock, i, j);
1195       TRYBLOCK
1196           /* 3.0 s */
1197           if (params->num_refs > 1) {
1198         schro_motionest_superblock_biref_zero (me, &tryblock, i, j);
1199       TRYBLOCK}
1200 
1201       if (min_score > block_threshold || block.mv[0][0].pred_mode == 0) {
1202         schro_motionest_superblock_subsuperblock (me, &tryblock, i, j);
1203         TRYBLOCK schro_motionest_superblock_block (me, &tryblock, i, j);
1204       TRYBLOCK}
1205 
1206       if (me->encoder_frame->encoder->enable_phasecorr_estimation) {
1207         schro_motionest_superblock_phasecorr1 (me, 0, &tryblock, i, j);
1208         TRYBLOCK if (params->num_refs > 1)
1209         {
1210           schro_motionest_superblock_phasecorr1 (me, 1, &tryblock, i, j);
1211         TRYBLOCK}
1212       }
1213 
1214       if (me->encoder_frame->encoder->enable_global_motion) {
1215         schro_motionest_superblock_global (me, 0, &tryblock, i, j);
1216         TRYBLOCK if (params->num_refs > 1)
1217         {
1218           schro_motionest_superblock_global (me, 1, &tryblock, i, j);
1219         TRYBLOCK}
1220       }
1221 
1222       if (block.error > 10 * block_size) {
1223         me->badblocks++;
1224       }
1225 
1226       schro_block_fixup (&block);
1227       schro_motion_copy_to (me->motion, i, j, &block);
1228 
1229       total_error +=
1230           (double) block.error * block.error / (double) (block_size *
1231           block_size);
1232     }
1233   }
1234 
1235   me->encoder_frame->mc_error = total_error / (240.0 * 240.0) /
1236       (params->x_num_blocks * params->y_num_blocks / 16);
1237 
1238   /* magic parameter */
1239   me->encoder_frame->mc_error *= 2.5;
1240 }
1241 
1242 int
schro_motion_block_estimate_entropy(SchroMotion * motion,int i,int j)1243 schro_motion_block_estimate_entropy (SchroMotion * motion, int i, int j)
1244 {
1245   SchroMotionVector *mv;
1246   int entropy = 0;
1247 
1248   mv = SCHRO_MOTION_GET_BLOCK (motion, i, j);
1249 
1250   if (mv->split == 0 && (i & 3 || j & 3))
1251     return 0;
1252   if (mv->split == 1 && (i & 1 || j & 1))
1253     return 0;
1254 
1255   if (mv->pred_mode == 0) {
1256     int pred[3];
1257 
1258     schro_motion_dc_prediction (motion, i, j, pred);
1259 
1260     entropy += schro_pack_estimate_sint (mv->u.dc.dc[0] - pred[0]);
1261     entropy += schro_pack_estimate_sint (mv->u.dc.dc[1] - pred[1]);
1262     entropy += schro_pack_estimate_sint (mv->u.dc.dc[2] - pred[2]);
1263 
1264     return entropy;
1265   }
1266   if (mv->using_global)
1267     return 0;
1268   if (mv->pred_mode & 1) {
1269     int pred_x, pred_y;
1270     schro_motion_vector_prediction (motion, i, j, &pred_x, &pred_y, 1);
1271     entropy += schro_pack_estimate_sint (mv->u.vec.dx[0] - pred_x);
1272     entropy += schro_pack_estimate_sint (mv->u.vec.dy[0] - pred_y);
1273   }
1274   if (mv->pred_mode & 2) {
1275     int pred_x, pred_y;
1276     schro_motion_vector_prediction (motion, i, j, &pred_x, &pred_y, 2);
1277     entropy += schro_pack_estimate_sint (mv->u.vec.dx[1] - pred_x);
1278     entropy += schro_pack_estimate_sint (mv->u.vec.dy[1] - pred_y);
1279   }
1280   return entropy;
1281 }
1282 
1283 int
schro_motion_estimate_entropy(SchroMotion * motion)1284 schro_motion_estimate_entropy (SchroMotion * motion)
1285 {
1286   SchroParams *params = motion->params;
1287   int i, j;
1288   int entropy = 0;
1289 
1290   for (j = 0; j < params->y_num_blocks; j++) {
1291     for (i = 0; i < params->x_num_blocks; i++) {
1292       entropy += schro_motion_block_estimate_entropy (motion, i, j);
1293     }
1294   }
1295 
1296   return entropy;
1297 }
1298 
1299 #ifdef unused
1300 int
schro_motion_superblock_estimate_entropy(SchroMotion * motion,int i,int j)1301 schro_motion_superblock_estimate_entropy (SchroMotion * motion, int i, int j)
1302 {
1303   int ii, jj;
1304   int entropy = 0;
1305 
1306   for (jj = j; jj < j + 4; jj++) {
1307     for (ii = i; ii < i + 4; ii++) {
1308       entropy += schro_motion_block_estimate_entropy (motion, ii, jj);
1309     }
1310   }
1311 
1312   return entropy;
1313 }
1314 #endif
1315 
1316 int
schro_motion_superblock_try_estimate_entropy(SchroMotion * motion,int i,int j,SchroBlock * block)1317 schro_motion_superblock_try_estimate_entropy (SchroMotion * motion, int i,
1318     int j, SchroBlock * block)
1319 {
1320   int ii, jj;
1321   int entropy = 0;
1322   SchroBlock save_block;
1323 
1324   schro_motion_copy_from (motion, i, j, &save_block);
1325   schro_motion_copy_to (motion, i, j, block);
1326   for (jj = 0; jj < 4; jj++) {
1327     for (ii = 0; ii < 4; ii++) {
1328       entropy += schro_motion_block_estimate_entropy (motion, i + ii, j + jj);
1329     }
1330   }
1331   schro_motion_copy_to (motion, i, j, &save_block);
1332 
1333   return entropy;
1334 }
1335 
1336 int
schro_motionest_superblock_get_metric(SchroMotionEst * me,SchroBlock * block,int i,int j)1337 schro_motionest_superblock_get_metric (SchroMotionEst * me,
1338     SchroBlock * block, int i, int j)
1339 {
1340   SchroMotionVector *mv;
1341   SchroFrameData orig;
1342   int width, height;
1343   int xmin, ymin;
1344   int xmax, ymax;
1345 
1346   xmin = MAX (i * me->params->xbsep_luma, 0);
1347   ymin = MAX (j * me->params->ybsep_luma, 0);
1348   xmax =
1349       MIN ((i + 4) * me->params->xbsep_luma,
1350       me->encoder_frame->filtered_frame->width);
1351   ymax =
1352       MIN ((j + 4) * me->params->ybsep_luma,
1353       me->encoder_frame->filtered_frame->height);
1354 
1355   schro_frame_get_subdata (get_downsampled (me->encoder_frame, 0), &orig,
1356       0, xmin, ymin);
1357 
1358   width = xmax - xmin;
1359   height = ymax - ymin;
1360 
1361   mv = &block->mv[0][0];
1362 
1363   if (mv->pred_mode == 0) {
1364     return schro_metric_get_dc (&orig, mv->u.dc.dc[0], width, height);
1365   }
1366   if (mv->pred_mode == 1 || mv->pred_mode == 2) {
1367     SchroFrame *ref_frame;
1368     SchroFrameData ref_data;
1369     int ref;
1370 
1371     ref = mv->pred_mode - 1;
1372 
1373     ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], 0);
1374 
1375     if (xmin + mv->u.vec.dx[ref] < -ref_frame->extension ||
1376         ymin + mv->u.vec.dy[ref] < -ref_frame->extension ||
1377         xmax + mv->u.vec.dx[ref] >
1378         me->encoder_frame->filtered_frame->width + ref_frame->extension
1379         || ymax + mv->u.vec.dy[ref] >
1380         me->encoder_frame->filtered_frame->height + ref_frame->extension) {
1381       /* bailing because it's "hard" */
1382       return SCHRO_METRIC_INVALID_2;
1383     }
1384 
1385     schro_frame_get_subdata (ref_frame, &ref_data,
1386         0, xmin + mv->u.vec.dx[ref], ymin + mv->u.vec.dy[ref]);
1387 
1388     return schro_metric_get (&orig, &ref_data, width, height);
1389   }
1390 
1391   if (mv->pred_mode == 3) {
1392     SchroFrame *ref0_frame;
1393     SchroFrame *ref1_frame;
1394     SchroFrameData ref0_data;
1395     SchroFrameData ref1_data;
1396 
1397     ref0_frame = get_downsampled (me->encoder_frame->ref_frame[0], 0);
1398     ref1_frame = get_downsampled (me->encoder_frame->ref_frame[1], 0);
1399 
1400     if (xmin + mv->u.vec.dx[0] < -ref0_frame->extension ||
1401         ymin + mv->u.vec.dy[0] < -ref0_frame->extension ||
1402         xmax + mv->u.vec.dx[0] >
1403         me->encoder_frame->filtered_frame->width + ref0_frame->extension
1404         || ymax + mv->u.vec.dy[0] >
1405         me->encoder_frame->filtered_frame->height + ref0_frame->extension
1406         || xmin + mv->u.vec.dx[1] < -ref1_frame->extension
1407         || ymin + mv->u.vec.dy[1] < -ref1_frame->extension
1408         || xmax + mv->u.vec.dx[1] >
1409         me->encoder_frame->filtered_frame->width + ref1_frame->extension
1410         || ymax + mv->u.vec.dy[1] >
1411         me->encoder_frame->filtered_frame->height + ref1_frame->extension) {
1412       /* bailing because it's "hard" */
1413       return SCHRO_METRIC_INVALID_2;
1414     }
1415 
1416     schro_frame_get_subdata (ref0_frame,
1417         &ref0_data, 0, xmin + mv->u.vec.dx[0], ymin + mv->u.vec.dy[0]);
1418     schro_frame_get_subdata (ref1_frame,
1419         &ref1_data, 0, xmin + mv->u.vec.dx[1], ymin + mv->u.vec.dy[1]);
1420 
1421     return schro_metric_get_biref (&orig, &ref0_data, 1, &ref1_data, 1, 1,
1422         width, height);
1423   }
1424 
1425   SCHRO_ASSERT (0);
1426 
1427   return SCHRO_METRIC_INVALID_2;
1428 }
1429 
1430 #ifdef unused
1431 int
schro_block_check(SchroBlock * block)1432 schro_block_check (SchroBlock * block)
1433 {
1434   SchroMotionVector *sbmv;
1435   SchroMotionVector *bmv;
1436   SchroMotionVector *mv;
1437   int i, j;
1438 
1439   sbmv = &block->mv[0][0];
1440   for (j = 0; j < 4; j++) {
1441     for (i = 0; i < 4; i++) {
1442       mv = &block->mv[j][i];
1443 
1444       switch (sbmv->split) {
1445         case 0:
1446           if (!schro_motion_vector_is_equal (mv, sbmv)) {
1447             SCHRO_ERROR ("mv(%d,%d) not equal to superblock mv", i, j);
1448             return 0;
1449           }
1450           break;
1451         case 1:
1452           bmv = &block->mv[(j & ~1)][(i & ~1)];
1453           if (!schro_motion_vector_is_equal (mv, bmv)) {
1454             SCHRO_ERROR ("mv(%d,%d) not equal to 2-block mv", i, j);
1455             return 0;
1456           }
1457           break;
1458         case 2:
1459           break;
1460         default:
1461           SCHRO_ERROR ("mv(%d,%d) has bad split", i, j);
1462           return 0;
1463           break;
1464       }
1465     }
1466   }
1467 
1468   return 1;
1469 }
1470 #endif
1471 
1472 void
schro_block_fixup(SchroBlock * block)1473 schro_block_fixup (SchroBlock * block)
1474 {
1475   SchroMotionVector *mv;
1476 
1477   mv = &block->mv[0][0];
1478   if (mv->split == 0) {
1479     mv[1] = mv[0];
1480     mv[2] = mv[0];
1481     mv[3] = mv[0];
1482     memcpy (mv + 4, mv, 4 * sizeof (*mv));
1483     memcpy (mv + 8, mv, 4 * sizeof (*mv));
1484     memcpy (mv + 12, mv, 4 * sizeof (*mv));
1485   }
1486   if (mv->split == 1) {
1487     mv[1] = mv[0];
1488     mv[3] = mv[2];
1489     memcpy (mv + 4, mv, 4 * sizeof (*mv));
1490     mv[9] = mv[8];
1491     mv[11] = mv[10];
1492     memcpy (mv + 12, mv + 8, 4 * sizeof (*mv));
1493   }
1494 }
1495 
1496 void
schro_motion_copy_from(SchroMotion * motion,int i,int j,SchroBlock * block)1497 schro_motion_copy_from (SchroMotion * motion, int i, int j, SchroBlock * block)
1498 {
1499   SchroMotionVector *mv;
1500   int ii, jj;
1501 
1502   for (jj = 0; jj < 4; jj++) {
1503     for (ii = 0; ii < 4; ii++) {
1504       mv = SCHRO_MOTION_GET_BLOCK (motion, i + ii, j + jj);
1505       block->mv[jj][ii] = *mv;
1506     }
1507   }
1508 }
1509 
1510 void
schro_motion_copy_to(SchroMotion * motion,int i,int j,SchroBlock * block)1511 schro_motion_copy_to (SchroMotion * motion, int i, int j, SchroBlock * block)
1512 {
1513   SchroMotionVector *mv;
1514   int ii, jj;
1515 
1516   for (jj = 0; jj < 4; jj++) {
1517     for (ii = 0; ii < 4; ii++) {
1518       mv = SCHRO_MOTION_GET_BLOCK (motion, i + ii, j + jj);
1519       *mv = block->mv[jj][ii];
1520     }
1521   }
1522 }
1523 
1524 /* performs single position block matching for split2
1525  * to calculate SAD */
1526 static void
schro_get_split2_metric(SchroMe * me,int ref,int i,int j,SchroMotionVector * mv,int * metric,SchroFrameData * fd)1527 schro_get_split2_metric (SchroMe * me, int ref, int i, int j,
1528     SchroMotionVector * mv, int *metric, SchroFrameData * fd)
1529 {
1530   SchroParams *params = schro_me_params (me);
1531   SchroFrameData orig[2], ref_data[2];
1532   SchroFrame *frame = schro_me_src (me);
1533   SchroUpsampledFrame *upframe;
1534   int mv_prec = params->mv_precision;
1535   int fd_width, fd_height;
1536   int width[3], height[3], dx, dy;
1537   int k;
1538   int tmp_x, tmp_y;
1539   int block_x[3], block_y[3];
1540 
1541   /* calculates split2 block sizes for all components */
1542   block_x[0] = params->xbsep_luma;
1543   block_y[0] = params->ybsep_luma;
1544   block_x[1] = block_x[2] =
1545       block_x[0] >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
1546       video_format->chroma_format);
1547   block_y[1] = block_y[2] =
1548       block_y[0] >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
1549       video_format->chroma_format);
1550 
1551   /* get source data if possible */
1552   for (k = 1; 3 > k; ++k) {
1553     if (!schro_frame_get_data (frame, &orig[k - 1], k, i * block_x[k],
1554             j * block_y[k])) {
1555       *metric = INT_MAX;
1556       return;
1557     }
1558     width[k] = MIN (block_x[k], orig[k - 1].width);
1559     height[k] = MIN (block_y[k], orig[k - 1].height);
1560   }
1561   upframe = schro_me_ref (me, ref);
1562   *metric = 0;
1563   for (k = 1; 3 > k; ++k) {
1564     /* get ref data, if possible */
1565     tmp_x = (i * block_x[k]) << mv_prec;
1566     tmp_y = (j * block_y[k]) << mv_prec;
1567     dx = mv->u.vec.dx[ref];
1568     dx >>= SCHRO_CHROMA_FORMAT_H_SHIFT (params->video_format->chroma_format);
1569     dx += tmp_x;
1570     dy = mv->u.vec.dy[ref];
1571     dy >>= SCHRO_CHROMA_FORMAT_V_SHIFT (params->video_format->chroma_format);
1572     dy += tmp_y;
1573     if (INT_MAX == mv->metric) {
1574       *metric = INT_MAX;
1575       return;
1576     }
1577     /* I need to save the original value of fd width and height */
1578     fd_width = fd->width;
1579     fd_height = fd->height;
1580     fd->width = width[k];
1581     fd->height = height[k];
1582 
1583     schro_upsampled_frame_get_block_fast_precN (upframe, k, dx, dy, mv_prec,
1584         &ref_data[k - 1], fd);
1585     fd->width = fd_width;
1586     fd->height = fd_height;
1587     *metric +=
1588         schro_metric_absdiff_u8 (orig[k - 1].data, orig[k - 1].stride,
1589         ref_data[k - 1].data, ref_data[k - 1].stride, width[k], height[k]);
1590   }
1591   mv->chroma_metric = *metric;
1592   *metric += mv->metric;
1593   return;
1594 }
1595 
1596 
1597 /* performs mode decision for a superblock, split level 2
1598  * Note that a SchroMotion object is required to estimate
1599  * the cost of the different prediction modes. */
1600 static void
schro_do_split2(SchroMe * me,int i,int j,SchroBlock * block,SchroFrameData * fd)1601 schro_do_split2 (SchroMe * me, int i, int j, SchroBlock * block,
1602     SchroFrameData * fd)
1603 {
1604   int total_entropy = 0, total_error = 0, ii, jj, ref;
1605   double lambda = schro_me_lambda (me); /* frame->frame_me_lambda; */
1606   int comp_w[3], comp_h[3];
1607   SchroParams *params = schro_me_params (me);
1608   SchroMotion *motion = schro_me_motion (me);
1609   int mvprec = params->mv_precision;
1610   int xnum_blocks = params->x_num_blocks;
1611   int fd_width, fd_height, biref;
1612   int xblen = params->xbsep_luma, yblen = params->ybsep_luma;
1613   SchroFrame *orig_frame = schro_me_src (me);
1614   SchroFrameData ref_data[3][2], orig[3];
1615   SchroUpsampledFrame *upframe[2];
1616   SchroMotionField *mf;
1617   int xmin, ymin, xmax, ymax;
1618 
1619   xmin = ymin = -orig_frame->extension;
1620   xmax = (orig_frame->width << mvprec) + orig_frame->extension;
1621   ymax = (orig_frame->height << mvprec) + orig_frame->extension;
1622 
1623   comp_w[0] = xblen;
1624   comp_h[0] = yblen;
1625   comp_w[1] = comp_w[2] = xblen
1626       >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->video_format->chroma_format);
1627   comp_h[1] = comp_h[2] = yblen
1628       >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->video_format->chroma_format);
1629 
1630 
1631   for (jj = 0; 4 > jj; ++jj) {
1632     for (ii = 0; 4 > ii; ++ii) {
1633       double score, min_score = HUGE_VAL;
1634       int entropy[2], error;
1635       int width[3], height[3];
1636       int dx[2], dy[2];
1637       int k;
1638       int best_entropy = INT_MAX, best_error = INT_MAX;
1639       SchroMotionVector *mv, *mv_ref[2], best_mv = { 0 };
1640       best_mv.split = 2;
1641       best_mv.pred_mode = 1;
1642 
1643       mv_ref[0] = mv_ref[1] = NULL;
1644       memset (entropy, 0, sizeof (entropy));
1645       memset (width, 0, sizeof (width));
1646       memset (height, 0, sizeof (height));
1647       mv = motion->motion_vectors + (j + jj) * xnum_blocks + i + ii;
1648       /* check that the block lies whitin the frame */
1649       if (!(orig_frame->width > (i + ii) * xblen)
1650           || !(orig_frame->height > (j + jj) * yblen)) {
1651         /* Note: blocks outside frame are encoded pred_mode 1, zero MVs */
1652         int pred_x, pred_y;
1653         *mv = best_mv;
1654         mv->pred_mode =
1655             schro_motion_get_mode_prediction (motion, i + ii, j + jj);
1656         if (mv->pred_mode != 1 && mv->pred_mode != 2)
1657           mv->pred_mode = 1;
1658         schro_motion_vector_prediction (motion, i + ii, j + jj, &pred_x,
1659             &pred_y, 1);
1660         mv->u.vec.dx[mv->pred_mode - 1] = pred_x;
1661         mv->u.vec.dy[mv->pred_mode - 1] = pred_y;
1662         block->mv[jj][ii] = best_mv;
1663         total_entropy += 2;
1664         continue;
1665       }
1666       mv->metric = INT_MAX;
1667 
1668       /* do the 2 references, if available */
1669       for (ref = 0; params->num_refs > ref; ++ref) {
1670         mf = schro_me_split2_mf (me, ref);
1671         SCHRO_ASSERT (mf);
1672         mv_ref[ref] = mf->motion_vectors + (j + jj) * xnum_blocks + i + ii;
1673         *mv = *mv_ref[ref];
1674         mv->split = 2;
1675         mv->pred_mode = ref + 1;
1676         mv->using_global = 0;
1677         entropy[ref] =
1678             schro_motion_block_estimate_entropy (motion, i + ii, j + jj);
1679         schro_get_split2_metric (me, ref, i + ii, j + jj, mv, &error, fd);
1680         score = entropy[ref] + error * lambda;
1681         if (min_score > score) {
1682           min_score = score;
1683           best_mv = *mv;
1684           best_entropy = entropy[ref];
1685           best_error = mv->metric;
1686         }
1687       }
1688       /* do biref, if available */
1689       if (1 < params->num_refs) {
1690         /* Note: I need to calculate the cost of biref prediction */
1691         biref = TRUE;           /* flag - either or both MVs could be outside frame+ext */
1692         mv->u.vec.dx[0] = mv_ref[0]->u.vec.dx[0];
1693         mv->u.vec.dy[0] = mv_ref[0]->u.vec.dy[0];
1694         mv->u.vec.dx[1] = mv_ref[1]->u.vec.dx[1];
1695         mv->u.vec.dy[1] = mv_ref[1]->u.vec.dy[1];
1696         mv->pred_mode = 3;
1697         mv->using_global = 0;
1698         for (k = 0; 3 > k; ++k) {
1699           int tmp_x;
1700           int tmp_y;
1701 
1702           /* fetch dource data for all components */
1703           schro_frame_get_data (orig_frame, &orig[k], k, (i + ii) * comp_w[k],
1704               (j + jj) * comp_h[k]);
1705           width[k] = MIN (comp_w[k], orig[k].width);
1706           height[k] = MIN (comp_h[k], orig[k].height);
1707           tmp_x = (i + ii) * (comp_w[k] << mvprec);
1708           tmp_y = (j + jj) * (comp_h[k] << mvprec);
1709           for (ref = 0; params->num_refs > ref; ++ref) {
1710             dx[ref] = mv->u.vec.dx[ref];
1711             dx[ref] >>= 0 == k ? 0
1712                 : SCHRO_CHROMA_FORMAT_H_SHIFT (params->
1713                 video_format->chroma_format);
1714             dx[ref] += tmp_x;
1715             dy[ref] = mv->u.vec.dy[ref];
1716             dy[ref] >>= 0 == k ? 0
1717                 : SCHRO_CHROMA_FORMAT_V_SHIFT (params->
1718                 video_format->chroma_format);
1719             dy[ref] += tmp_y;
1720             if (0 == k && biref && (xmin > dx[ref] || ymin > dy[ref]
1721                     || !(xmax > dx[ref] + width[k] - 1)
1722                     || !(ymax > dy[ref] + height[k] - 1))) {
1723               biref = FALSE;
1724               break;
1725             }
1726             /* I need to save the original value of fd width and height */
1727             fd_width = fd[ref].width;
1728             fd_height = fd[ref].height;
1729             fd[ref].width = width[k];
1730             fd[ref].height = height[k];
1731             upframe[ref] = schro_me_ref (me, ref);
1732             schro_upsampled_frame_get_block_fast_precN (upframe[ref], k, dx[ref]
1733                 , dy[ref], mvprec, &ref_data[k][ref], &fd[ref]);
1734             fd[ref].width = fd_width;
1735             fd[ref].height = fd_height;
1736           }
1737         }
1738         if (biref) {
1739           mv->metric =
1740               schro_metric_get_biref (&orig[0], &ref_data[0][0], 1,
1741               &ref_data[0][1], 1, 1, width[0], height[0]);
1742           mv->chroma_metric = 0;
1743           for (k = 1; 3 > k; ++k) {
1744             mv->chroma_metric +=
1745                 schro_metric_get_biref (&orig[k], &ref_data[k][0], 1,
1746                 &ref_data[k][1], 1, 1, width[k], height[k]);
1747           }
1748           score =
1749               entropy[0] + entropy[1] + (mv->metric +
1750               mv->chroma_metric) * lambda;
1751           if (min_score > score) {
1752             best_error = mv->metric + mv->chroma_metric;
1753             best_entropy = entropy[0] + entropy[1];
1754             best_mv = *mv;
1755             min_score = score;
1756           }
1757         }
1758       }
1759 
1760       /* FIXME: magic used for considering DC prediction */
1761       if (4 * (width[0] * height[0] + 2 * width[1] * height[1]) < best_error) {
1762         /* let's consider DC prediction */
1763         SchroMotionVector *mvdc;
1764         int k;
1765         int ok = TRUE;
1766 
1767         mvdc = (SchroMotionVector *) mv;
1768         mvdc->pred_mode = 0;
1769         mvdc->split = 2;
1770         mvdc->using_global = 0;
1771         error = 0;
1772         for (k = 0; 3 > k; ++k) {
1773           int tmp = schro_block_average (&mvdc->u.dc.dc[k],
1774               orig_frame->components + k, (i + ii) * comp_w[k],
1775               (j + jj) * comp_h[k], comp_w[k], comp_h[k]);
1776           if (SCHRO_METRIC_INVALID_2 == tmp) {
1777             SCHRO_DEBUG ("Invalid DC metric");
1778             mvdc->metric = INT_MAX;
1779             ok = FALSE;
1780           } else {
1781             error += tmp;
1782           }
1783         }
1784         if (ok) {
1785           mvdc->metric = error;
1786           /* FIXME: we're assuming that the block doesn't have any predictor */
1787           entropy[0] = schro_pack_estimate_sint (mvdc->u.dc.dc[0]);
1788           entropy[0] += schro_pack_estimate_sint (mvdc->u.dc.dc[1]);
1789           entropy[0] += schro_pack_estimate_sint (mvdc->u.dc.dc[2]);
1790           if (error < best_error) {
1791             best_mv = *(SchroMotionVector *) mvdc;
1792             best_error = mvdc->metric;
1793             best_entropy = entropy[0];
1794           }
1795         }
1796       }
1797       *mv = best_mv;
1798       total_error += best_error;
1799       total_entropy += best_entropy;
1800       block->mv[jj][ii] = best_mv;
1801     }
1802   }
1803   block->valid = TRUE;
1804   block->error = total_error;
1805   block->entropy = total_entropy;
1806   block->score = total_entropy + lambda * total_error;
1807 }
1808 
1809 static void
set_split1_motion(SchroMotion * motion,int i,int j)1810 set_split1_motion (SchroMotion * motion, int i, int j)
1811 {
1812   SchroParams *params = motion->params;
1813   int xnum_blocks = params->x_num_blocks;
1814   SchroMotionVector *mv = motion->motion_vectors + j * xnum_blocks + i;
1815 
1816   *(mv + 1) = *mv;
1817   *(mv + xnum_blocks) = *mv;
1818   *(mv + xnum_blocks + 1) = *mv;
1819 }
1820 
1821 static int
mv_already_in_list(SchroMotionVector * hint_list[],int len,SchroMotionVector * candidate_mv,int ref,int shift)1822 mv_already_in_list (SchroMotionVector * hint_list[], int len,
1823     SchroMotionVector * candidate_mv, int ref, int shift)
1824 {
1825   int i;
1826 
1827   for (i = 0; len > i; ++i) {
1828     if ((candidate_mv->u.vec.dx[ref] << shift) == hint_list[i]->u.vec.dx[ref]
1829         && (candidate_mv->u.vec.dy[ref] << shift) ==
1830         hint_list[i]->u.vec.dy[ref]) {
1831       return TRUE;
1832     }
1833   }
1834   return FALSE;
1835 }
1836 
1837 /* select a MV for a split1 block based on 5 seeds
1838    the four split 2 MVs and the MV from rough ME, level 1.
1839    The selection of the MV is based on actual cost, not just SAD */
1840 static void
schro_get_best_mv_split1(SchroMe * me,int ref,int i,int j,SchroMotionVector * mv_ref,int * error,int * entropy,SchroFrameData * fd)1841 schro_get_best_mv_split1 (SchroMe * me, int ref, int i, int j,
1842     SchroMotionVector * mv_ref, int *error, int *entropy, SchroFrameData * fd)
1843 {
1844   SchroMotionVector *hint_mv[6], *mv_motion;
1845   SchroMotionVector *mv, temp_mv = { 0 };
1846   SchroMotionField *mf;
1847   SchroParams *params = schro_me_params (me);
1848   SchroFrameData orig[3], ref_data[3];
1849   SchroFrame *frame = schro_me_src (me);
1850   SchroUpsampledFrame *upframe;
1851   SchroMotion *motion = schro_me_motion (me);
1852   int n = 0, ii, jj, m = 0, min_m, metric, ent;
1853   int mv_prec = params->mv_precision;
1854   int fd_width, fd_height;
1855   double score, min_score, lambda = schro_me_lambda (me);
1856   int xblen, yblen, width[3], height[3], dx, dy;
1857   int comp_w[3], comp_h[3];
1858   int k;
1859   int xmin, xmax, ymin, ymax, tmp_x, tmp_y;
1860   int best_error = INT_MAX, best_entropy = INT_MAX;
1861   int best_chroma_error = INT_MAX;
1862   int block_x[3], block_y[3];
1863   SchroHierBm *hbm;
1864 
1865   xblen = params->xbsep_luma << 1;
1866   yblen = params->ybsep_luma << 1;
1867   xmin = ymin = -frame->extension;
1868   xmax = (frame->width << mv_prec) + frame->extension;
1869   ymax = (frame->height << mv_prec) + frame->extension;
1870   /* calculate split1 block sizes for all components */
1871   comp_w[0] = xblen;
1872   comp_h[0] = yblen;
1873   comp_w[1] = comp_w[2] = xblen
1874       >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->video_format->chroma_format);
1875   comp_h[1] = comp_h[2] = yblen
1876       >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->video_format->chroma_format);
1877   /* calculates split2 block sizes for all components */
1878   block_x[0] = params->xbsep_luma;
1879   block_y[0] = params->ybsep_luma;
1880   block_x[1] = block_x[2] =
1881       block_x[0] >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
1882       video_format->chroma_format);
1883   block_y[1] = block_y[2] =
1884       block_y[0] >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
1885       video_format->chroma_format);
1886 
1887   SCHRO_ASSERT (motion);
1888   mv_motion = motion->motion_vectors + j * params->x_num_blocks + i;
1889 
1890   for (k = 0; 3 > k; ++k) {
1891     /* get source data if possible */
1892     if (!schro_frame_get_data (frame, &orig[k], k, i * block_x[k],
1893             j * block_y[k])) {
1894       *mv_ref = temp_mv;
1895       mv_ref->metric = INT_MAX;
1896       mv_ref->pred_mode = ref + 1;
1897       *error = INT_MAX;
1898       *mv_motion = *mv_ref;
1899       *entropy = schro_motion_block_estimate_entropy (motion, i, j);
1900       return;
1901     }
1902     width[k] = MIN (comp_w[k], orig[k].width);
1903     height[k] = MIN (comp_h[k], orig[k].height);
1904   }
1905   /* inherit from split 2 level MV */
1906   mf = schro_me_subpel_mf (me, ref);
1907   SCHRO_ASSERT (mf);
1908   for (jj = 0; 2 > jj; ++jj) {
1909     for (ii = 0; 2 > ii; ++ii) {
1910       mv = mf->motion_vectors + (j + jj) * mf->x_num_blocks + i + ii;
1911       if (SCHRO_METRIC_INVALID != mv->metric) {
1912         if ((0 < n && !mv_already_in_list (hint_mv, n, mv, ref, mv_prec))
1913             || 0 == n) {
1914           hint_mv[n++] = mv;
1915         }
1916       }
1917     }
1918   }
1919   /* inherit from stage 1 of hier. BM */
1920   hbm = schro_me_hbm (me, ref);
1921   SCHRO_ASSERT (hbm);
1922   mf = schro_hbm_motion_field (hbm, 1);
1923   SCHRO_ASSERT (mf);
1924   mv = mf->motion_vectors + j * mf->x_num_blocks + i;
1925   if (INT_MAX != mv->metric) {
1926     if ((0 < n && !mv_already_in_list (hint_mv, n, mv, ref, mv_prec)) || 0 == n) {
1927       temp_mv = *mv;
1928       temp_mv.u.vec.dx[ref] <<= mv_prec;
1929       temp_mv.u.vec.dy[ref] <<= mv_prec;
1930       hint_mv[n++] = &temp_mv;
1931     }
1932   }
1933 
1934   /* now pick the best candidate */
1935   min_m = -1;
1936   min_score = HUGE_VAL;
1937   upframe = schro_me_ref (me, ref);
1938   for (m = 0; n > m; ++m) {
1939     int chroma_metric = 0;
1940     int ok = TRUE;
1941 
1942     metric = 0;
1943     for (k = 0; 3 > k; ++k) {
1944       tmp_x = (i * block_x[k]) << mv_prec;
1945       tmp_y = (j * block_y[k]) << mv_prec;
1946       dx = hint_mv[m]->u.vec.dx[ref];
1947       dx >>= 0 == k ? 0
1948           : SCHRO_CHROMA_FORMAT_H_SHIFT (params->video_format->chroma_format);
1949       dx += tmp_x;
1950       dy = hint_mv[m]->u.vec.dy[ref];
1951       dy >>= 0 == k ? 0
1952           : SCHRO_CHROMA_FORMAT_V_SHIFT (params->video_format->chroma_format);
1953       dy += tmp_y;
1954       if (0 == k && (xmin > dx || ymin > dy
1955               || !(xmax > dx + width[k] - 1) || !(ymax > dy + height[k] - 1))) {
1956         k = 3;
1957         ok = FALSE;
1958         continue;
1959       }
1960       /* I need to save the original value of fd width and height */
1961       fd_width = fd->width;
1962       fd_height = fd->height;
1963       fd->width = width[k];
1964       fd->height = height[k];
1965 
1966       schro_upsampled_frame_get_block_fast_precN (upframe, k, dx, dy, mv_prec,
1967           &ref_data[k], fd);
1968       fd->width = fd_width;
1969       fd->height = fd_height;
1970       if (0 == k) {
1971         metric =
1972             schro_metric_absdiff_u8 (orig[0].data, orig[0].stride,
1973             ref_data[0].data, ref_data[0].stride, width[0], height[0]);
1974       } else {
1975         chroma_metric +=
1976             schro_metric_absdiff_u8 (orig[k].data, orig[k].stride,
1977             ref_data[k].data, ref_data[k].stride, width[k], height[k]);
1978       }
1979     }
1980     if (ok) {
1981       *mv_motion = *hint_mv[m];
1982       mv_motion->split = 1;
1983       mv_motion->pred_mode = ref + 1;
1984       ent = schro_motion_block_estimate_entropy (motion, i, j);
1985       score = ent + (metric + chroma_metric) * lambda;
1986       if (min_score > score) {
1987         min_score = score;
1988         min_m = m;
1989         best_entropy = ent;
1990         best_error = metric;
1991         best_chroma_error = chroma_metric;
1992       }
1993     }
1994   }
1995   if (-1 < min_m) {
1996     *error = best_error + best_chroma_error;
1997     *entropy = best_entropy;
1998     *mv_ref = *hint_mv[min_m];
1999     mv_ref->metric = best_error >> 2;
2000     mv_ref->chroma_metric = best_chroma_error >> 2;
2001     mv_ref->split = 1;
2002     mv_ref->pred_mode = ref + 1;
2003   } else
2004     mv_ref->metric = INT_MAX;
2005 }
2006 
2007 /* performs mode decision for a superblock, split level 1 */
2008 static void
schro_do_split1(SchroMe * me,int i,int j,SchroBlock * block,SchroFrameData * fd)2009 schro_do_split1 (SchroMe * me, int i, int j, SchroBlock * block,
2010     SchroFrameData * fd)
2011 {
2012   SchroParams *params = schro_me_params (me);
2013   SchroMotion *motion = schro_me_motion (me);
2014   SchroFrame *orig_frame = schro_me_src (me);
2015   SchroFrameData ref_data[3][2], orig[3];
2016   SchroUpsampledFrame *upframe[2];
2017   SchroMotionField *mf;
2018   double lambda = schro_me_lambda (me);
2019   int ii, jj, ref, biref, k;
2020   int total_entropy = 0, total_error = 0;
2021   int mvprec = params->mv_precision;
2022   int xblen = params->xbsep_luma * 2, yblen = params->ybsep_luma * 2;
2023   int width[3], height[3], dx[2], dy[2], tmp_x, tmp_y;
2024   int fd_width, fd_height;
2025   int xmin, xmax, ymin, ymax;
2026   int comp_h[3], comp_w[3];
2027   int block_x[3], block_y[3];
2028 
2029   xmin = ymin = -orig_frame->extension;
2030   xmax = (orig_frame->width << mvprec) + orig_frame->extension;
2031   ymax = (orig_frame->height << mvprec) + orig_frame->extension;
2032 
2033   comp_w[0] = xblen;
2034   comp_h[0] = yblen;
2035   comp_w[1] = comp_w[2] = xblen
2036       >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->video_format->chroma_format);
2037   comp_h[1] = comp_h[2] = yblen
2038       >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->video_format->chroma_format);
2039   block_x[0] = params->xbsep_luma;
2040   block_y[0] = params->ybsep_luma;
2041   block_x[1] = block_x[2] =
2042       block_x[0] >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
2043       video_format->chroma_format);
2044   block_y[1] = block_y[2] =
2045       block_y[0] >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
2046       video_format->chroma_format);
2047 
2048   block->valid = TRUE;
2049 
2050   for (jj = 0; 4 > jj; jj += 2) {
2051     for (ii = 0; 4 > ii; ii += 2) {
2052       double score, min_score = HUGE_VAL;
2053       int entropy[2], error = INT_MAX;
2054       int best_entropy = INT_MAX, best_chroma_error = INT_MAX, best_error =
2055           INT_MAX;
2056       /* Note that the metric for the split 1 block will be stored in best_mv
2057        * but divided by 4 */
2058       SchroMotionVector *mv, best_mv = { 0 }, mv_ref[2], *mv_split1;
2059       best_mv.split = 1;
2060       best_mv.pred_mode = 1;
2061 
2062       mv = motion->motion_vectors + (j + jj) * params->x_num_blocks + i + ii;
2063       /* check that the block lies within the frame */
2064       if (!(orig_frame->width > (i + ii) * params->xbsep_luma)
2065           || !(orig_frame->height > (j + jj) * params->ybsep_luma)) {
2066         /* the block lies outside the frame, set both block and motion
2067          * to a zero mv, split 1, forward predicted */
2068         int pred_x, pred_y;
2069         *mv = best_mv;
2070         mv->pred_mode =
2071             schro_motion_get_mode_prediction (motion, i + ii, j + jj);
2072         if (mv->pred_mode != 1 && mv->pred_mode != 2)
2073           mv->pred_mode = 1;
2074         schro_motion_vector_prediction (motion, i + ii, j + jj, &pred_x,
2075             &pred_y, 1);
2076         mv->u.vec.dx[mv->pred_mode - 1] = pred_x;
2077         mv->u.vec.dy[mv->pred_mode - 1] = pred_y;
2078         block->mv[jj][ii] = *mv;
2079         set_split1_motion (motion, i + ii, j + jj);
2080         total_entropy += 2;
2081         mf = schro_me_split1_mf (me, 0);
2082         SCHRO_ASSERT (mf);
2083         mv_split1 =
2084             mf->motion_vectors + (j + jj) * params->x_num_blocks + i + ii;
2085         *mv_split1 = best_mv;
2086         if (1 < params->num_refs) {
2087           mf = schro_me_split1_mf (me, 1);
2088           SCHRO_ASSERT (mf);
2089           mv_split1 =
2090               mf->motion_vectors + (j + jj) * params->x_num_blocks + i + ii;
2091           *mv_split1 = best_mv;
2092           mv_split1->pred_mode = 2;
2093         }
2094         continue;
2095       }
2096       mv->metric = INT_MAX;
2097       mv->chroma_metric = INT_MAX;
2098       best_mv.metric = INT_MAX;
2099       best_mv.chroma_metric = INT_MAX;
2100 
2101       /* do the 2 references, if available */
2102       for (ref = 0; params->num_refs > ref; ++ref) {
2103         mf = schro_me_split1_mf (me, ref);
2104         SCHRO_ASSERT (mf);
2105         mv_split1 =
2106             mf->motion_vectors + (j + jj) * params->x_num_blocks + i + ii;
2107         schro_get_best_mv_split1 (me, ref, i + ii, j + jj, &mv_ref[ref]
2108             , &error, &entropy[ref], fd);
2109         *mv_split1 = mv_ref[ref];
2110         if (INT_MAX != mv_ref[ref].metric) {
2111           score = entropy[ref] + lambda * error;
2112           if (min_score > score) {
2113             min_score = score;
2114             best_mv = mv_ref[ref];
2115             best_entropy = entropy[ref];
2116             best_error = error;
2117           }
2118         }
2119       }
2120       /* do biref if available */
2121       if (1 < params->num_refs
2122           && SCHRO_METRIC_INVALID != mv_ref[0].metric
2123           && SCHRO_METRIC_INVALID != mv_ref[1].metric) {
2124         /* I'm going to use the two best MVs from previous steps
2125          * Note: I need to calculate the cost and entropy of biref */
2126         mv_ref[0].u.vec.dx[1] = mv_ref[1].u.vec.dx[1];
2127         mv_ref[0].u.vec.dy[1] = mv_ref[1].u.vec.dy[1];
2128         mv_ref[0].pred_mode = 3;
2129         biref = TRUE;
2130         for (k = 0; 3 > k; ++k) {
2131           schro_frame_get_data (orig_frame, &orig[k], k, (i + ii) * block_x[k],
2132               (j + jj) * block_y[k]);
2133           width[k] = MIN (comp_w[k], orig[k].width);
2134           height[k] = MIN (comp_h[k], orig[k].height);
2135           tmp_x = (i + ii) * (block_x[k] << mvprec);
2136           tmp_y = (j + jj) * (block_y[k] << mvprec);
2137           for (ref = 0; params->num_refs > ref; ++ref) {
2138             dx[ref] = mv_ref[0].u.vec.dx[ref];
2139             dx[ref] >>= 0 == k ? 0
2140                 : SCHRO_CHROMA_FORMAT_H_SHIFT (params->
2141                 video_format->chroma_format);
2142             dx[ref] += tmp_x;
2143             dy[ref] = mv_ref[0].u.vec.dy[ref];
2144             dy[ref] >>= 0 == k ? 0
2145                 : SCHRO_CHROMA_FORMAT_V_SHIFT (params->
2146                 video_format->chroma_format);
2147             dy[ref] += tmp_y;
2148             /* check whether we can extract reference blocks */
2149             if (0 == k && biref && (xmin > dx[ref] || ymin > dy[ref]
2150                     || !(xmax > dx[ref] + width[k] - 1)
2151                     || !(ymax > dy[ref] + height[k] - 1))) {
2152               biref = FALSE;
2153               k = 3;
2154               break;
2155             }
2156             /* I need to save the original value of fd width and height */
2157             fd_width = fd[ref].width;
2158             fd_height = fd[ref].height;
2159             fd[ref].width = width[k];
2160             fd[ref].height = height[k];
2161             upframe[ref] = schro_me_ref (me, ref);
2162             schro_upsampled_frame_get_block_fast_precN (upframe[ref], k,
2163                 dx[ref], dy[ref], mvprec, &ref_data[k][ref], &fd[ref]);
2164             fd[ref].width = fd_width;
2165             fd[ref].height = fd_height;
2166           }
2167         }
2168         if (biref) {
2169           int chroma_error = 0;
2170 
2171           error = 0;
2172           error =
2173               schro_metric_get_biref (&orig[0], &ref_data[0][0], 1,
2174               &ref_data[0][1], 1, 1, width[0], height[0]);
2175           for (k = 1; 3 > k; ++k) {
2176             chroma_error +=
2177                 schro_metric_get_biref (&orig[k], &ref_data[k][0], 1,
2178                 &ref_data[k][1], 1, 1, width[k], height[k]);
2179           }
2180           score = entropy[0] + entropy[1] + lambda * (error + chroma_error);
2181           mv_ref[0].metric = error >> 2;
2182           mv_ref[0].chroma_metric = chroma_error >> 2;
2183           if (min_score > score) {
2184             best_error = error;
2185             best_chroma_error = chroma_error;
2186             best_entropy = entropy[0] + entropy[1];
2187             best_mv = mv_ref[0];
2188             min_score = score;
2189           }
2190         }
2191       }
2192       if (SCHRO_METRIC_INVALID == best_mv.metric) {
2193         block->valid = FALSE;
2194       } else {
2195         *mv = best_mv;
2196         total_error += best_error + best_chroma_error;
2197         total_entropy += best_entropy;
2198         block->mv[jj][ii] = best_mv;
2199         set_split1_motion (motion, i + ii, j + jj);
2200       }
2201     }
2202   }
2203   block->error = total_error;
2204   block->entropy = total_entropy;
2205   block->score = total_entropy + lambda * total_error;
2206 }
2207 
2208 static void
schro_get_best_split0_mv(SchroMe * me,int ref,int i,int j,SchroMotionVector * mv_ref,int * error,int * entropy,SchroFrameData * fd)2209 schro_get_best_split0_mv (SchroMe * me, int ref, int i, int j,
2210     SchroMotionVector * mv_ref, int *error, int *entropy, SchroFrameData * fd)
2211 {
2212   SchroMotionVector *hint_mv[6], *mv_motion;
2213   SchroMotionVector *mv, temp_mv = { 0 };
2214   SchroMotionField *mf;
2215   SchroParams *params = schro_me_params (me);
2216   SchroFrameData orig[3], ref_data[3];
2217   SchroFrame *frame = schro_me_src (me);
2218   SchroUpsampledFrame *upframe;
2219   SchroHierBm *hbm;
2220   SchroMotion *motion = schro_me_motion (me);
2221   int n = 0, m = 0, min_m = -1, metric = 0, ent;
2222   int mv_prec = params->mv_precision;
2223   int fd_width, fd_height, jj, ii;
2224   int k;
2225   double score, min_score = HUGE_VAL, lambda = schro_me_lambda (me);
2226   int width[3], height[3], dx, dy, xmin, xmax, ymin, ymax, tmp_x, tmp_y;
2227   int best_error = INT_MAX, best_chroma_error = INT_MAX, best_entropy = INT_MAX;
2228   int comp_w[3], comp_h[3];
2229   /* split2 block sizes for all components */
2230   int block_x[3], block_y[3];
2231 
2232   block_x[0] = params->xbsep_luma;
2233   block_y[0] = params->ybsep_luma;
2234   block_x[1] = block_x[2] =
2235       block_x[0] >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
2236       video_format->chroma_format);
2237   block_y[1] = block_y[2] =
2238       block_y[0] >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
2239       video_format->chroma_format);
2240   /* split0 block sizes for all components */
2241   comp_w[0] = block_x[0] << 2;
2242   comp_h[0] = block_y[0] << 2;
2243   comp_w[1] = comp_w[2] =
2244       comp_w[0] >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
2245       video_format->chroma_format);
2246   comp_h[1] = comp_h[2] =
2247       comp_h[0] >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
2248       video_format->chroma_format);
2249 
2250   xmin = -frame->extension;
2251   ymin = -frame->extension;
2252   xmax = (frame->width << mv_prec) + frame->extension;
2253   ymax = (frame->height << mv_prec) + frame->extension;
2254 
2255   /* get source data if possible */
2256   for (k = 0; 3 > k; ++k) {
2257     if (!schro_frame_get_data (frame, &orig[k], k, i * block_x[k],
2258             j * block_y[k])) {
2259       /* this should never happen */
2260       SCHRO_ASSERT (0);
2261     }
2262     width[k] = MIN (comp_w[k], orig[k].width);
2263     height[k] = MIN (comp_h[k], orig[k].height);
2264   }
2265   mv_motion = motion->motion_vectors + j * params->x_num_blocks + i;
2266 
2267   /* inherit from split 1 level MV */
2268   mf = schro_me_split1_mf (me, ref);
2269   SCHRO_ASSERT (mf);
2270   for (jj = 0; 4 > jj; jj += 2) {
2271     for (ii = 0; 4 > ii; ii += 2) {
2272       mv = mf->motion_vectors + (j + jj) * mf->x_num_blocks + i + ii;
2273       if (INT_MAX != mv->metric) {
2274         if ((0 < n && !mv_already_in_list (hint_mv, n, mv, ref, 0)) || 0 == n) {
2275           hint_mv[n++] = mv;
2276         }
2277       }
2278     }
2279   }
2280   /* inherit from stage 2 of hier. BM */
2281   hbm = schro_me_hbm (me, ref);
2282   SCHRO_ASSERT (hbm);
2283   mf = schro_hbm_motion_field (hbm, 2);
2284   mv = mf->motion_vectors + j * mf->x_num_blocks + i;
2285   if (INT_MAX != mv->metric) {
2286     if ((0 < n && !mv_already_in_list (hint_mv, n, mv, ref, mv_prec)) || 0 == n) {
2287       temp_mv = *mv;
2288       temp_mv.u.vec.dx[ref] <<= mv_prec;
2289       temp_mv.u.vec.dy[ref] <<= mv_prec;
2290       hint_mv[n++] = &temp_mv;
2291     }
2292   }
2293   /* now pick the best candidate */
2294   tmp_x = (i * params->xbsep_luma) << mv_prec;
2295   tmp_y = (j * params->ybsep_luma) << mv_prec;
2296   upframe = schro_me_ref (me, ref);
2297   for (m = 0; n > m; ++m) {
2298     int ok = TRUE;
2299     int chroma_metric = 0;
2300     for (k = 0; 3 > k; ++k) {
2301       tmp_x = (i * block_x[k]) << mv_prec;
2302       tmp_y = (j * block_y[k]) << mv_prec;
2303       dx = hint_mv[m]->u.vec.dx[ref];
2304       dx >>= 0 == k ? 0
2305           : SCHRO_CHROMA_FORMAT_H_SHIFT (params->video_format->chroma_format);
2306       dx += tmp_x;
2307       dy = hint_mv[m]->u.vec.dy[ref];
2308       dy >>= 0 == k ? 0
2309           : SCHRO_CHROMA_FORMAT_V_SHIFT (params->video_format->chroma_format);
2310       dy += tmp_y;
2311       if (0 == k && (xmin > dx || ymin > dy
2312               || !(xmax > dx + width[k] - 1) || !(ymax > dy + height[k] - 1))) {
2313         ok = FALSE;
2314         k = 3;
2315         continue;
2316       }
2317       if (ok) {
2318         /* I need to save the original values of fd width and height */
2319         fd_width = fd->width;
2320         fd_height = fd->height;
2321         fd->width = width[k];
2322         fd->height = height[k];
2323         schro_upsampled_frame_get_block_fast_precN (upframe, k, dx, dy, mv_prec,
2324             &ref_data[k], fd);
2325         fd->width = fd_width;
2326         fd->height = fd_height;
2327         if (0 == k) {
2328           metric =
2329               schro_metric_absdiff_u8 (orig[0].data, orig[0].stride,
2330               ref_data[0].data, ref_data[0].stride, width[0], height[0]);
2331         } else {
2332           chroma_metric +=
2333               schro_metric_absdiff_u8 (orig[k].data, orig[k].stride,
2334               ref_data[k].data, ref_data[k].stride, width[k], height[k]);
2335         }
2336       }
2337     }
2338     if (ok) {
2339       *mv_motion = *hint_mv[m];
2340       mv_motion->split = 0;
2341       mv_motion->pred_mode = ref + 1;
2342       ent = schro_motion_block_estimate_entropy (motion, i, j);
2343       score = ent + lambda * (metric + chroma_metric);
2344       if (min_score > score) {
2345         min_score = score;
2346         min_m = m;
2347         best_entropy = ent;
2348         best_error = metric;
2349         best_chroma_error = chroma_metric;
2350       }
2351     }
2352   }
2353   if (-1 < min_m) {
2354     *error = best_error + best_chroma_error;
2355     *entropy = best_entropy;
2356     *mv_ref = *hint_mv[min_m];
2357     mv_ref->metric = best_error >> 4;
2358     mv_ref->chroma_metric = best_chroma_error >> 4;
2359     mv_ref->split = 0;
2360     mv_ref->pred_mode = ref + 1;
2361   } else
2362     mv_ref->metric = INT_MAX;
2363 }
2364 
2365 static void
schro_do_split0_biref(SchroMe * me,int i,int j,SchroBlock * block,SchroFrameData * fd)2366 schro_do_split0_biref (SchroMe * me, int i, int j, SchroBlock * block,
2367     SchroFrameData * fd)
2368 {
2369   SchroParams *params = schro_me_params (me);
2370   int entropy = 0;
2371   SchroMotion *motion = schro_me_motion (me);
2372   SchroMotionVector *mv_motion;
2373   SchroFrame *orig_frame = schro_me_src (me);
2374   SchroFrameData ref_data[3][2], orig[3];
2375   SchroUpsampledFrame *upframe[2];
2376   double lambda = schro_me_lambda (me);
2377   int mv_prec = params->mv_precision;
2378   int width[3], height[3], dx[2], dy[2], tmp_x, tmp_y;
2379   int ref, error = INT_MAX;
2380   int xmin = -orig_frame->extension;
2381   int ymin = -orig_frame->extension;
2382   int xmax = (orig_frame->width << mv_prec) + orig_frame->extension;
2383   int ymax = (orig_frame->height << mv_prec) + orig_frame->extension;
2384   int biref, fd_width, fd_height;
2385   int k;
2386   /* split2 block sizes for all components */
2387   int block_x[3], block_y[3];
2388   int comp_w[3], comp_h[3];
2389   SchroMotionVector *mv;
2390 
2391 
2392   block->valid = FALSE;
2393 
2394   mv_motion = motion->motion_vectors + j * params->x_num_blocks + i;
2395 
2396   mv = &block->mv[0][0];
2397   mv->split = 0;
2398   mv->pred_mode = 3;
2399   mv->using_global = 0;
2400 
2401   *mv_motion = *mv;
2402   entropy = schro_motion_block_estimate_entropy (motion, i, j);
2403 
2404   block_x[0] = params->xbsep_luma;
2405   block_y[0] = params->ybsep_luma;
2406   block_x[1] = block_x[2] =
2407       block_x[0] >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
2408       video_format->chroma_format);
2409   block_y[1] = block_y[2] =
2410       block_y[0] >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
2411       video_format->chroma_format);
2412   /* split0 block sizes for all components */
2413   comp_w[0] = block_x[0] << 2;
2414   comp_h[0] = block_y[0] << 2;
2415   comp_w[1] = comp_w[2] =
2416       comp_w[0] >> SCHRO_CHROMA_FORMAT_H_SHIFT (params->
2417       video_format->chroma_format);
2418   comp_h[1] = comp_h[2] =
2419       comp_h[0] >> SCHRO_CHROMA_FORMAT_V_SHIFT (params->
2420       video_format->chroma_format);
2421 
2422   /* do biref, if available */
2423   biref = TRUE;
2424   /* fetch source data */
2425   for (k = 0; 3 > k; ++k) {
2426     if (schro_frame_get_data (orig_frame, &orig[k], k, i * block_x[k],
2427             j * block_y[k])) {
2428       width[k] = MIN (orig[k].width, comp_w[k]);
2429       height[k] = MIN (orig[k].height, comp_h[k]);
2430     } else {
2431       biref = FALSE;
2432       break;
2433     }
2434   }
2435   if (biref) {
2436     /* fetch reference data, if possible */
2437     for (ref = 0; params->num_refs > ref; ++ref) {
2438       for (k = 0; 3 > k && biref; ++k) {
2439         tmp_x = (i * block_x[k]) << mv_prec;
2440         tmp_y = (j * block_y[k]) << mv_prec;
2441         dx[ref] = mv->u.vec.dx[ref];
2442         dx[ref] >>= 0 == k ? 0
2443             : SCHRO_CHROMA_FORMAT_H_SHIFT (params->video_format->chroma_format);
2444         dx[ref] += tmp_x;
2445         dy[ref] = mv->u.vec.dy[ref];
2446         dy[ref] >>= 0 == k ? 0
2447             : SCHRO_CHROMA_FORMAT_V_SHIFT (params->video_format->chroma_format);
2448         dy[ref] += tmp_y;
2449         /* check whether we can extract reference blocks */
2450         if (0 == k && (xmin > dx[ref] || ymin > dy[ref]
2451                 || !(xmax > dx[ref] + width[k] - 1)
2452                 || !(ymax > dy[ref] + height[k] - 1))) {
2453           biref = FALSE;
2454           break;
2455         } else {
2456           fd_width = fd[ref].width;
2457           fd_height = fd[ref].height;
2458           fd[ref].width = width[k];
2459           fd[ref].height = height[k];
2460           upframe[ref] = schro_me_ref (me, ref);
2461           schro_upsampled_frame_get_block_fast_precN (upframe[ref], k, dx[ref],
2462               dy[ref], mv_prec, &ref_data[k][ref], &fd[ref]);
2463           fd[ref].width = fd_width;
2464           fd[ref].height = fd_height;
2465         }
2466       }
2467     }
2468     if (biref) {
2469       int chroma_error = 0;
2470       error =
2471           schro_metric_get_biref (&orig[0], &ref_data[0][0], 1, &ref_data[0][1],
2472           1, 1, width[0], height[0]);
2473       for (k = 1; 3 > k; ++k) {
2474         chroma_error +=
2475             schro_metric_get_biref (&orig[k], &ref_data[k][0], 1,
2476             &ref_data[k][1], 1, 1, width[k], height[k]);
2477       }
2478       mv->metric = error >> 4;
2479       mv->chroma_metric = chroma_error >> 4;
2480       block->entropy = entropy;
2481       block->error = error + chroma_error;
2482       block->score = block->entropy + lambda * block->error;
2483       block->valid = TRUE;
2484     }
2485   }
2486 }
2487 
2488 static void
schro_do_split0_biref_zero(SchroMe * me,int i,int j,SchroBlock * block,SchroFrameData * fd)2489 schro_do_split0_biref_zero (SchroMe * me, int i, int j, SchroBlock * block,
2490     SchroFrameData * fd)
2491 {
2492   SchroParams *params = schro_me_params (me);
2493   SchroMotionVector *mv;
2494 
2495   SCHRO_ASSERT (1 < params->num_refs);
2496 
2497   mv = &block->mv[0][0];
2498   mv->split = 0;
2499   mv->pred_mode = 3;
2500   mv->using_global = 0;
2501   mv->u.vec.dx[0] = 0;
2502   mv->u.vec.dy[0] = 0;
2503   mv->u.vec.dx[1] = 0;
2504   mv->u.vec.dy[1] = 0;
2505 
2506   schro_do_split0_biref (me, i, j, block, fd);
2507 }
2508 
2509 /* performs mode decision for a superblock, split level 0 */
2510 static void
schro_do_split0(SchroMe * me,int i,int j,SchroBlock * block,SchroFrameData * fd)2511 schro_do_split0 (SchroMe * me, int i, int j, SchroBlock * block,
2512     SchroFrameData * fd)
2513 {
2514   SchroParams *params = schro_me_params (me);
2515   SchroMotionField *mf;
2516   SchroMotionVector mv_ref[2], best_mv = { 0 }, *mv_split0;
2517   double lambda = schro_me_lambda (me);
2518   int ref;
2519   int error = INT_MAX;
2520   int entropy[2];
2521   int best_error = INT_MAX;
2522   int best_entropy = INT_MAX;
2523   double score, min_score = HUGE_VAL;
2524 
2525   best_mv.metric = INT_MAX;
2526 
2527   block->valid = FALSE;
2528 
2529   /* do the 2 references, if available */
2530   for (ref = 0; params->num_refs > ref; ++ref) {
2531     mf = schro_me_split0_mf (me, ref);
2532     SCHRO_ASSERT (mf);
2533     mv_split0 = mf->motion_vectors + j * params->x_num_blocks + i;
2534     schro_get_best_split0_mv (me, ref, i, j, &mv_ref[ref], &error,
2535         &entropy[ref], fd);
2536     *mv_split0 = mv_ref[ref];
2537     if (INT_MAX != mv_ref[ref].metric) {
2538       score = entropy[ref] + lambda * error;
2539       if (min_score > score) {
2540         min_score = score;
2541         best_mv = mv_ref[ref];
2542         best_entropy = entropy[ref];
2543         best_error = error;
2544       }
2545     }
2546   }
2547   /* do biref, if available */
2548   if (1 < params->num_refs
2549       && INT_MAX != mv_ref[0].metric && INT_MAX != mv_ref[1].metric) {
2550     SchroBlock biref_block = { 0 };
2551 
2552     SchroMotionVector *mv;
2553     mv = &biref_block.mv[0][0];
2554     mv->split = 0;
2555     mv->pred_mode = 3;
2556     mv->using_global = 0;
2557     mv->u.vec.dx[0] = mv_ref[0].u.vec.dx[0];
2558     mv->u.vec.dy[0] = mv_ref[0].u.vec.dy[0];
2559     mv->u.vec.dx[1] = mv_ref[1].u.vec.dx[1];
2560     mv->u.vec.dy[1] = mv_ref[1].u.vec.dy[1];
2561     mv->metric = INT_MAX;
2562 
2563     schro_do_split0_biref (me, i, j, &biref_block, fd);
2564 
2565     if (biref_block.valid && min_score > biref_block.score) {
2566       min_score = biref_block.score;
2567       best_mv = biref_block.mv[0][0];
2568       best_error = biref_block.error;
2569       best_entropy = biref_block.entropy;
2570     }
2571   }
2572 
2573   if (INT_MAX == best_mv.metric) {
2574     block->valid = FALSE;
2575   } else {
2576     block->valid = TRUE;
2577     block->error = best_error;
2578     block->entropy = best_entropy;
2579     block->score = best_entropy + lambda * best_error;
2580     block->mv[0][0] = best_mv;
2581   }
2582 }
2583 
2584 
2585 /* performs mode decision and block/superblock splitting */
2586 void
schro_mode_decision(SchroMe * me)2587 schro_mode_decision (SchroMe * me)
2588 {
2589   SchroParams *params = schro_me_params (me);
2590   SchroFrameData fd[2];
2591   SchroMotion *motion = schro_me_motion (me);
2592   int i, j, ref;
2593   double total_error = 0.0;
2594   int block_size;
2595   int badblocks = 0, dcblocks = 0;
2596   double min_score;
2597   int k, l;
2598 
2599   block_size = 16 * params->xbsep_luma * params->ybsep_luma;
2600   fd[0].data = fd[1].data = NULL;
2601   if (1 < params->mv_precision) {
2602     for (ref = 0; params->num_refs > ref; ++ref) {
2603       fd[ref].data = schro_malloc (block_size * sizeof (uint8_t));
2604       fd[ref].stride = fd[ref].width = params->xbsep_luma << 2;
2605       fd[ref].height = params->ybsep_luma << 2;
2606       fd[ref].length = block_size * sizeof (uint8_t);
2607       fd[ref].h_shift = fd[ref].v_shift = 0;
2608       fd[ref].format = SCHRO_FRAME_FORMAT_U8_420;
2609     }
2610   }
2611   /* we're now using chroma info for MS, increase block size accordingly */
2612   block_size = block_size * 2 / 3;
2613   /* loop over all superblocks. The indices are set to the value of the
2614    * top-left block in the SB, just like in Dave's bigblock estimation.
2615    * We'll start considering split 2 first, then split 1 and finally split 0 */
2616   for (j = 0; params->y_num_blocks > j; j += 4) {
2617     for (i = 0; params->x_num_blocks > i; i += 4) {
2618       SchroBlock block = { 0 }
2619       , tryblock = {
2620       0};
2621 
2622       schro_do_split2 (me, i, j, &block, fd);
2623       min_score = block.score;
2624 
2625       /* note: do_split1 writes to motion */
2626       schro_do_split1 (me, i, j, &tryblock, fd);
2627       if (tryblock.valid) {
2628         if (min_score > tryblock.score) {
2629           memcpy (&block, &tryblock, sizeof (block));
2630           schro_block_fixup (&block);
2631           /* I need to overwrite motion because it's needed to estimate
2632            * entropy at split 0 */
2633           schro_motion_copy_to (motion, i, j, &block);
2634           min_score = block.score;
2635           /* Note: only do split0 if split1 better than split2 */
2636           schro_do_split0 (me, i, j, &tryblock, fd);
2637           if (tryblock.valid) {
2638             if (min_score > tryblock.score) {
2639               memcpy (&block, &tryblock, sizeof (block));
2640               schro_block_fixup (&block);
2641             }
2642           }
2643         }
2644       }
2645       if (1 < params->num_refs) {
2646         schro_do_split0_biref_zero (me, i, j, &tryblock, fd);
2647         if (tryblock.valid) {
2648           if (min_score > tryblock.score) {
2649             memcpy (&block, &tryblock, sizeof (block));
2650             schro_block_fixup (&block);
2651           }
2652         }
2653       }
2654       schro_motion_copy_to (motion, i, j, &block);
2655       if (block.error > 10 * block_size) {
2656         ++badblocks;
2657       }
2658 
2659       for (k = 0; 4 > k; ++k) {
2660         for (l = 0; 4 > l; ++l) {
2661           if (0 == block.mv[k][l].pred_mode) {
2662             ++dcblocks;
2663           }
2664         }
2665       }
2666 
2667       total_error += (double) block.error * block.error /
2668           (double) (block_size * block_size);
2669     }
2670   }
2671 
2672   schro_me_set_mc_error (me,
2673       total_error / (240.0 * 240.0) /
2674       params->x_num_blocks * params->y_num_blocks / 16);
2675 
2676   schro_me_set_badblock_ratio (me,
2677       ((double) badblocks) / (params->x_num_blocks * params->y_num_blocks /
2678           16));
2679 
2680   schro_me_set_dcblock_ratio (me,
2681       ((double) dcblocks) / (params->x_num_blocks * params->y_num_blocks));
2682 
2683   if (1 < params->mv_precision) {
2684     for (ref = 0; params->num_refs > ref; ++ref) {
2685       schro_free (fd[ref].data);
2686     }
2687   }
2688 }
2689 
2690 struct SchroMeElement
2691 {
2692   SchroUpsampledFrame *ref;
2693 
2694   SchroMotionField *subpel_mf;
2695   SchroMotionField *split2_mf;
2696   SchroMotionField *split1_mf;
2697   SchroMotionField *split0_mf;
2698 
2699   SchroHierBm *hbm;
2700 };
2701 
2702 
2703 typedef struct SchroMeElement *SchroMeElement;
2704 
2705 /* supports motion estimation */
2706 struct _SchroMe
2707 {
2708   SchroFrame *src;
2709 
2710   SchroParams *params;
2711   double lambda;
2712   SchroMotion *motion;
2713 
2714   double mc_error;
2715   double badblocks_ratio;
2716   double dcblock_ratio;
2717 
2718   SchroMeElement meElement[2];
2719 };
2720 
2721 static SchroMeElement
schro_me_element_new(SchroEncoderFrame * frame,int ref_number)2722 schro_me_element_new (SchroEncoderFrame * frame, int ref_number)
2723 {
2724   SchroMeElement me;
2725 
2726   me = schro_malloc0 (sizeof (struct SchroMeElement));
2727 
2728   SCHRO_ASSERT (frame && (0 == ref_number || 1 == ref_number));
2729   SCHRO_ASSERT (me);
2730 
2731   me->ref = frame->ref_frame[ref_number]->upsampled_original_frame;
2732   me->hbm = schro_hbm_ref (frame->hier_bm[ref_number]);
2733   return me;
2734 }
2735 
2736 static void
schro_me_element_free(SchroMeElement * pme)2737 schro_me_element_free (SchroMeElement * pme)
2738 {
2739   SchroMeElement me = *pme;
2740 
2741   if (me) {
2742     if (me->hbm)
2743       schro_hbm_unref (me->hbm);
2744     if (me->subpel_mf)
2745       schro_motion_field_free (me->subpel_mf);
2746     if (me->split2_mf)
2747       schro_motion_field_free (me->split2_mf);
2748     if (me->split1_mf)
2749       schro_motion_field_free (me->split1_mf);
2750     if (me->split0_mf)
2751       schro_motion_field_free (me->split0_mf);
2752     schro_free (me);
2753     *pme = NULL;
2754   }
2755 }
2756 
2757 
2758 SchroMe *
schro_me_new(SchroEncoderFrame * frame)2759 schro_me_new (SchroEncoderFrame * frame)
2760 {
2761   int ref;
2762   SchroMe *me = schro_malloc0 (sizeof (struct _SchroMe));
2763 
2764   SCHRO_ASSERT (me);
2765 
2766   me->src = frame->filtered_frame;
2767   me->params = &frame->params;
2768   me->motion = frame->motion;
2769   me->lambda = frame->frame_me_lambda;
2770   for (ref = 0; me->params->num_refs > ref; ++ref) {
2771     me->meElement[ref] = schro_me_element_new (frame, ref);
2772   }
2773   return me;
2774 }
2775 
2776 void
schro_me_free(SchroMe * me)2777 schro_me_free (SchroMe * me)
2778 {
2779   int ref;
2780 
2781   if (me) {
2782     for (ref = 0; me->params->num_refs > ref; ++ref) {
2783       schro_me_element_free (&me->meElement[ref]);
2784     }
2785   }
2786   schro_free (me);
2787 }
2788 
2789 SchroFrame *
schro_me_src(SchroMe * me)2790 schro_me_src (SchroMe * me)
2791 {
2792   SCHRO_ASSERT (me);
2793   return me->src;
2794 }
2795 
2796 SchroUpsampledFrame *
schro_me_ref(SchroMe * me,int ref_number)2797 schro_me_ref (SchroMe * me, int ref_number)
2798 {
2799   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2800   return me->meElement[ref_number]->ref;
2801 }
2802 
2803 SchroMotionField *
schro_me_subpel_mf(SchroMe * me,int ref_number)2804 schro_me_subpel_mf (SchroMe * me, int ref_number)
2805 {
2806   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2807   return me->meElement[ref_number]->subpel_mf;
2808 }
2809 
2810 void
schro_me_set_subpel_mf(SchroMe * me,SchroMotionField * mf,int ref_number)2811 schro_me_set_subpel_mf (SchroMe * me, SchroMotionField * mf, int ref_number)
2812 {
2813   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2814   me->meElement[ref_number]->subpel_mf = mf;
2815 }
2816 
2817 SchroMotionField *
schro_me_split2_mf(SchroMe * me,int ref_number)2818 schro_me_split2_mf (SchroMe * me, int ref_number)
2819 {
2820   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2821   return me->meElement[ref_number]->split2_mf;
2822 }
2823 
2824 void
schro_me_set_split2_mf(SchroMe * me,SchroMotionField * mf,int ref_number)2825 schro_me_set_split2_mf (SchroMe * me, SchroMotionField * mf, int ref_number)
2826 {
2827   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2828   me->meElement[ref_number]->split2_mf = mf;
2829 }
2830 
2831 SchroMotionField *
schro_me_split1_mf(SchroMe * me,int ref_number)2832 schro_me_split1_mf (SchroMe * me, int ref_number)
2833 {
2834   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2835   return me->meElement[ref_number]->split1_mf;
2836 }
2837 
2838 void
schro_me_set_split1_mf(SchroMe * me,SchroMotionField * mf,int ref_number)2839 schro_me_set_split1_mf (SchroMe * me, SchroMotionField * mf, int ref_number)
2840 {
2841   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2842   me->meElement[ref_number]->split1_mf = mf;
2843 }
2844 
2845 SchroMotionField *
schro_me_split0_mf(SchroMe * me,int ref_number)2846 schro_me_split0_mf (SchroMe * me, int ref_number)
2847 {
2848   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2849   return me->meElement[ref_number]->split0_mf;
2850 }
2851 
2852 void
schro_me_set_split0_mf(SchroMe * me,SchroMotionField * mf,int ref_number)2853 schro_me_set_split0_mf (SchroMe * me, SchroMotionField * mf, int ref_number)
2854 {
2855   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2856   me->meElement[ref_number]->split0_mf = mf;
2857 }
2858 
2859 SchroHierBm *
schro_me_hbm(SchroMe * me,int ref_number)2860 schro_me_hbm (SchroMe * me, int ref_number)
2861 {
2862   SCHRO_ASSERT (me && (0 == ref_number || 1 == ref_number));
2863   return me->meElement[ref_number]->hbm;
2864 }
2865 
2866 void
schro_me_set_lambda(SchroMe * me,double lambda)2867 schro_me_set_lambda (SchroMe * me, double lambda)
2868 {
2869   SCHRO_ASSERT (me);
2870   me->lambda = lambda;
2871 }
2872 
2873 double
schro_me_lambda(SchroMe * me)2874 schro_me_lambda (SchroMe * me)
2875 {
2876   SCHRO_ASSERT (me);
2877   return me->lambda;
2878 }
2879 
2880 SchroParams *
schro_me_params(SchroMe * me)2881 schro_me_params (SchroMe * me)
2882 {
2883   SCHRO_ASSERT (me);
2884   return me->params;
2885 }
2886 
2887 SchroMotion *
schro_me_motion(SchroMe * me)2888 schro_me_motion (SchroMe * me)
2889 {
2890   SCHRO_ASSERT (me);
2891   return me->motion;
2892 }
2893 
2894 void
schro_me_set_motion(SchroMe * me,SchroMotion * motion)2895 schro_me_set_motion (SchroMe * me, SchroMotion * motion)
2896 {
2897   SCHRO_ASSERT (me);
2898   me->motion = motion;
2899 }
2900 
2901 void
schro_me_set_mc_error(SchroMe * me,double mc_error)2902 schro_me_set_mc_error (SchroMe * me, double mc_error)
2903 {
2904   SCHRO_ASSERT (me);
2905   me->mc_error = mc_error;
2906 }
2907 
2908 double
schro_me_mc_error(SchroMe * me)2909 schro_me_mc_error (SchroMe * me)
2910 {
2911   SCHRO_ASSERT (me);
2912   return me->mc_error;
2913 }
2914 
2915 void
schro_me_set_badblock_ratio(SchroMe * me,double badblocks_ratio)2916 schro_me_set_badblock_ratio (SchroMe * me, double badblocks_ratio)
2917 {
2918   SCHRO_ASSERT (me);
2919   me->badblocks_ratio = badblocks_ratio;
2920 }
2921 
2922 double
schro_me_badblocks_ratio(SchroMe * me)2923 schro_me_badblocks_ratio (SchroMe * me)
2924 {
2925   SCHRO_ASSERT (me);
2926   return me->badblocks_ratio;
2927 }
2928 
2929 void
schro_me_set_dcblock_ratio(SchroMe * me,double dcblock_ratio)2930 schro_me_set_dcblock_ratio (SchroMe * me, double dcblock_ratio)
2931 {
2932   SCHRO_ASSERT (me);
2933   me->dcblock_ratio = dcblock_ratio;
2934 }
2935 
2936 double
schro_me_dcblock_ratio(SchroMe * me)2937 schro_me_dcblock_ratio (SchroMe * me)
2938 {
2939   SCHRO_ASSERT (me);
2940   return me->dcblock_ratio;
2941 }
2942