Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: source/libvpx/vp9/common/vp9_reconinter.c

Issue 232133009: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vp9/common/vp9_reconinter.h ('k') | source/libvpx/vp9/common/vp9_reconintra.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom); 137 xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom);
138 138
139 return clamped_mv; 139 return clamped_mv;
140 } 140 }
141 141
142 static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block, 142 static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
143 int bw, int bh, 143 int bw, int bh,
144 int x, int y, int w, int h, 144 int x, int y, int w, int h,
145 int mi_x, int mi_y) { 145 int mi_x, int mi_y) {
146 struct macroblockd_plane *const pd = &xd->plane[plane]; 146 struct macroblockd_plane *const pd = &xd->plane[plane];
147 const MODE_INFO *mi = xd->mi_8x8[0]; 147 const MODE_INFO *mi = xd->mi[0];
148 const int is_compound = has_second_ref(&mi->mbmi); 148 const int is_compound = has_second_ref(&mi->mbmi);
149 const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
149 int ref; 150 int ref;
150 151
151 for (ref = 0; ref < 1 + is_compound; ++ref) { 152 for (ref = 0; ref < 1 + is_compound; ++ref) {
152 const struct scale_factors *const sf = &xd->block_refs[ref]->sf; 153 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
153 struct buf_2d *const pre_buf = &pd->pre[ref]; 154 struct buf_2d *const pre_buf = &pd->pre[ref];
154 struct buf_2d *const dst_buf = &pd->dst; 155 struct buf_2d *const dst_buf = &pd->dst;
155 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x; 156 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
156 157
157 // TODO(jkoleszar): All chroma MVs in SPLITMV mode are taken as the 158 // TODO(jkoleszar): All chroma MVs in SPLITMV mode are taken as the
158 // same MV (the average of the 4 luma MVs) but we could do something 159 // same MV (the average of the 4 luma MVs) but we could do something
(...skipping 27 matching lines...) Expand all
186 scaled_mv.row = mv_q4.row; 187 scaled_mv.row = mv_q4.row;
187 scaled_mv.col = mv_q4.col; 188 scaled_mv.col = mv_q4.col;
188 xs = ys = 16; 189 xs = ys = 16;
189 } 190 }
190 subpel_x = scaled_mv.col & SUBPEL_MASK; 191 subpel_x = scaled_mv.col & SUBPEL_MASK;
191 subpel_y = scaled_mv.row & SUBPEL_MASK; 192 subpel_y = scaled_mv.row & SUBPEL_MASK;
192 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride 193 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride
193 + (scaled_mv.col >> SUBPEL_BITS); 194 + (scaled_mv.col >> SUBPEL_BITS);
194 195
195 inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride, 196 inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
196 subpel_x, subpel_y, sf, w, h, ref, xd->interp_kernel, 197 subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys);
197 xs, ys);
198 } 198 }
199 } 199 }
200 200
201 static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize, 201 static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize,
202 int mi_row, int mi_col, 202 int mi_row, int mi_col,
203 int plane_from, int plane_to) { 203 int plane_from, int plane_to) {
204 int plane; 204 int plane;
205 const int mi_x = mi_col * MI_SIZE; 205 const int mi_x = mi_col * MI_SIZE;
206 const int mi_y = mi_row * MI_SIZE; 206 const int mi_y = mi_row * MI_SIZE;
207 for (plane = plane_from; plane <= plane_to; ++plane) { 207 for (plane = plane_from; plane <= plane_to; ++plane) {
208 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, 208 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize,
209 &xd->plane[plane]); 209 &xd->plane[plane]);
210 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; 210 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
211 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; 211 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
212 const int bw = 4 * num_4x4_w; 212 const int bw = 4 * num_4x4_w;
213 const int bh = 4 * num_4x4_h; 213 const int bh = 4 * num_4x4_h;
214 214
215 if (xd->mi_8x8[0]->mbmi.sb_type < BLOCK_8X8) { 215 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8) {
216 int i = 0, x, y; 216 int i = 0, x, y;
217 assert(bsize == BLOCK_8X8); 217 assert(bsize == BLOCK_8X8);
218 for (y = 0; y < num_4x4_h; ++y) 218 for (y = 0; y < num_4x4_h; ++y)
219 for (x = 0; x < num_4x4_w; ++x) 219 for (x = 0; x < num_4x4_w; ++x)
220 build_inter_predictors(xd, plane, i++, bw, bh, 220 build_inter_predictors(xd, plane, i++, bw, bh,
221 4 * x, 4 * y, 4, 4, mi_x, mi_y); 221 4 * x, 4 * y, 4, 4, mi_x, mi_y);
222 } else { 222 } else {
223 build_inter_predictors(xd, plane, 0, bw, bh, 223 build_inter_predictors(xd, plane, 0, bw, bh,
224 0, 0, bw, bh, mi_x, mi_y); 224 0, 0, bw, bh, mi_x, mi_y);
225 } 225 }
(...skipping 11 matching lines...) Expand all
237 } 237 }
238 void vp9_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col, 238 void vp9_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
239 BLOCK_SIZE bsize) { 239 BLOCK_SIZE bsize) {
240 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, 240 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0,
241 MAX_MB_PLANE - 1); 241 MAX_MB_PLANE - 1);
242 } 242 }
243 243
244 // TODO(jingning): This function serves as a placeholder for decoder prediction 244 // TODO(jingning): This function serves as a placeholder for decoder prediction
245 // using on demand border extension. It should be moved to /decoder/ directory. 245 // using on demand border extension. It should be moved to /decoder/ directory.
246 static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block, 246 static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
247 int bw, int bh,
247 int x, int y, int w, int h, 248 int x, int y, int w, int h,
248 int mi_x, int mi_y) { 249 int mi_x, int mi_y) {
249 struct macroblockd_plane *const pd = &xd->plane[plane]; 250 struct macroblockd_plane *const pd = &xd->plane[plane];
250 const MODE_INFO *mi = xd->mi_8x8[0]; 251 const MODE_INFO *mi = xd->mi[0];
251 const int is_compound = has_second_ref(&mi->mbmi); 252 const int is_compound = has_second_ref(&mi->mbmi);
253 const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
252 int ref; 254 int ref;
253 255
254 for (ref = 0; ref < 1 + is_compound; ++ref) { 256 for (ref = 0; ref < 1 + is_compound; ++ref) {
255 const struct scale_factors *const sf = &xd->block_refs[ref]->sf; 257 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
256 struct buf_2d *const pre_buf = &pd->pre[ref]; 258 struct buf_2d *const pre_buf = &pd->pre[ref];
257 struct buf_2d *const dst_buf = &pd->dst; 259 struct buf_2d *const dst_buf = &pd->dst;
258 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x; 260 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
259 261
260 // TODO(jkoleszar): All chroma MVs in SPLITMV mode are taken as the 262 // TODO(jkoleszar): All chroma MVs in SPLITMV mode are taken as the
261 // same MV (the average of the 4 luma MVs) but we could do something 263 // same MV (the average of the 4 luma MVs) but we could do something
262 // smarter for non-4:2:0. Just punt for now, pending the changes to get 264 // smarter for non-4:2:0. Just punt for now, pending the changes to get
263 // rid of SPLITMV mode entirely. 265 // rid of SPLITMV mode entirely.
264 const MV mv = mi->mbmi.sb_type < BLOCK_8X8 266 const MV mv = mi->mbmi.sb_type < BLOCK_8X8
265 ? (plane == 0 ? mi->bmi[block].as_mv[ref].as_mv 267 ? (plane == 0 ? mi->bmi[block].as_mv[ref].as_mv
266 : mi_mv_pred_q4(mi, ref)) 268 : mi_mv_pred_q4(mi, ref))
267 : mi->mbmi.mv[ref].as_mv; 269 : mi->mbmi.mv[ref].as_mv;
270
271 // TODO(jkoleszar): This clamping is done in the incorrect place for the
272 // scaling case. It needs to be done on the scaled MV, not the pre-scaling
273 // MV. Note however that it performs the subsampling aware scaling so
274 // that the result is always q4.
275 // mv_precision precision is MV_PRECISION_Q4.
276 const MV mv_q4 = clamp_mv_to_umv_border_sb(xd, &mv, bw, bh,
277 pd->subsampling_x,
278 pd->subsampling_y);
279
268 MV32 scaled_mv; 280 MV32 scaled_mv;
269 int xs, ys, x0, y0, x0_16, y0_16, frame_width, frame_height, buf_stride, 281 int xs, ys, x0, y0, x0_16, y0_16, frame_width, frame_height, buf_stride,
270 subpel_x, subpel_y; 282 subpel_x, subpel_y;
271 uint8_t *ref_frame, *buf_ptr; 283 uint8_t *ref_frame, *buf_ptr;
272 const YV12_BUFFER_CONFIG *ref_buf = xd->block_refs[ref]->buf; 284 const YV12_BUFFER_CONFIG *ref_buf = xd->block_refs[ref]->buf;
273 const MV mv_q4 = {
274 mv.row * (1 << (1 - pd->subsampling_y)),
275 mv.col * (1 << (1 - pd->subsampling_x))
276 };
277 285
278 // Get reference frame pointer, width and height. 286 // Get reference frame pointer, width and height.
279 if (plane == 0) { 287 if (plane == 0) {
280 frame_width = ref_buf->y_crop_width; 288 frame_width = ref_buf->y_crop_width;
281 frame_height = ref_buf->y_crop_height; 289 frame_height = ref_buf->y_crop_height;
282 ref_frame = ref_buf->y_buffer; 290 ref_frame = ref_buf->y_buffer;
283 } else { 291 } else {
284 frame_width = ref_buf->uv_crop_width; 292 frame_width = ref_buf->uv_crop_width;
285 frame_height = ref_buf->uv_crop_height; 293 frame_height = ref_buf->uv_crop_height;
286 ref_frame = plane == 1 ? ref_buf->u_buffer : ref_buf->v_buffer; 294 ref_frame = plane == 1 ? ref_buf->u_buffer : ref_buf->v_buffer;
287 } 295 }
288 296
289 // Get block position in current frame. 297 if (vp9_is_scaled(sf)) {
290 x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; 298 // Co-ordinate of containing block to pixel precision.
291 y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; 299 int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x));
300 int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y));
292 301
293 // Precision of x0_16 and y0_16 is 1/16th pixel. 302 // Co-ordinate of the block to 1/16th pixel precision.
294 x0_16 = x0 << SUBPEL_BITS; 303 x0_16 = (x_start + x) << SUBPEL_BITS;
295 y0_16 = y0 << SUBPEL_BITS; 304 y0_16 = (y_start + y) << SUBPEL_BITS;
296 305
297 if (vp9_is_scaled(sf)) { 306 // Co-ordinate of current block in reference frame
307 // to 1/16th pixel precision.
308 x0_16 = sf->scale_value_x(x0_16, sf);
309 y0_16 = sf->scale_value_y(y0_16, sf);
310
311 // Map the top left corner of the block into the reference frame.
312 x0 = sf->scale_value_x(x_start + x, sf);
313 y0 = sf->scale_value_y(y_start + y, sf);
314
315 // Scale the MV and incorporate the sub-pixel offset of the block
316 // in the reference frame.
298 scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); 317 scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
299 xs = sf->x_step_q4; 318 xs = sf->x_step_q4;
300 ys = sf->y_step_q4; 319 ys = sf->y_step_q4;
301 // Map the top left corner of the block into the reference frame.
302 x0 = sf->scale_value_x(x0, sf);
303 y0 = sf->scale_value_y(y0, sf);
304 x0_16 = sf->scale_value_x(x0_16, sf);
305 y0_16 = sf->scale_value_y(y0_16, sf);
306 } else { 320 } else {
321 // Co-ordinate of containing block to pixel precision.
322 x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
323 y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
324
325 // Co-ordinate of the block to 1/16th pixel precision.
326 x0_16 = x0 << SUBPEL_BITS;
327 y0_16 = y0 << SUBPEL_BITS;
328
307 scaled_mv.row = mv_q4.row; 329 scaled_mv.row = mv_q4.row;
308 scaled_mv.col = mv_q4.col; 330 scaled_mv.col = mv_q4.col;
309 xs = ys = 16; 331 xs = ys = 16;
310 } 332 }
311 subpel_x = scaled_mv.col & SUBPEL_MASK; 333 subpel_x = scaled_mv.col & SUBPEL_MASK;
312 subpel_y = scaled_mv.row & SUBPEL_MASK; 334 subpel_y = scaled_mv.row & SUBPEL_MASK;
313 335
314 // Calculate the top left corner of the best matching block in the reference frame. 336 // Calculate the top left corner of the best matching block in the reference frame.
315 x0 += scaled_mv.col >> SUBPEL_BITS; 337 x0 += scaled_mv.col >> SUBPEL_BITS;
316 y0 += scaled_mv.row >> SUBPEL_BITS; 338 y0 += scaled_mv.row >> SUBPEL_BITS;
(...skipping 23 matching lines...) Expand all
340 y0 -= VP9_INTERP_EXTEND - 1; 362 y0 -= VP9_INTERP_EXTEND - 1;
341 y1 += VP9_INTERP_EXTEND; 363 y1 += VP9_INTERP_EXTEND;
342 y_pad = 1; 364 y_pad = 1;
343 } 365 }
344 366
345 // Skip border extension if block is inside the frame. 367 // Skip border extension if block is inside the frame.
346 if (x0 < 0 || x0 > frame_width - 1 || x1 < 0 || x1 > frame_width || 368 if (x0 < 0 || x0 > frame_width - 1 || x1 < 0 || x1 > frame_width ||
347 y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) { 369 y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) {
348 uint8_t *buf_ptr1 = ref_frame + y0 * pre_buf->stride + x0; 370 uint8_t *buf_ptr1 = ref_frame + y0 * pre_buf->stride + x0;
349 // Extend the border. 371 // Extend the border.
350 build_mc_border(buf_ptr1, pre_buf->stride, xd->mc_buf, x1 - x0, 372 build_mc_border(buf_ptr1, pre_buf->stride, xd->mc_buf, x1 - x0 + 1,
351 x0, y0, x1 - x0, y1 - y0, frame_width, frame_height); 373 x0, y0, x1 - x0 + 1, y1 - y0 + 1, frame_width,
352 buf_stride = x1 - x0; 374 frame_height);
375 buf_stride = x1 - x0 + 1;
353 buf_ptr = xd->mc_buf + y_pad * 3 * buf_stride + x_pad * 3; 376 buf_ptr = xd->mc_buf + y_pad * 3 * buf_stride + x_pad * 3;
354 } 377 }
355 } 378 }
356 379
357 inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, 380 inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
358 subpel_y, sf, w, h, ref, xd->interp_kernel, xs, ys); 381 subpel_y, sf, w, h, ref, kernel, xs, ys);
359 } 382 }
360 } 383 }
361 384
362 void vp9_dec_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col, 385 void vp9_dec_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
363 BLOCK_SIZE bsize) { 386 BLOCK_SIZE bsize) {
364 int plane; 387 int plane;
365 const int mi_x = mi_col * MI_SIZE; 388 const int mi_x = mi_col * MI_SIZE;
366 const int mi_y = mi_row * MI_SIZE; 389 const int mi_y = mi_row * MI_SIZE;
367 for (plane = 0; plane < MAX_MB_PLANE; ++plane) { 390 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
368 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, 391 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize,
369 &xd->plane[plane]); 392 &xd->plane[plane]);
370 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; 393 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
371 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; 394 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
372 const int bw = 4 * num_4x4_w; 395 const int bw = 4 * num_4x4_w;
373 const int bh = 4 * num_4x4_h; 396 const int bh = 4 * num_4x4_h;
374 397
375 if (xd->mi_8x8[0]->mbmi.sb_type < BLOCK_8X8) { 398 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8) {
376 int i = 0, x, y; 399 int i = 0, x, y;
377 assert(bsize == BLOCK_8X8); 400 assert(bsize == BLOCK_8X8);
378 for (y = 0; y < num_4x4_h; ++y) 401 for (y = 0; y < num_4x4_h; ++y)
379 for (x = 0; x < num_4x4_w; ++x) 402 for (x = 0; x < num_4x4_w; ++x)
380 dec_build_inter_predictors(xd, plane, i++, 403 dec_build_inter_predictors(xd, plane, i++, bw, bh,
381 4 * x, 4 * y, 4, 4, mi_x, mi_y); 404 4 * x, 4 * y, 4, 4, mi_x, mi_y);
382 } else { 405 } else {
383 dec_build_inter_predictors(xd, plane, 0, 406 dec_build_inter_predictors(xd, plane, 0, bw, bh,
384 0, 0, bw, bh, mi_x, mi_y); 407 0, 0, bw, bh, mi_x, mi_y);
385 } 408 }
386 } 409 }
387 } 410 }
411
412 void vp9_setup_dst_planes(MACROBLOCKD *xd,
413 const YV12_BUFFER_CONFIG *src,
414 int mi_row, int mi_col) {
415 uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
416 src->alpha_buffer};
417 const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
418 src->alpha_stride};
419 int i;
420
421 for (i = 0; i < MAX_MB_PLANE; ++i) {
422 struct macroblockd_plane *const pd = &xd->plane[i];
423 setup_pred_plane(&pd->dst, buffers[i], strides[i], mi_row, mi_col, NULL,
424 pd->subsampling_x, pd->subsampling_y);
425 }
426 }
427
428 void vp9_setup_pre_planes(MACROBLOCKD *xd, int idx,
429 const YV12_BUFFER_CONFIG *src,
430 int mi_row, int mi_col,
431 const struct scale_factors *sf) {
432 if (src != NULL) {
433 int i;
434 uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
435 src->alpha_buffer};
436 const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
437 src->alpha_stride};
438
439 for (i = 0; i < MAX_MB_PLANE; ++i) {
440 struct macroblockd_plane *const pd = &xd->plane[i];
441 setup_pred_plane(&pd->pre[idx], buffers[i], strides[i], mi_row, mi_col,
442 sf, pd->subsampling_x, pd->subsampling_y);
443 }
444 }
445 }
OLDNEW
« no previous file with comments | « source/libvpx/vp9/common/vp9_reconinter.h ('k') | source/libvpx/vp9/common/vp9_reconintra.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698