00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.h"
00016 #include "image.h"
00017
00018
00019
00020
00021
00022
00023
00024 static inline void CopyMVBlock16(short ***enc_mv, short ***rdo_mv, int start, int end)
00025 {
00026 int j;
00027 for (j = start; j < end; j++)
00028 {
00029 memcpy(enc_mv[img->block_y + j][img->block_x], rdo_mv[j][0], BLOCK_MULTIPLE * 2 * sizeof(short));
00030 }
00031 }
00032
00033
00034
00035
00036
00037
00038
00039 static inline void ResetMVBlock16(short ***enc_mv, int start, int end)
00040 {
00041 int j;
00042 for (j = img->block_y + start; j < img->block_y + end; j++)
00043 {
00044 memset(enc_mv[j][img->block_x], 0, BLOCK_MULTIPLE * 2 * sizeof(short));
00045 }
00046 }
00047
00048
00049
00050
00051
00052
00053
00054 static inline void ResetRefBlock16(char **enc_ref, int start, int end)
00055 {
00056 int j;
00057 for (j = img->block_y + start; j < img->block_y + end; j++)
00058 {
00059 memset(&enc_ref[j][img->block_x], -1, BLOCK_MULTIPLE * sizeof(char));
00060 }
00061 }
00062
00063
00064
00065
00066
00067
00068
00069 static inline void CopyMVBlock8(short ***enc_mv, short ***rdo_mv, int start, int end, int offset)
00070 {
00071 int j;
00072 int block_x = img->block_x + offset;
00073 for (j = start; j < end; j++)
00074 {
00075 memcpy(enc_mv[img->block_y + j][block_x], rdo_mv[j][offset], 2 * 2 * sizeof(short));
00076 }
00077 }
00078
00079
00080
00081
00082
00083
00084
00085 static inline void ResetMVBlock8(short ***enc_mv, int start, int end, int offset)
00086 {
00087 int j;
00088 int block_x = img->block_x + offset;
00089 for (j = img->block_y + start; j < img->block_y + end; j++)
00090 {
00091 memset(enc_mv[j][block_x], 0, 2 * 2 * sizeof(short));
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100
00101 static inline void ResetRefBlock8(char **enc_ref, int start, int end, int offset)
00102 {
00103 int j;
00104 int block_x = img->block_x + offset;
00105 for (j = img->block_y + start; j < img->block_y + end; j++)
00106 {
00107 memset(&enc_ref[j][block_x], -1, 2 * sizeof(char));
00108 }
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 static void SetMotionVectorsMBPSlice (ImageParameters *img, PicMotionParams *motion, Macroblock* currMB)
00118 {
00119 short *****all_mv = img->all_mv[LIST_0];
00120 int l0_ref, mode8;
00121 short ***rdo_mv = motion->mv[LIST_0];
00122
00123 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
00124 {
00125 memcpy(&rdopt->all_mv[LIST_0][0][0][0][0][0], &all_mv[0][0][0][0][0], img->max_num_references * 9 * MB_BLOCK_PARTITIONS * 2 * sizeof(short));
00126 }
00127
00128 if (currMB->mb_type == PSKIP)
00129 {
00130 CopyMVBlock16(rdo_mv, all_mv[0][PSKIP], 0, 4);
00131 }
00132 else if (currMB->mb_type == P16x16)
00133 {
00134 l0_ref = motion->ref_idx[LIST_0][img->block_y][img->block_x];
00135 CopyMVBlock16(rdo_mv, all_mv[l0_ref][P16x16], 0, 4);
00136 }
00137 else if (currMB->mb_type == P16x8)
00138 {
00139 l0_ref = motion->ref_idx[LIST_0][img->block_y][img->block_x];
00140 CopyMVBlock16(rdo_mv, all_mv[l0_ref][P16x8], 0, 2);
00141
00142 l0_ref = motion->ref_idx[LIST_0][img->block_y + 2][img->block_x];
00143 CopyMVBlock16(rdo_mv, all_mv[l0_ref][P16x8], 2, 4);
00144 }
00145 else if (currMB->mb_type == P8x16)
00146 {
00147 l0_ref = motion->ref_idx[LIST_0][img->block_y][img->block_x];
00148 CopyMVBlock8(rdo_mv, all_mv[l0_ref][P8x16], 0, 4, 0);
00149
00150 l0_ref = motion->ref_idx[LIST_0][img->block_y][img->block_x + 2];
00151 CopyMVBlock8(rdo_mv, all_mv[l0_ref][P8x16], 0, 4, 2);
00152 }
00153 else if (currMB->mb_type == P8x8)
00154 {
00155 mode8 = currMB->b8mode[0];
00156 l0_ref = motion->ref_idx[LIST_0][img->block_y ][img->block_x ];
00157 CopyMVBlock8(rdo_mv, all_mv[l0_ref][mode8], 0, 2, 0);
00158
00159 mode8 = currMB->b8mode[1];
00160 l0_ref = motion->ref_idx[LIST_0][img->block_y ][img->block_x + 2];
00161 CopyMVBlock8(rdo_mv, all_mv[l0_ref][mode8], 0, 2, 2);
00162
00163 mode8 = currMB->b8mode[2];
00164 l0_ref = motion->ref_idx[LIST_0][img->block_y + 2][img->block_x ];
00165 CopyMVBlock8(rdo_mv, all_mv[l0_ref][mode8], 2, 4, 0);
00166
00167 mode8 = currMB->b8mode[3];
00168 l0_ref = motion->ref_idx[LIST_0][img->block_y + 2][img->block_x + 2];
00169 CopyMVBlock8(rdo_mv, all_mv[l0_ref][mode8], 2, 4, 2);
00170 }
00171 else
00172 {
00173 ResetMVBlock16 (rdo_mv, 0, 4);
00174 ResetRefBlock16(motion->ref_idx[LIST_0], 0, 4);
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184 static void SetMVBSlice16x8(PicMotionParams *motion, Macroblock* currMB, int pos)
00185 {
00186 int l0_ref, l1_ref;
00187 int pdir = currMB->b8pdir[pos];
00188 if (pdir == LIST_0)
00189 {
00190 l0_ref = motion->ref_idx[LIST_0][img->block_y + pos][img->block_x];
00191 CopyMVBlock16(motion->mv[LIST_0], img->all_mv [LIST_0][l0_ref][P16x8], pos, pos + 2);
00192 ResetMVBlock16 (motion->mv[LIST_1], pos, pos + 2);
00193 ResetRefBlock16(motion->ref_idx[LIST_1], pos, pos + 2);
00194 }
00195 else if (pdir == LIST_1)
00196 {
00197 ResetMVBlock16 (motion->mv[LIST_0], pos, pos + 2);
00198 ResetRefBlock16(motion->ref_idx[LIST_0], pos, pos + 2);
00199 l1_ref = motion->ref_idx[LIST_1][img->block_y + pos][img->block_x];
00200 CopyMVBlock16 (motion->mv[LIST_1], img->all_mv [LIST_1][l1_ref][P16x8], pos, pos + 2);
00201 }
00202 else
00203 {
00204 int bipred_me = currMB->bipred_me[pos];
00205 short ******all_mv = bipred_me ? img->bipred_mv[bipred_me - 1]: img->all_mv;
00206 l0_ref = motion->ref_idx[LIST_0][img->block_y + pos][img->block_x];
00207 CopyMVBlock16 (motion->mv[LIST_0], all_mv [LIST_0][l0_ref][P16x8], pos, pos + 2);
00208
00209 l1_ref = motion->ref_idx[LIST_1][img->block_y + pos][img->block_x];
00210 CopyMVBlock16 (motion->mv[LIST_1], all_mv [LIST_1][l1_ref][P16x8], pos, pos + 2);
00211
00212 if (bipred_me && (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)))
00213 {
00214 memcpy(rdopt->all_mv [LIST_0][l0_ref][P16x8][pos][0], all_mv [LIST_0][l0_ref][P16x8][pos][0], 2 * BLOCK_MULTIPLE * 2 * sizeof(short));
00215 memcpy(rdopt->all_mv [LIST_1][l1_ref][P16x8][pos][0], all_mv [LIST_1][l1_ref][P16x8][pos][0], 2 * BLOCK_MULTIPLE * 2 * sizeof(short));
00216 }
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 static void SetMVBSlice8x16(PicMotionParams *motion, Macroblock* currMB, int pos)
00227 {
00228 int l0_ref, l1_ref;
00229 int pdir = currMB->b8pdir[pos >> 1];
00230 if (pdir == LIST_0)
00231 {
00232 l0_ref = motion->ref_idx[LIST_0][img->block_y][img->block_x + pos];
00233 CopyMVBlock8 (motion->mv[LIST_0], img->all_mv [LIST_0][l0_ref][P8x16], 0, 4, pos);
00234 ResetMVBlock8(motion->mv[LIST_1], 0, 4, pos);
00235 ResetRefBlock8(motion->ref_idx[LIST_1], 0, 4, pos);
00236 }
00237 else if (pdir == LIST_1)
00238 {
00239 ResetMVBlock8(motion->mv[LIST_0], 0, 4, pos);
00240 ResetRefBlock8(motion->ref_idx[LIST_0], 0, 4, pos);
00241 l1_ref = motion->ref_idx[LIST_1][img->block_y][img->block_x + pos];
00242 CopyMVBlock8 (motion->mv[LIST_1], img->all_mv [LIST_1][l1_ref][P8x16], 0, 4, pos);
00243 }
00244 else
00245 {
00246 int bipred_me = currMB->bipred_me[pos >> 1];
00247 short ******all_mv = bipred_me ? img->bipred_mv[bipred_me - 1]: img->all_mv;
00248 l0_ref = motion->ref_idx[LIST_0][img->block_y][img->block_x + pos];
00249 CopyMVBlock8(motion->mv [LIST_0], all_mv [LIST_0][l0_ref][P8x16], 0, 4, pos);
00250 l1_ref = motion->ref_idx[LIST_1][img->block_y][img->block_x + pos];
00251 CopyMVBlock8(motion->mv [LIST_1], all_mv [LIST_1][l1_ref][P8x16], 0, 4, pos);
00252
00253 if (bipred_me && (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)))
00254 {
00255 int j;
00256 for (j = 0; j < BLOCK_MULTIPLE; j++)
00257 {
00258 memcpy(rdopt->all_mv [LIST_0][l0_ref][P8x16][j][pos], all_mv [LIST_0][l0_ref][P8x16][j][pos], 2 * 2 * sizeof(short));
00259 }
00260 for (j = 0; j < BLOCK_MULTIPLE; j++)
00261 {
00262 memcpy(rdopt->all_mv [LIST_1][l1_ref][P8x16][j][pos], all_mv [LIST_1][l1_ref][P8x16][j][pos], 2 * 2 * sizeof(short));
00263 }
00264 }
00265 }
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 static void SetMVBSlice8x8(PicMotionParams *motion, Macroblock* currMB, int pos_y, int pos_x)
00275 {
00276 int l0_ref, l1_ref;
00277 int pos = pos_y + (pos_x >> 1);
00278 int pdir = currMB->b8pdir[pos];
00279 int mode = currMB->b8mode[pos];
00280 int block_y = img->block_y + pos_y;
00281 int block_x = img->block_x + pos_x;
00282
00283 if (pdir == LIST_0)
00284 {
00285 l0_ref = motion->ref_idx[LIST_0][block_y][block_x];
00286 CopyMVBlock8 (motion->mv[LIST_0], img->all_mv [LIST_0][l0_ref][mode], pos_y, pos_y + 2, pos_x);
00287 ResetMVBlock8(motion->mv[LIST_1], pos_y, pos_y + 2, pos_x);
00288 ResetRefBlock8(motion->ref_idx[LIST_1], pos_y, pos_y + 2, pos_x);
00289 }
00290 else if (pdir == LIST_1)
00291 {
00292 ResetMVBlock8(motion->mv[LIST_0], pos_y, pos_y + 2, pos_x);
00293 ResetRefBlock8(motion->ref_idx[LIST_0], pos_y, pos_y + 2, pos_x);
00294 l1_ref = motion->ref_idx[LIST_1][block_y][block_x];
00295 CopyMVBlock8 (motion->mv[LIST_1], img->all_mv [LIST_1][l1_ref][mode], pos_y, pos_y + 2, pos_x);
00296 }
00297 else if (pdir == BI_PRED)
00298 {
00299 int bipred_me = currMB->bipred_me[pos];
00300 short ******all_mv = bipred_me ? img->bipred_mv[bipred_me - 1]: img->all_mv;
00301 l0_ref = motion->ref_idx[LIST_0][block_y][block_x];
00302 CopyMVBlock8(motion->mv [LIST_0], all_mv [LIST_0][l0_ref][mode], pos_y, pos_y + 2, pos_x);
00303
00304 l1_ref = motion->ref_idx[LIST_1][block_y][block_x];
00305 CopyMVBlock8(motion->mv [LIST_1], all_mv [LIST_1][l1_ref][mode], pos_y, pos_y + 2, pos_x);
00306
00307 if (bipred_me && (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)))
00308 {
00309 memcpy(rdopt->all_mv [LIST_0][l0_ref][mode][pos_y ][pos_x], all_mv [LIST_0][l0_ref][mode][pos_y ][pos_x], 2 * 2 * sizeof(short));
00310 memcpy(rdopt->all_mv [LIST_0][l0_ref][mode][pos_y + 1][pos_x], all_mv [LIST_0][l0_ref][mode][pos_y + 1][pos_x], 2 * 2 * sizeof(short));
00311 memcpy(rdopt->all_mv [LIST_1][l1_ref][mode][pos_y ][pos_x], all_mv [LIST_1][l1_ref][mode][pos_y ][pos_x], 2 * 2 * sizeof(short));
00312 memcpy(rdopt->all_mv [LIST_1][l1_ref][mode][pos_y + 1][pos_x], all_mv [LIST_1][l1_ref][mode][pos_y + 1][pos_x], 2 * 2 * sizeof(short));
00313 }
00314 }
00315 else
00316 {
00317 ResetMVBlock8(motion->mv[LIST_0], pos_y, pos_y + 2, pos_x);
00318 ResetRefBlock8(motion->ref_idx[LIST_0], pos_y, pos_y + 2, pos_x);
00319 ResetMVBlock8(motion->mv[LIST_1], pos_y, pos_y + 2, pos_x);
00320 ResetRefBlock8(motion->ref_idx[LIST_1], pos_y, pos_y + 2, pos_x);
00321 }
00322 }
00323
00324
00325
00326
00327
00328
00329
00330 static void SetMotionVectorsMBBSlice (ImageParameters *img, PicMotionParams *motion, Macroblock* currMB)
00331 {
00332 int l0_ref, l1_ref;
00333
00334
00335
00336
00337
00338 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
00339 {
00340 memcpy(&rdopt->all_mv[LIST_0][0][0][0][0][0], &img->all_mv[LIST_0][0][0][0][0][0], 2 * img->max_num_references * 9 * MB_BLOCK_PARTITIONS * 2 * sizeof(short));
00341 }
00342
00343 if (currMB->mb_type == P16x16)
00344 {
00345 int pdir = currMB->b8pdir[0];
00346 if (pdir == LIST_0)
00347 {
00348 l0_ref = motion->ref_idx[LIST_0][img->block_y][img->block_x];
00349 CopyMVBlock16 (motion->mv[LIST_0], img->all_mv [LIST_0][l0_ref][P16x16], 0, 4);
00350 ResetMVBlock16(motion->mv[LIST_1], 0, 4);
00351 }
00352 else if (pdir == LIST_1)
00353 {
00354 l1_ref = motion->ref_idx[LIST_1][img->block_y][img->block_x];
00355 ResetMVBlock16(motion->mv[LIST_0], 0, 4);
00356 CopyMVBlock16 (motion->mv[LIST_1], img->all_mv [LIST_1][l1_ref][P16x16], 0, 4);
00357 }
00358 else
00359 {
00360 int bipred_me = currMB->bipred_me[0];
00361 short ******all_mv = bipred_me ? img->bipred_mv[bipred_me - 1]: img->all_mv;
00362 l0_ref = motion->ref_idx[LIST_0][img->block_y][img->block_x];
00363 CopyMVBlock16 (motion->mv[LIST_0], all_mv [LIST_0][l0_ref][P16x16], 0, 4);
00364 l1_ref = motion->ref_idx[LIST_1][img->block_y][img->block_x];
00365 CopyMVBlock16 (motion->mv[LIST_1], all_mv [LIST_1][l1_ref][P16x16], 0, 4);
00366
00367
00368 if (bipred_me && (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)))
00369 {
00370 memcpy(rdopt->all_mv [LIST_0][l0_ref][P16x16][0][0], all_mv [LIST_0][l0_ref][P16x16][0][0], MB_BLOCK_PARTITIONS * 2 * sizeof(short));
00371 memcpy(rdopt->all_mv [LIST_1][l1_ref][P16x16][0][0], all_mv [LIST_1][l1_ref][P16x16][0][0], MB_BLOCK_PARTITIONS * 2 * sizeof(short));
00372 }
00373 }
00374 }
00375 else if (currMB->mb_type == P16x8)
00376 {
00377 SetMVBSlice16x8(motion, currMB, 0);
00378 SetMVBSlice16x8(motion, currMB, 2);
00379 }
00380 else if (currMB->mb_type == P8x16)
00381 {
00382 SetMVBSlice8x16(motion, currMB, 0);
00383 SetMVBSlice8x16(motion, currMB, 2);
00384 }
00385 else if (currMB->mb_type == P8x8 || currMB->mb_type == BSKIP_DIRECT)
00386 {
00387 SetMVBSlice8x8(motion, currMB, 0, 0);
00388 SetMVBSlice8x8(motion, currMB, 0, 2);
00389 SetMVBSlice8x8(motion, currMB, 2, 0);
00390 SetMVBSlice8x8(motion, currMB, 2, 2);
00391 }
00392 else
00393 {
00394 ResetMVBlock16(motion->mv[LIST_0], 0, 4);
00395 ResetRefBlock16(motion->ref_idx[LIST_0], 0, 4);
00396 ResetMVBlock16(motion->mv[LIST_1], 0, 4);
00397 ResetRefBlock16(motion->ref_idx[LIST_1], 0, 4);
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407 void SetMotionVectorsMB (ImageParameters *img, PicMotionParams *motion, Macroblock *currMB)
00408 {
00409 if (img->type == B_SLICE)
00410 {
00411 SetMotionVectorsMBBSlice (img, motion, currMB);
00412 }
00413 else if (img->type == P_SLICE || img->type == SP_SLICE)
00414 {
00415 SetMotionVectorsMBPSlice (img, motion, currMB);
00416 }
00417 }
00418