~ubuntu-branches/ubuntu/lucid/schroedinger/lucid

« back to all changes in this revision

Viewing changes to schroedinger/schromotionest.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2008-03-16 18:26:29 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20080316182629-6ofrq5h72ddrl1oo
Tags: 1.0.1-2
* debian/patches/01_no-x86-opcodes.patch:
  + Don't use x86 opcodes, these obviously don't work on non-x86 archs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#define DC_METRIC 50
13
13
#define BIDIR_LIMIT (10*8*8)
14
14
 
 
15
#define SCHRO_METRIC_INVALID_2 0x7fffffff
 
16
 
15
17
#define motion_field_get(mf,x,y) \
16
18
  ((mf)->motion_vectors + (y)*(mf)->x_num_blocks + (x))
17
19
 
18
20
void schro_encoder_bigblock_estimation (SchroMotionEst *me);
19
 
void schro_encoder_bigblock2_estimation (SchroMotionEst *me);
20
 
void schro_encoder_hierarchical_estimation (SchroMotionEst *me);
21
 
void schro_encoder_zero_estimation (SchroMotionEst *me);
22
 
void schro_encoder_dc_estimation (SchroMotionEst *me);
23
 
void schro_encoder_fullscan_estimation (SchroMotionEst *me);
24
21
void schro_motion_field_set (SchroMotionField *field, int split, int pred_mode);
25
22
void schro_motion_global_metric (SchroMotionField *mf, SchroFrame *frame,
26
23
    SchroFrame *ref);
29
26
void schro_motionest_rough_scan_hint (SchroMotionEst *me,
30
27
    int shift, int ref, int distance);
31
28
 
32
 
void schro_motion_merge (SchroMotion *motion, SchroList *_list);
33
 
void schro_motion_cleanup (SchroMotion *motion, int x, int y);
34
 
void schro_motion_combine (SchroMotion *motion);
35
 
#if 0
 
29
#ifdef unused
36
30
void schro_motion_predict_subpixel (SchroMotion *motion, SchroFrame *frame,
37
31
    SchroMotionField *mf);
38
32
#endif
39
33
void schro_motion_calculate_stats (SchroMotion *motion, SchroEncoderFrame *frame);
40
34
 
 
35
#ifdef unused
41
36
static void motion_field_splat_4x4 (SchroMotionField *mf, int i, int j);
42
 
#if 0
43
37
static void motion_field_splat_2x2 (SchroMotionField *mf, int i, int j);
44
38
#endif
45
39
 
55
49
  me->encoder_frame = frame;
56
50
  me->params = &frame->params;
57
51
 
58
 
  me->src0 = frame->ref_frame0->reconstructed_frame;
59
 
  me->downsampled_src0[0] = frame->ref_frame0->filtered_frame;
60
 
  me->downsampled_src0[1] = frame->ref_frame0->downsampled_frames[0];
61
 
  me->downsampled_src0[2] = frame->ref_frame0->downsampled_frames[1];
62
 
  me->downsampled_src0[3] = frame->ref_frame0->downsampled_frames[2];
63
 
  me->downsampled_src0[4] = frame->ref_frame0->downsampled_frames[3];
 
52
  me->src0 = frame->ref_frame[0]->reconstructed_frame;
 
53
  me->downsampled_src0[0] = frame->ref_frame[0]->filtered_frame;
 
54
  me->downsampled_src0[1] = frame->ref_frame[0]->downsampled_frames[0];
 
55
  me->downsampled_src0[2] = frame->ref_frame[0]->downsampled_frames[1];
 
56
  me->downsampled_src0[3] = frame->ref_frame[0]->downsampled_frames[2];
 
57
  me->downsampled_src0[4] = frame->ref_frame[0]->downsampled_frames[3];
64
58
 
65
59
  if (me->params->num_refs > 1) {
66
 
    me->src1 = frame->ref_frame1->reconstructed_frame;
67
 
    me->downsampled_src1[0] = frame->ref_frame1->filtered_frame;
68
 
    me->downsampled_src1[1] = frame->ref_frame1->downsampled_frames[0];
69
 
    me->downsampled_src1[2] = frame->ref_frame1->downsampled_frames[1];
70
 
    me->downsampled_src1[3] = frame->ref_frame1->downsampled_frames[2];
71
 
    me->downsampled_src1[4] = frame->ref_frame1->downsampled_frames[3];
 
60
    me->src1 = frame->ref_frame[1]->reconstructed_frame;
 
61
    me->downsampled_src1[0] = frame->ref_frame[1]->filtered_frame;
 
62
    me->downsampled_src1[1] = frame->ref_frame[1]->downsampled_frames[0];
 
63
    me->downsampled_src1[2] = frame->ref_frame[1]->downsampled_frames[1];
 
64
    me->downsampled_src1[3] = frame->ref_frame[1]->downsampled_frames[2];
 
65
    me->downsampled_src1[4] = frame->ref_frame[1]->downsampled_frames[3];
72
66
  }
73
67
 
74
68
  n = params->x_num_blocks * params->y_num_blocks / 16;
105
99
  SchroParams *params = &frame->params;
106
100
  SchroMotionEst *me;
107
101
  int n;
 
102
  int ref;
108
103
 
109
104
  SCHRO_ASSERT(params->x_num_blocks != 0);
110
105
  SCHRO_ASSERT(params->y_num_blocks != 0);
113
108
  me = schro_motionest_new (frame);
114
109
 
115
110
  frame->motion = schro_motion_new (params,
116
 
      frame->ref_frame0->reconstructed_frame,
117
 
      (params->num_refs > 1) ? frame->ref_frame1->reconstructed_frame : NULL);
 
111
      frame->ref_frame[0]->reconstructed_frame,
 
112
      (params->num_refs > 1) ? frame->ref_frame[1]->reconstructed_frame : NULL);
118
113
  me->motion = frame->motion;
119
114
 
120
115
  frame->motion_field_list = schro_list_new_full ((SchroListFreeFunc)schro_motion_field_free, NULL);
121
116
  n = 0;
122
117
 
123
 
  if (frame->encoder->enable_bigblock_estimation) {
124
 
    int ref;
125
 
 
126
 
    for(ref=0;ref<params->num_refs;ref++){
127
 
      schro_motionest_rough_scan_nohint (me, 3, ref, 12);
128
 
      schro_motionest_rough_scan_hint (me, 2, ref, 2);
129
 
      schro_motionest_rough_scan_hint (me, 1, ref, 2);
130
 
    }
131
 
 
132
 
    //schro_encoder_bigblock_estimation (me);
133
 
    schro_encoder_bigblock2_estimation (me);
134
 
  } else {
135
 
    schro_encoder_dc_estimation (me);
136
 
 
 
118
  for(ref=0;ref<params->num_refs;ref++){
 
119
    schro_motionest_rough_scan_nohint (me, 3, ref, 12);
 
120
    schro_motionest_rough_scan_hint (me, 2, ref, 2);
 
121
    schro_motionest_rough_scan_hint (me, 1, ref, 2);
 
122
  }
 
123
 
 
124
  schro_encoder_bigblock_estimation (me);
 
125
 
 
126
#if 0
137
127
    if (frame->encoder->enable_phasecorr_estimation) {
138
128
      schro_encoder_phasecorr_estimation (me);
139
129
    }
140
 
 
141
 
    if (frame->encoder->enable_hierarchical_estimation) {
142
 
      schro_encoder_hierarchical_estimation (me);
143
 
    }
144
 
 
145
 
    if (frame->encoder->enable_zero_estimation) {
146
 
      schro_encoder_zero_estimation (me);
147
 
    }
148
 
 
149
 
    if (frame->encoder->enable_fullscan_estimation) {
150
 
      schro_encoder_fullscan_estimation (me);
151
 
    }
152
 
 
153
130
    if (params->have_global_motion) {
154
131
      schro_encoder_global_estimation (me);
155
 
    }
156
 
 
157
 
    schro_motion_merge (frame->motion, frame->motion_field_list);
158
 
    schro_motion_cleanup (frame->motion,
159
 
        (params->video_format->width + params->xbsep_luma - 1)/params->xbsep_luma,
160
 
        (params->video_format->height + params->ybsep_luma - 1)/params->ybsep_luma);
161
 
 
162
 
    schro_motion_combine (frame->motion);
163
 
  }
 
132
#endif
164
133
 
165
134
  schro_motion_calculate_stats (frame->motion, frame);
166
135
  frame->estimated_mc_bits = schro_motion_estimate_entropy (frame->motion);
171
140
}
172
141
 
173
142
void
174
 
schro_motion_merge (SchroMotion *motion, SchroList *list)
175
 
{
176
 
  int i,j,k;
177
 
  SchroMotionVector *mv;
178
 
  SchroMotionVector *mvk;
179
 
  SchroMotionField **fields = (SchroMotionField **)list->members;
180
 
  int n = schro_list_get_size (list);
181
 
 
182
 
  for(k=0;k<n;k++){
183
 
    SCHRO_ASSERT(fields[k]->x_num_blocks == motion->params->x_num_blocks);
184
 
    SCHRO_ASSERT(fields[k]->y_num_blocks == motion->params->y_num_blocks);
185
 
  }
186
 
 
187
 
  for(j=0;j<motion->params->y_num_blocks;j++){
188
 
    for(i=0;i<motion->params->x_num_blocks;i++){
189
 
      mv = SCHRO_MOTION_GET_BLOCK(motion,i,j);
190
 
 
191
 
      mvk = &fields[0]->motion_vectors[j*motion->params->x_num_blocks + i];
192
 
      *mv = *mvk;
193
 
      for(k=1;k<n;k++){
194
 
        mvk = &fields[k]->motion_vectors[j*motion->params->x_num_blocks + i];
195
 
        if (mvk->metric < mv->metric) {
196
 
          *mv = *mvk;
197
 
        }
198
 
      }
199
 
      if (mv->pred_mode == 2) {
200
 
        mv->dx[1] = mv->dx[0];
201
 
        mv->dy[1] = mv->dy[0];
202
 
      }
203
 
      SCHRO_ASSERT (!(mv->pred_mode == 0 && mv->using_global));
204
 
    }
205
 
  }
206
 
}
207
 
 
208
 
void
209
 
schro_motion_cleanup (SchroMotion *motion, int x_blocks, int y_blocks)
210
 
{
211
 
  int i,j;
212
 
  SchroMotionVector *mv;
213
 
 
214
 
  SCHRO_DEBUG("motion field cleanup %dx%d to %dx%d",
215
 
      x_blocks, y_blocks,
216
 
      motion->params->x_num_blocks, motion->params->y_num_blocks);
217
 
  if (x_blocks < motion->params->x_num_blocks) {
218
 
    for(j=0;j<motion->params->y_num_blocks;j++){
219
 
      for(i=x_blocks;i<motion->params->x_num_blocks;i++){
220
 
        mv = SCHRO_MOTION_GET_BLOCK(motion,i,j);
221
 
        *mv = *SCHRO_MOTION_GET_BLOCK(motion,i-1,j);
222
 
      }
223
 
    }
224
 
  }
225
 
  if (y_blocks < motion->params->y_num_blocks) {
226
 
    for(j=y_blocks;j<motion->params->y_num_blocks;j++){
227
 
      for(i=0;i<motion->params->x_num_blocks;i++){
228
 
        mv = SCHRO_MOTION_GET_BLOCK(motion,i,j);
229
 
        *mv = *SCHRO_MOTION_GET_BLOCK(motion,i,j-1);
230
 
      }
231
 
    }
232
 
  }
233
 
}
234
 
 
235
 
void
236
 
schro_motion_combine (SchroMotion *motion)
237
 
{
238
 
  int i,j,k,l;
239
 
  SchroMotionVector *mv;
240
 
  SchroMotionVector *mv2;
241
 
 
242
 
  for(j=0;j<motion->params->y_num_blocks;j+=4){
243
 
    for(i=0;i<motion->params->x_num_blocks;i+=4){
244
 
      mv = SCHRO_MOTION_GET_BLOCK(motion,i,j);
245
 
      if (mv->pred_mode == 0) {
246
 
#if 0
247
 
        int dc[3] = { 0, 0, 0 };
248
 
        for(k=0;k<4;k++){
249
 
          for(l=0;l<4;l++){
250
 
            if (mv[k*mf->x_num_blocks + l].pred_mode != 0) goto next_mb;
251
 
            dc[0] += mv[k*mf->x_num_blocks + l].u.dc[0];
252
 
            dc[1] += mv[k*mf->x_num_blocks + l].u.dc[1];
253
 
            dc[2] += mv[k*mf->x_num_blocks + l].u.dc[2];
254
 
          }
255
 
        }
256
 
        mv->split = 0;
257
 
        mv->u.dc[0] = (dc[0] + 8)>>4;
258
 
        mv->u.dc[1] = (dc[1] + 8)>>4;
259
 
        mv->u.dc[2] = (dc[2] + 8)>>4;
260
 
#else
261
 
        continue;
262
 
#endif
263
 
      } else if (mv->using_global) {
264
 
        for(k=0;k<4;k++){
265
 
          for(l=0;l<4;l++){
266
 
            mv2 = SCHRO_MOTION_GET_BLOCK(motion,i+k,j+l);
267
 
            if (!mv2->using_global ||
268
 
                mv2->pred_mode != mv->pred_mode) {
269
 
              goto next_mb;
270
 
            }
271
 
          }
272
 
        }
273
 
        mv->split = 0;
274
 
      } else {
275
 
        goto next_mb;
276
 
      }
277
 
 
278
 
      for(k=0;k<4;k++){
279
 
        for(l=0;l<4;l++){
280
 
          mv2 = SCHRO_MOTION_GET_BLOCK(motion,i+k,j+l);
281
 
          if (mv != mv2) {
282
 
            *mv2 = *mv;
283
 
          }
284
 
        }
285
 
      }
286
 
next_mb:
287
 
      do {} while (0);
288
 
    }
289
 
  }
290
 
}
291
 
 
292
 
void
293
143
schro_motion_field_lshift (SchroMotionField *mf, int n)
294
144
{
295
145
  int i,j;
418
268
    if (i == 0) {
419
269
      schro_motion_global_metric (mf,
420
270
          me->encoder_frame->filtered_frame,
421
 
          me->encoder_frame->ref_frame0->filtered_frame);
 
271
          me->encoder_frame->ref_frame[0]->filtered_frame);
422
272
    } else {
423
273
      schro_motion_global_metric (mf, me->encoder_frame->filtered_frame,
424
 
          me->encoder_frame->ref_frame1->filtered_frame);
 
274
          me->encoder_frame->ref_frame[1]->filtered_frame);
425
275
    }
426
276
    schro_list_append (me->encoder_frame->motion_field_list, mf);
427
277
  }
804
654
  }
805
655
 
806
656
  if (n == 0) {
807
 
    return SCHRO_METRIC_INVALID;
 
657
    return SCHRO_METRIC_INVALID_2;
808
658
  }
809
659
 
810
660
  ave = (sum + n/2)/n;
898
748
  return metric;
899
749
}
900
750
 
901
 
void
902
 
schro_encoder_hierarchical_estimation (SchroMotionEst *me)
903
 
{
904
 
  SchroParams *params = me->params;
905
 
  int ref;
906
 
  int x_blocks;
907
 
  int y_blocks;
908
 
  SchroFrame *downsampled_ref;
909
 
  SchroFrame *downsampled_frame;
910
 
  int shift;
911
 
  SchroMotionField *mf;
912
 
  SchroMotionField *parent_mf = NULL;
913
 
  SchroMotionField *mf1 = NULL;
914
 
  SchroMotionField *mf2 = NULL;
915
 
 
916
 
  for(ref=0;ref<params->num_refs;ref++){
917
 
 
918
 
    shift = 3;
919
 
    if (ref == 0) {
920
 
      downsampled_ref = get_downsampled(me->encoder_frame->ref_frame0,shift);
921
 
    } else {
922
 
      downsampled_ref = get_downsampled(me->encoder_frame->ref_frame1,shift);
923
 
    }
924
 
    downsampled_frame = get_downsampled(me->encoder_frame,shift);
925
 
 
926
 
    x_blocks = params->x_num_blocks>>shift;
927
 
    y_blocks = params->y_num_blocks>>shift;
928
 
    parent_mf = schro_motion_field_new (x_blocks, y_blocks);
929
 
 
930
 
    schro_motion_field_set (parent_mf, 2, 1<<ref);
931
 
    schro_motion_field_scan (parent_mf, params, downsampled_frame, downsampled_ref,
932
 
        12);
933
 
 
934
 
    for(shift=2;shift>=0;shift--) {
935
 
      int i,j;
936
 
      SchroMotionVector *mv;
937
 
 
938
 
      x_blocks = params->x_num_blocks>>shift;
939
 
      y_blocks = params->y_num_blocks>>shift;
940
 
 
941
 
      mf = schro_motion_field_new (x_blocks, y_blocks);
942
 
 
943
 
      if (ref == 0) {
944
 
        downsampled_ref = get_downsampled(me->encoder_frame->ref_frame0,shift);
945
 
      } else {
946
 
        downsampled_ref = get_downsampled(me->encoder_frame->ref_frame1,shift);
947
 
      }
948
 
      downsampled_frame = get_downsampled(me->encoder_frame,shift);
949
 
 
950
 
      for(j=0;j<mf->y_num_blocks;j++){
951
 
        for(i=0;i<mf->x_num_blocks;i++){
952
 
#define LIST_LENGTH 20
953
 
          int list_x[LIST_LENGTH], list_y[LIST_LENGTH];
954
 
          int n = 0;
955
 
          int l, k;
956
 
          int x, y;
957
 
          int metric;
958
 
 
959
 
          /* always test the zero vector */
960
 
          list_x[n] = 0;
961
 
          list_y[n] = 0;
962
 
          n++;
963
 
 
964
 
          /* inherit from parent */
965
 
          for(k=0;k<4;k++){
966
 
            int l = (i-1+2*(k&1))>>1;
967
 
            int m = (j-1+(k&2))>>1;
968
 
            if (l >= 0 && l < parent_mf->x_num_blocks &&
969
 
                m >= 0 && m < parent_mf->y_num_blocks) {
970
 
              mv = motion_field_get(parent_mf, l, m);
971
 
              list_x[n] = mv->dx[0] * 2;
972
 
              list_y[n] = mv->dy[0] * 2;
973
 
              n++;
974
 
            }
975
 
          }
976
 
 
977
 
          /* inherit from neighbors (only towards SE) */
978
 
          if (i > 0) {
979
 
            mv = motion_field_get (mf, i-1, j);
980
 
            list_x[n] = mv->dx[0];
981
 
            list_y[n] = mv->dy[0];
982
 
            n++;
983
 
          }
984
 
          if (j > 0) {
985
 
            mv = motion_field_get (mf, i, j-1);
986
 
            list_x[n] = mv->dx[0];
987
 
            list_y[n] = mv->dy[0];
988
 
            n++;
989
 
          }
990
 
          if (i > 0 && j > 0) {
991
 
            mv = motion_field_get (mf, i-1, j-1);
992
 
            list_x[n] = mv->dx[0];
993
 
            list_y[n] = mv->dy[0];
994
 
            n++;
995
 
          }
996
 
          
997
 
          SCHRO_ASSERT(n<=LIST_LENGTH);
998
 
          metric = schro_frame_get_metric (downsampled_frame,
999
 
              i * 8, j * 8, downsampled_ref, i*8 + list_x[0],
1000
 
              j*8 + list_y[0]);
1001
 
          x = list_x[0];
1002
 
          y = list_y[0];
1003
 
          for (l = 1; l < n; l++) {
1004
 
            int m;
1005
 
 
1006
 
            m = schro_frame_get_metric (downsampled_frame,
1007
 
                i * 8, j * 8, downsampled_ref, i*8 + list_x[l],
1008
 
                j*8 + list_y[l]);
1009
 
            if (m < metric) {
1010
 
              metric = m;
1011
 
              x = list_x[l];
1012
 
              y = list_y[l];
1013
 
            }
1014
 
          }
1015
 
 
1016
 
          mv = motion_field_get (mf, i, j);
1017
 
          mv->dx[0] = x;
1018
 
          mv->dy[0] = y;
1019
 
          mv->metric = metric;
1020
 
          mv->split = 2;
1021
 
          mv->pred_mode = (1<<ref);
1022
 
        }
1023
 
      }
1024
 
 
1025
 
      schro_motion_field_scan (mf, params, downsampled_frame, downsampled_ref, 4);
1026
 
 
1027
 
      schro_motion_field_free (parent_mf);
1028
 
      parent_mf = mf;
1029
 
    }
1030
 
 
1031
 
    schro_motion_field_lshift (parent_mf, params->mv_precision);
1032
 
#if 0
1033
 
    schro_motion_predict_subpixel (frame->motion, frame->filtered_frame,
1034
 
        parent_mf);
1035
 
#endif
1036
 
    schro_list_append (me->encoder_frame->motion_field_list, parent_mf);
1037
 
    
1038
 
    if (ref == 0) {
1039
 
      mf1 = parent_mf;
1040
 
    } else {
1041
 
      mf2 = parent_mf;
1042
 
    }
1043
 
  }
1044
 
 
1045
 
  if (params->num_refs == 2) {
1046
 
    int i,j;
1047
 
    SchroMotionVector *mv;
1048
 
    SchroMotionVector *mv1;
1049
 
    SchroMotionVector *mv2;
1050
 
 
1051
 
    mf = schro_motion_field_new (params->x_num_blocks, params->y_num_blocks);
1052
 
    for(j=0;j<mf->y_num_blocks;j++){
1053
 
      for(i=0;i<mf->x_num_blocks;i++){
1054
 
        mv = motion_field_get (mf, i, j);
1055
 
        mv1 = motion_field_get (mf1, i, j);
1056
 
        mv2 = motion_field_get (mf2, i, j);
1057
 
 
1058
 
        *mv = *mv1;
1059
 
        mv->pred_mode = 3;
1060
 
        mv->dx[1] = mv2->dx[0];
1061
 
        mv->dy[1] = mv2->dy[0];
1062
 
        if (mv1->metric < BIDIR_LIMIT && mv2->metric < BIDIR_LIMIT) {
1063
 
          mv->metric = MIN(mv1->metric, mv2->metric) - 1;
1064
 
        } else {
1065
 
          mv->metric = 32000;
1066
 
        }
1067
 
      }
1068
 
    }
1069
 
    schro_list_append (me->encoder_frame->motion_field_list, mf);
1070
 
  }
1071
 
}
1072
 
 
1073
 
void
1074
 
schro_encoder_zero_estimation (SchroMotionEst *me)
1075
 
{
1076
 
  SchroParams *params = me->params;
1077
 
  int ref;
1078
 
  int x_blocks;
1079
 
  int y_blocks;
1080
 
  SchroFrame *downsampled_ref;
1081
 
  SchroFrame *downsampled_frame;
1082
 
  SchroMotionField *mf;
1083
 
 
1084
 
  for(ref=0;ref<params->num_refs;ref++){
1085
 
    int i,j;
1086
 
    SchroMotionVector *mv;
1087
 
 
1088
 
    x_blocks = params->x_num_blocks;
1089
 
    y_blocks = params->y_num_blocks;
1090
 
 
1091
 
    mf = schro_motion_field_new (x_blocks, y_blocks);
1092
 
 
1093
 
    if (ref == 0) {
1094
 
      downsampled_ref = get_downsampled(me->encoder_frame->ref_frame0,0);
1095
 
    } else {
1096
 
      downsampled_ref = get_downsampled(me->encoder_frame->ref_frame1,0);
1097
 
    }
1098
 
    downsampled_frame = get_downsampled(me->encoder_frame,0);
1099
 
 
1100
 
    for(j=0;j<mf->y_num_blocks;j++){
1101
 
      for(i=0;i<mf->x_num_blocks;i++){
1102
 
        int metric;
1103
 
        
1104
 
        metric = schro_frame_get_metric (downsampled_frame,
1105
 
            i * params->xbsep_luma, j * params->ybsep_luma,
1106
 
            downsampled_ref, i*params->xbsep_luma, j*params->ybsep_luma);
1107
 
 
1108
 
        mv = motion_field_get (mf, i, j);
1109
 
        mv->dx[0] = 0;
1110
 
        mv->dy[0] = 0;
1111
 
        mv->metric = metric;
1112
 
        mv->split = 2;
1113
 
        mv->pred_mode = (1<<ref);
1114
 
      }
1115
 
    }
1116
 
 
1117
 
    schro_motion_field_lshift (mf, params->mv_precision);
1118
 
    schro_list_append (me->encoder_frame->motion_field_list, mf);
1119
 
  }
1120
 
}
1121
 
 
1122
 
void
1123
 
schro_encoder_fullscan_estimation (SchroMotionEst *me)
1124
 
{
1125
 
  SchroParams *params = me->params;
1126
 
  int ref;
1127
 
  SchroFrame *downsampled_ref;
1128
 
  SchroFrame *downsampled_frame;
1129
 
  SchroMotionField *mf;
1130
 
 
1131
 
  for(ref=0;ref<params->num_refs;ref++){
1132
 
    mf = schro_motion_field_new (params->x_num_blocks, params->y_num_blocks);
1133
 
 
1134
 
    if (ref == 0) {
1135
 
      downsampled_ref = get_downsampled(me->encoder_frame->ref_frame0,0);
1136
 
    } else {
1137
 
      downsampled_ref = get_downsampled(me->encoder_frame->ref_frame1,0);
1138
 
    }
1139
 
    downsampled_frame = get_downsampled(me->encoder_frame,0);
1140
 
 
1141
 
    schro_motion_field_set (mf, 2, (1<<ref));
1142
 
    schro_motion_field_scan (mf, params, downsampled_frame,
1143
 
        downsampled_ref, 20);
1144
 
 
1145
 
    schro_motion_field_lshift (mf, params->mv_precision);
1146
 
    schro_list_append (me->encoder_frame->motion_field_list, mf);
1147
 
  }
1148
 
}
1149
 
 
1150
751
 
1151
752
void
1152
753
schro_motionest_rough_scan_nohint (SchroMotionEst *me, int shift, int ref,
1161
762
  int skip;
1162
763
 
1163
764
  scan.frame = get_downsampled (me->encoder_frame, shift);
1164
 
  if (ref == 0) {
1165
 
    scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame0, shift);
1166
 
  } else {
1167
 
    scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame1, shift);
1168
 
  }
 
765
  scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], shift);
1169
766
 
1170
767
  mf = schro_motion_field_new (params->x_num_blocks, params->y_num_blocks);
1171
768
 
1223
820
  unsigned int hint_mask;
1224
821
 
1225
822
  scan.frame = get_downsampled (me->encoder_frame, shift);
1226
 
  if (ref == 0) {
1227
 
    scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame0, shift);
1228
 
  } else {
1229
 
    scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame1, shift);
1230
 
  }
 
823
  scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], shift);
1231
824
 
1232
825
  mf = schro_motion_field_new (params->x_num_blocks, params->y_num_blocks);
1233
826
  hint_mf = me->downsampled_mf[ref][shift+1];
1248
841
    for(i=0;i<params->x_num_blocks;i+=skip){
1249
842
      SchroFrameData orig;
1250
843
      SchroFrameData ref_data;
 
844
#define LIST_LENGTH 10
1251
845
      SchroMotionVector *hint_mv[LIST_LENGTH];
1252
846
      int m;
1253
847
      int n = 0;
1353
947
{
1354
948
  SchroParams *params = me->params;
1355
949
  SchroMotionVector *mv;
1356
 
  SchroMetricScan scan2;
 
950
  SchroMetricScan scan;
1357
951
  SchroMotionField *hint_mf;
1358
952
  SchroMotionVector *hint_mv;
1359
953
  int dx, dy;
1360
954
 
1361
 
  scan2.frame = get_downsampled (me->encoder_frame, 0);
1362
 
  if (ref == 0) {
1363
 
    scan2.ref_frame = get_downsampled (me->encoder_frame->ref_frame0, 0);
1364
 
  } else {
1365
 
    scan2.ref_frame = get_downsampled (me->encoder_frame->ref_frame1, 0);
1366
 
  }
 
955
  scan.frame = get_downsampled (me->encoder_frame, 0);
 
956
  scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], 0);
1367
957
 
1368
958
  hint_mf = me->downsampled_mf[ref][2];
1369
959
 
1370
 
  scan2.x = i * params->xbsep_luma;
1371
 
  scan2.y = j * params->ybsep_luma;
1372
 
  scan2.block_width = MIN(4*params->xbsep_luma, scan2.frame->width - scan2.x);
1373
 
  scan2.block_height = MIN(4*params->ybsep_luma, scan2.frame->height - scan2.y);
1374
 
  scan2.gravity_scale = 0;
1375
 
  scan2.gravity_x = 0;
1376
 
  scan2.gravity_y = 0;
 
960
  scan.x = i * params->xbsep_luma;
 
961
  scan.y = j * params->ybsep_luma;
 
962
  scan.block_width = MIN(4*params->xbsep_luma, scan.frame->width - scan.x);
 
963
  scan.block_height = MIN(4*params->ybsep_luma, scan.frame->height - scan.y);
 
964
  scan.gravity_scale = 0;
 
965
  scan.gravity_x = 0;
 
966
  scan.gravity_y = 0;
1377
967
 
1378
968
  mv = &block->mv[0][0];
1379
969
  hint_mv = motion_field_get (hint_mf, i, j);
1381
971
  dx = hint_mv->dx[ref];
1382
972
  dy = hint_mv->dy[ref];
1383
973
 
1384
 
  schro_metric_scan_setup (&scan2, dx, dy, distance);
1385
 
  if (scan2.scan_width <= 0 || scan2.scan_height <= 0) {
 
974
  schro_metric_scan_setup (&scan, dx, dy, distance);
 
975
  if (scan.scan_width <= 0 || scan.scan_height <= 0) {
1386
976
    mv->dx[ref] = 0;
1387
977
    mv->dy[ref] = 0;
1388
978
    mv->metric = SCHRO_METRIC_INVALID;
 
979
    block->valid = FALSE;
1389
980
    return;
1390
981
  }
1391
982
 
1392
 
  schro_metric_scan_do_scan (&scan2);
1393
 
  block->error = schro_metric_scan_get_min (&scan2, &dx, &dy);
 
983
  schro_metric_scan_do_scan (&scan);
 
984
  block->error = schro_metric_scan_get_min (&scan, &dx, &dy);
1394
985
  mv->metric = block->error/16;
1395
986
 
1396
987
  mv->split = 0;
1402
993
  schro_block_fixup (block);
1403
994
  block->entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
1404
995
      i, j, block);
1405
 
}
1406
 
 
1407
 
static SchroMotionField *
1408
 
schro_motionest_superblock_scan (SchroMotionEst *me, int ref, int distance)
1409
 
{
1410
 
  SchroMotionField *mf;
1411
 
  SchroMotionVector *mv;
1412
 
  SchroParams *params = me->params;
1413
 
  int i;
1414
 
  int j;
1415
 
  int skip = 4;
1416
 
  SchroBlock block;
1417
 
 
1418
 
  mf = schro_motion_field_new (params->x_num_blocks, params->y_num_blocks);
1419
 
  schro_motion_field_set (mf, 0, 1<<ref);
1420
 
 
1421
 
  for(j=0;j<params->y_num_blocks;j+=skip){
1422
 
    for(i=0;i<params->x_num_blocks;i+=skip){
1423
 
      mv = motion_field_get (mf, i, j);
1424
 
 
1425
 
      schro_motionest_superblock_scan_one (me, ref, distance, &block,
1426
 
          i, j);
1427
 
 
1428
 
      *mv = block.mv[0][0];
1429
 
      motion_field_splat_4x4 (mf, i, j);
1430
 
    }
1431
 
  }
1432
 
 
1433
 
  return mf;
 
996
  block->valid = TRUE;
1434
997
}
1435
998
 
1436
999
static void
1451
1014
  block->error = schro_motionest_superblock_get_metric (me, block, i, j);
1452
1015
  block->entropy = 0;
1453
1016
  schro_block_fixup (block);
 
1017
 
 
1018
  block->valid = (block->error != SCHRO_METRIC_INVALID_2);
1454
1019
}
1455
1020
 
1456
1021
static void
1471
1036
  schro_block_fixup (block);
1472
1037
  block->entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
1473
1038
      i, j, block);
 
1039
  block->valid = (block->error != SCHRO_METRIC_INVALID_2);
1474
1040
}
1475
1041
 
1476
1042
static void
1507
1073
 
1508
1074
  block->entropy = schro_motion_superblock_try_estimate_entropy (me->motion,
1509
1075
      i, j, block);
 
1076
  block->valid = TRUE;
1510
1077
}
1511
1078
 
1512
1079
static void
1531
1098
 
1532
1099
  schro_block_fixup (block);
1533
1100
  block->entropy = 0;
 
1101
  block->valid = TRUE;
1534
1102
}
1535
1103
 
 
1104
#ifdef unused
1536
1105
static void
1537
1106
schro_motion_splat_4x4 (SchroMotion *motion, int i, int j)
1538
1107
{
1546
1115
  memcpy (SCHRO_MOTION_GET_BLOCK (motion, i, j+2), mv, 4*sizeof(*mv));
1547
1116
  memcpy (SCHRO_MOTION_GET_BLOCK (motion, i, j+3), mv, 4*sizeof(*mv));
1548
1117
}
 
1118
#endif
1549
1119
 
 
1120
#ifdef unused
1550
1121
static void
1551
1122
motion_field_splat_4x4 (SchroMotionField *mf, int i, int j)
1552
1123
{
1560
1131
  memcpy (motion_field_get (mf, i, j+2), mv, 4*sizeof(*mv));
1561
1132
  memcpy (motion_field_get (mf, i, j+3), mv, 4*sizeof(*mv));
1562
1133
}
 
1134
#endif
1563
1135
 
1564
1136
#ifdef unused
1565
1137
static void
1586
1158
  int ii, jj;
1587
1159
 
1588
1160
  scan.frame = get_downsampled (me->encoder_frame, 0);
1589
 
  if (ref == 0) {
1590
 
    scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame0, 0);
1591
 
  } else {
1592
 
    scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame1, 0);
1593
 
  }
 
1161
  scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], 0);
1594
1162
 
1595
1163
  hint_mf = me->downsampled_mf[ref][1];
1596
1164
 
1601
1169
  scan.gravity_y = 0;
1602
1170
 
1603
1171
  block->error = 0;
 
1172
  block->valid = TRUE;
1604
1173
  for(jj=0;jj<4;jj++){
1605
1174
    for(ii=0;ii<4;ii++){
1606
1175
      mv = &block->mv[jj][ii];
1617
1186
        mv->dy[ref] = 0;
1618
1187
        mv->metric = SCHRO_METRIC_INVALID;
1619
1188
        block->error += mv->metric;
 
1189
        block->valid = FALSE;
1620
1190
        continue;
1621
1191
      }
1622
1192
 
1623
1193
      schro_metric_scan_do_scan (&scan);
1624
1194
      mv->metric = schro_metric_scan_get_min (&scan, &dx, &dy);
1625
1195
      block->error += mv->metric;
 
1196
      block->valid &= (mv->metric != SCHRO_METRIC_INVALID);
1626
1197
 
1627
1198
      mv->split = 2;
1628
1199
      mv->pred_mode = 1<<ref;
1637
1208
      i, j, block);
1638
1209
}
1639
1210
 
1640
 
static SchroMotionField *
1641
 
schro_motionest_block_scan (SchroMotionEst *me, SchroMotionField *mask_mf,
1642
 
    int ref)
1643
 
{
1644
 
  SchroMetricScan scan;
1645
 
  SchroMotionVector *mv;
1646
 
  SchroMotionField *mf;
1647
 
  SchroMotionVector *hint_mv;
1648
 
  SchroMotionField *hint_mf;
1649
 
  SchroMotionVector *mask_mv;
1650
 
  SchroParams *params = me->params;
1651
 
  int i;
1652
 
  int j;
1653
 
  int distance = 12;
1654
 
 
1655
 
  scan.frame = get_downsampled (me->encoder_frame, 0);
1656
 
  if (ref == 0) {
1657
 
    scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame0, 0);
1658
 
  } else {
1659
 
    scan.ref_frame = get_downsampled (me->encoder_frame->ref_frame1, 0);
1660
 
  }
1661
 
 
1662
 
  hint_mf = me->downsampled_mf[ref][2];
1663
 
  mf = schro_motion_field_new (params->x_num_blocks, params->y_num_blocks);
1664
 
 
1665
 
  schro_motion_field_set (mf, 2, 1<<ref);
1666
 
 
1667
 
  scan.block_width = params->xbsep_luma;
1668
 
  scan.block_height = params->ybsep_luma;
1669
 
  scan.gravity_scale = 0;
1670
 
  scan.gravity_x = 0;
1671
 
  scan.gravity_y = 0;
1672
 
 
1673
 
  for(j=0;j<params->y_num_blocks;j++){
1674
 
    for(i=0;i<params->x_num_blocks;i++){
1675
 
      int dx, dy;
1676
 
 
1677
 
      mask_mv = motion_field_get (mask_mf, i&(~3), j&(~3));
1678
 
      /* FIXME */
1679
 
      //if (mask_mv->metric != SCHRO_METRIC_INVALID) continue;
1680
 
 
1681
 
      hint_mv = motion_field_get (hint_mf, i, j);
1682
 
 
1683
 
      scan.x = i * params->xbsep_luma;
1684
 
      scan.y = j * params->ybsep_luma;
1685
 
      schro_metric_scan_setup (&scan, hint_mv->dx[ref], hint_mv->dy[ref],
1686
 
          distance);
1687
 
 
1688
 
      mv = motion_field_get (mf, i, j);
1689
 
      if (scan.scan_width <= 0 || scan.scan_height <= 0) {
1690
 
        mv->pred_mode = 1<<ref;
1691
 
        mv->dx[ref] = 0;
1692
 
        mv->dy[ref] = 0;
1693
 
        mv->split = 2;
1694
 
        mv->metric = SCHRO_METRIC_INVALID;
1695
 
        continue;
1696
 
      }
1697
 
 
1698
 
      schro_metric_scan_do_scan (&scan);
1699
 
      mv->metric = schro_metric_scan_get_min (&scan, &dx, &dy);
1700
 
 
1701
 
      mv->dx[ref] = dx;
1702
 
      mv->dy[ref] = dy;
1703
 
 
1704
 
      mv->split = 2;
1705
 
      mv->pred_mode = 1<<ref;
1706
 
      if (mv->metric > (scan.block_width * scan.block_height)*50) {
1707
 
        mv->metric = SCHRO_METRIC_INVALID;
1708
 
      }
1709
 
    }
1710
 
  }
1711
 
 
1712
 
  return mf;
1713
 
}
1714
 
 
1715
 
static void
1716
 
schro_encoder_dc_predict (SchroEncoderFrame *frame, int i, int j)
1717
 
{
1718
 
  SchroParams *params = &frame->params;
1719
 
  int luma_w, luma_h;
1720
 
  int chroma_w, chroma_h;
1721
 
  SchroFrame *orig_frame = frame->filtered_frame;
1722
 
  SchroMotionVectorDC *mvdc;
1723
 
 
1724
 
  luma_w = params->xbsep_luma;
1725
 
  luma_h = params->xbsep_luma;
1726
 
  chroma_w = luma_w>>params->video_format->chroma_h_shift;
1727
 
  chroma_h = luma_h>>params->video_format->chroma_v_shift;
1728
 
 
1729
 
  mvdc = SCHRO_MOTION_GET_DC_BLOCK (frame->motion, i, j);
1730
 
 
1731
 
  memset(mvdc, 0, sizeof(*mvdc));
1732
 
  mvdc->pred_mode = 0;
1733
 
  mvdc->split = 2;
1734
 
  mvdc->using_global = 0;
1735
 
  schro_block_average (&mvdc->dc[0], orig_frame->components + 0,
1736
 
      i*luma_w, j*luma_h, luma_w, luma_h);
1737
 
  schro_block_average (&mvdc->dc[1], orig_frame->components + 1,
1738
 
      i*chroma_w, j*chroma_h, chroma_w, chroma_h);
1739
 
  schro_block_average (&mvdc->dc[2], orig_frame->components + 2,
1740
 
      i*chroma_w, j*chroma_h, chroma_w, chroma_h);
1741
 
 
1742
 
  mvdc->metric = DC_METRIC*8*8;
1743
 
}
1744
1211
 
1745
1212
#define MAGIC_SUPERBLOCK_METRIC 5
1746
1213
#define MAGIC_BLOCK_METRIC 50
1747
1214
 
1748
1215
void
1749
 
schro_encoder_bigblock2_estimation (SchroMotionEst *me)
 
1216
schro_encoder_bigblock_estimation (SchroMotionEst *me)
1750
1217
{
1751
1218
  SchroParams *params = me->params;
1752
1219
  int i,j;
1790
1257
      min_k = 0;
1791
1258
      min_score = blocks[0].entropy + me->lambda * blocks[0].error;
1792
1259
      for(k=0;k<n;k++){
 
1260
#if 0
 
1261
        if (blocks[k].error == SCHRO_METRIC_INVALID) {
 
1262
          SCHRO_ERROR("k %d", k);
 
1263
          SCHRO_ASSERT(blocks[k].error != SCHRO_METRIC_INVALID);
 
1264
        }
 
1265
        SCHRO_ASSERT(blocks[k].error != 16*SCHRO_METRIC_INVALID);
 
1266
#endif
 
1267
        if (!blocks[k].valid) continue;
1793
1268
        score = blocks[k].entropy + me->lambda * blocks[k].error;
1794
1269
        if (score < min_score) {
1795
1270
          min_k = k;
1806
1281
  me->encoder_frame->mc_error = total_error;
1807
1282
}
1808
1283
 
1809
 
void
1810
 
schro_encoder_bigblock_estimation (SchroMotionEst *me)
1811
 
{
1812
 
  SchroMotionField *mf1;
1813
 
  SchroMotionField *mf2 = NULL;
1814
 
  SchroMotionField *mf3;
1815
 
  SchroMotionField *mf4 = NULL;
1816
 
  SchroMotionVector *mv;
1817
 
  SchroMotionVector *mv1;
1818
 
  SchroMotionVector *mv2;
1819
 
  SchroParams *params = me->params;
1820
 
  int i,j;
1821
 
  int k,l;
1822
 
  int n;
1823
 
 
1824
 
  n = params->xbsep_luma * params->ybsep_luma;
1825
 
 
1826
 
  mf1 = schro_motionest_superblock_scan (me, 0, 4);
1827
 
  schro_motion_field_lshift (mf1, params->mv_precision);
1828
 
 
1829
 
  mf3 = schro_motionest_block_scan (me, mf1, 0);
1830
 
 
1831
 
  if (me->encoder_frame->num_refs > 1) {
1832
 
    mf2 = schro_motionest_superblock_scan (me, 1, 4);
1833
 
    schro_motion_field_lshift (mf2, params->mv_precision);
1834
 
 
1835
 
    mf4 = schro_motionest_block_scan (me, mf2, 1);
1836
 
  }
1837
 
 
1838
 
  for(j=0;j<params->y_num_blocks;j+=4){
1839
 
    for(i=0;i<params->x_num_blocks;i+=4){
1840
 
      mv = SCHRO_MOTION_GET_BLOCK (me->motion, i, j);
1841
 
 
1842
 
      if (me->encoder_frame->num_refs == 1) {
1843
 
        mv1 = motion_field_get (mf1, i, j);
1844
 
        if (mv1->metric < n*MAGIC_SUPERBLOCK_METRIC) {
1845
 
          *mv = *mv1;
1846
 
          mv->pred_mode = 1;
1847
 
          schro_motion_splat_4x4 (me->motion, i, j);
1848
 
          continue;
1849
 
        }
1850
 
      } else {
1851
 
        int pred_mode = 0;
1852
 
 
1853
 
        mv1 = motion_field_get (mf1, i, j);
1854
 
        mv2 = motion_field_get (mf2, i, j);
1855
 
 
1856
 
        if (mv1->metric < n*MAGIC_SUPERBLOCK_METRIC) pred_mode |= 1;
1857
 
        if (mv2->metric < n*MAGIC_SUPERBLOCK_METRIC) pred_mode |= 2;
1858
 
 
1859
 
        if (pred_mode != 0) {
1860
 
          mv->pred_mode = pred_mode;
1861
 
          mv->split = 0;
1862
 
          mv->dx[0] = mv1->dx[0];
1863
 
          mv->dy[0] = mv1->dy[0];
1864
 
          mv->dx[1] = mv2->dx[1];
1865
 
          mv->dy[1] = mv2->dy[1];
1866
 
          mv->metric = MIN(mv1->metric, mv2->metric);
1867
 
 
1868
 
          schro_motion_splat_4x4 (me->motion, i, j);
1869
 
          continue;
1870
 
        }
1871
 
      }
1872
 
 
1873
 
      for(l=j;l<j+4;l++) {
1874
 
        for(k=i;k<i+4;k++) {
1875
 
          mv = SCHRO_MOTION_GET_BLOCK (me->motion, k, l);
1876
 
 
1877
 
          if (me->encoder_frame->num_refs == 1) {
1878
 
            mv1 = motion_field_get (mf3, k, l);
1879
 
            if (mv1->metric < n*MAGIC_BLOCK_METRIC) {
1880
 
              *mv = *mv1;
1881
 
              mv->pred_mode = 1;
1882
 
              mv->split = 2;
1883
 
              continue;
1884
 
            }
1885
 
          } else {
1886
 
            int pred_mode = 0;
1887
 
 
1888
 
            mv1 = motion_field_get (mf3, k, l);
1889
 
            mv2 = motion_field_get (mf4, k, l);
1890
 
 
1891
 
            if (mv1->metric < n*MAGIC_BLOCK_METRIC) pred_mode |= 1;
1892
 
            if (mv2->metric < n*MAGIC_BLOCK_METRIC) pred_mode |= 2;
1893
 
 
1894
 
            if (pred_mode == 3) {
1895
 
              if (mv1->metric < mv2->metric/2) {
1896
 
                pred_mode = 1;
1897
 
              } else if (mv2->metric < mv1->metric/2) {
1898
 
                pred_mode = 2;
1899
 
              }
1900
 
            }
1901
 
 
1902
 
            if (pred_mode != 0) {
1903
 
              mv->pred_mode = pred_mode;
1904
 
              mv->split = 2;
1905
 
              mv->dx[0] = mv1->dx[0];
1906
 
              mv->dy[0] = mv1->dy[0];
1907
 
              mv->dx[1] = mv2->dx[1];
1908
 
              mv->dy[1] = mv2->dy[1];
1909
 
              mv->metric = MIN(mv1->metric, mv2->metric);
1910
 
              continue;
1911
 
            }
1912
 
          }
1913
 
 
1914
 
          schro_encoder_dc_predict (me->encoder_frame, k, l);
1915
 
        }
1916
 
      }
1917
 
    }
1918
 
  }
1919
 
  schro_motion_cleanup (me->motion,
1920
 
      (params->video_format->width + params->xbsep_luma - 1)/params->xbsep_luma,
1921
 
      (params->video_format->height + params->ybsep_luma - 1)/params->ybsep_luma);
1922
 
 
1923
 
  schro_motion_field_free (mf1);
1924
 
  schro_motion_field_free (mf3);
1925
 
  if (me->encoder_frame->num_refs > 1) {
1926
 
    schro_motion_field_free (mf2);
1927
 
    schro_motion_field_free (mf4);
1928
 
  }
1929
 
 
1930
 
}
1931
 
 
1932
 
 
1933
1284
int
1934
1285
schro_motion_block_estimate_entropy (SchroMotion *motion, int i, int j)
1935
1286
{
2048
1399
 
2049
1400
    ref = mv->pred_mode - 1;
2050
1401
 
2051
 
    if (ref == 0) {
2052
 
      ref_frame = get_downsampled (me->encoder_frame->ref_frame0, 0);
2053
 
    } else {
2054
 
      ref_frame = get_downsampled (me->encoder_frame->ref_frame1, 0);
 
1402
    ref_frame = get_downsampled (me->encoder_frame->ref_frame[ref], 0);
 
1403
 
 
1404
    if (i*me->params->xbsep_luma + mv->dx[ref] < 0 ||
 
1405
        j*me->params->ybsep_luma + mv->dy[ref] < 0) {
 
1406
      return SCHRO_METRIC_INVALID_2;
2055
1407
    }
2056
1408
 
2057
1409
    schro_frame_get_subdata (ref_frame, &ref_data,
2059
1411
        j*me->params->ybsep_luma + mv->dy[ref]);
2060
1412
 
2061
1413
    if (ref_data.width < width || ref_data.height < height) {
2062
 
      return SCHRO_METRIC_INVALID;
 
1414
      return SCHRO_METRIC_INVALID_2;
2063
1415
    }
2064
1416
 
2065
1417
    return schro_metric_get (&orig, &ref_data, width, height);
2069
1421
    SchroFrameData ref0_data;
2070
1422
    SchroFrameData ref1_data;
2071
1423
 
2072
 
    schro_frame_get_subdata (get_downsampled (me->encoder_frame->ref_frame0, 0),
 
1424
    if (i*me->params->xbsep_luma + mv->dx[0] < 0 ||
 
1425
        j*me->params->ybsep_luma + mv->dy[0] < 0 ||
 
1426
        i*me->params->xbsep_luma + mv->dx[1] < 0 ||
 
1427
        j*me->params->ybsep_luma + mv->dy[1] < 0) {
 
1428
      return SCHRO_METRIC_INVALID_2;
 
1429
    }
 
1430
 
 
1431
    schro_frame_get_subdata (get_downsampled (me->encoder_frame->ref_frame[0], 0),
2073
1432
        &ref0_data, 0, i*me->params->xbsep_luma + mv->dx[0],
2074
1433
        j*me->params->ybsep_luma + mv->dy[0]);
2075
 
    schro_frame_get_subdata (get_downsampled (me->encoder_frame->ref_frame1, 0),
 
1434
    schro_frame_get_subdata (get_downsampled (me->encoder_frame->ref_frame[1], 0),
2076
1435
        &ref1_data, 0, i*me->params->xbsep_luma + mv->dx[1],
2077
1436
        j*me->params->ybsep_luma + mv->dy[1]);
2078
1437
 
2079
1438
    if (ref0_data.width < width || ref0_data.height < height ||
2080
1439
        ref1_data.width < width || ref1_data.height < height) {
2081
 
      return SCHRO_METRIC_INVALID;
 
1440
      return SCHRO_METRIC_INVALID_2;
2082
1441
    }
2083
1442
 
2084
1443
    return schro_metric_get_biref (&orig, &ref0_data, 1, &ref1_data, 1, 1, width, height);
2086
1445
 
2087
1446
  SCHRO_ASSERT(0);
2088
1447
 
2089
 
  return SCHRO_METRIC_INVALID;
 
1448
  return SCHRO_METRIC_INVALID_2;
2090
1449
}
2091
1450
 
2092
1451
int