2010-05-18 17:58:33 +02:00
/*
2010-09-09 14:16:39 +02:00
* Copyright ( c ) 2010 The WebM project authors . All Rights Reserved .
2010-05-18 17:58:33 +02:00
*
2010-06-09 17:29:20 +02:00
* Use of this source code is governed by a BSD - style license
2010-06-04 22:19:40 +02:00
* that can be found in the LICENSE file in the root of the source
* tree . An additional intellectual property rights grant can be found
2010-06-09 17:29:20 +02:00
* in the file PATENTS . All contributing project authors may
2010-06-04 22:19:40 +02:00
* be found in the AUTHORS file in the root of the source tree .
2010-05-18 17:58:33 +02:00
*/
2011-01-24 10:21:40 +01:00
# if !defined(WIN32) && CONFIG_OS_SUPPORT == 1
2010-05-18 17:58:33 +02:00
# include <unistd.h>
# endif
2010-07-29 23:04:39 +02:00
# ifdef __APPLE__
# include <mach/mach_init.h>
# endif
2010-05-18 17:58:33 +02:00
# include "onyxd_int.h"
# include "vpx_mem/vpx_mem.h"
# include "threading.h"
# include "loopfilter.h"
# include "extend.h"
# include "vpx_ports/vpx_timer.h"
2010-09-16 20:08:52 +02:00
# include "detokenize.h"
# include "reconinter.h"
# include "reconintra_mt.h"
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
extern void mb_init_dequantizer ( VP8D_COMP * pbi , MACROBLOCKD * xd ) ;
extern void clamp_mvs ( MACROBLOCKD * xd ) ;
2010-05-18 17:58:33 +02:00
extern void vp8_build_uvmvs ( MACROBLOCKD * x , int fullpixel ) ;
2010-09-16 20:08:52 +02:00
# if CONFIG_RUNTIME_CPU_DETECT
# define RTCD_VTABLE(x) (&(pbi)->common.rtcd.x)
# else
# define RTCD_VTABLE(x) NULL
# endif
2010-07-29 22:24:26 +02:00
2010-05-18 17:58:33 +02:00
void vp8_setup_decoding_thread_data ( VP8D_COMP * pbi , MACROBLOCKD * xd , MB_ROW_DEC * mbrd , int count )
{
# if CONFIG_MULTITHREAD
VP8_COMMON * const pc = & pbi - > common ;
int i , j ;
for ( i = 0 ; i < count ; i + + )
{
MACROBLOCKD * mbd = & mbrd [ i ] . mbd ;
# if CONFIG_RUNTIME_CPU_DETECT
mbd - > rtcd = xd - > rtcd ;
# endif
mbd - > subpixel_predict = xd - > subpixel_predict ;
mbd - > subpixel_predict8x4 = xd - > subpixel_predict8x4 ;
mbd - > subpixel_predict8x8 = xd - > subpixel_predict8x8 ;
mbd - > subpixel_predict16x16 = xd - > subpixel_predict16x16 ;
mbd - > mode_info_context = pc - > mi + pc - > mode_info_stride * ( i + 1 ) ;
mbd - > mode_info_stride = pc - > mode_info_stride ;
mbd - > frame_type = pc - > frame_type ;
mbd - > frames_since_golden = pc - > frames_since_golden ;
mbd - > frames_till_alt_ref_frame = pc - > frames_till_alt_ref_frame ;
2010-07-22 14:07:32 +02:00
mbd - > pre = pc - > yv12_fb [ pc - > lst_fb_idx ] ;
mbd - > dst = pc - > yv12_fb [ pc - > new_fb_idx ] ;
2010-05-18 17:58:33 +02:00
vp8_setup_block_dptrs ( mbd ) ;
vp8_build_block_doffsets ( mbd ) ;
mbd - > segmentation_enabled = xd - > segmentation_enabled ;
mbd - > mb_segement_abs_delta = xd - > mb_segement_abs_delta ;
vpx_memcpy ( mbd - > segment_feature_data , xd - > segment_feature_data , sizeof ( xd - > segment_feature_data ) ) ;
2010-10-28 01:04:02 +02:00
/*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/
2010-09-16 20:08:52 +02:00
vpx_memcpy ( mbd - > ref_lf_deltas , xd - > ref_lf_deltas , sizeof ( xd - > ref_lf_deltas ) ) ;
2010-10-28 01:04:02 +02:00
/*signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];*/
2010-09-16 20:08:52 +02:00
vpx_memcpy ( mbd - > mode_lf_deltas , xd - > mode_lf_deltas , sizeof ( xd - > mode_lf_deltas ) ) ;
2010-10-28 01:04:02 +02:00
/*unsigned char mode_ref_lf_delta_enabled;
unsigned char mode_ref_lf_delta_update ; */
2010-09-16 20:08:52 +02:00
mbd - > mode_ref_lf_delta_enabled = xd - > mode_ref_lf_delta_enabled ;
mbd - > mode_ref_lf_delta_update = xd - > mode_ref_lf_delta_update ;
2010-05-18 17:58:33 +02:00
mbd - > current_bc = & pbi - > bc2 ;
for ( j = 0 ; j < 25 ; j + + )
{
mbd - > block [ j ] . dequant = xd - > block [ j ] . dequant ;
}
}
2010-07-29 22:24:26 +02:00
for ( i = 0 ; i < pc - > mb_rows ; i + + )
2010-09-16 20:08:52 +02:00
pbi - > mt_current_mb_col [ i ] = - 1 ;
2010-05-18 17:58:33 +02:00
# else
( void ) pbi ;
( void ) xd ;
( void ) mbrd ;
( void ) count ;
# endif
}
2010-09-16 20:08:52 +02:00
void vp8mt_decode_macroblock ( VP8D_COMP * pbi , MACROBLOCKD * xd , int mb_row , int mb_col )
2010-07-29 22:24:26 +02:00
{
# if CONFIG_MULTITHREAD
2010-09-16 20:08:52 +02:00
int eobtotal = 0 ;
int i , do_clamp = xd - > mode_info_context - > mbmi . need_to_clamp_mvs ;
VP8_COMMON * pc = & pbi - > common ;
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
if ( xd - > mode_info_context - > mbmi . mb_skip_coeff )
2010-07-29 22:24:26 +02:00
{
2010-09-16 20:08:52 +02:00
vp8_reset_mb_tokens_context ( xd ) ;
}
else
{
eobtotal = vp8_decode_mb_tokens ( pbi , xd ) ;
}
2010-07-29 22:24:26 +02:00
2010-10-28 01:04:02 +02:00
/* Perform temporary clamping of the MV to be used for prediction */
2010-09-16 20:08:52 +02:00
if ( do_clamp )
{
clamp_mvs ( xd ) ;
}
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
xd - > mode_info_context - > mbmi . dc_diff = 1 ;
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
if ( xd - > mode_info_context - > mbmi . mode ! = B_PRED & & xd - > mode_info_context - > mbmi . mode ! = SPLITMV & & eobtotal = = 0 )
{
xd - > mode_info_context - > mbmi . dc_diff = 0 ;
2010-07-29 22:24:26 +02:00
2010-10-28 01:04:02 +02:00
/*mt_skip_recon_mb(pbi, xd, mb_row, mb_col);*/
2010-09-16 20:08:52 +02:00
if ( xd - > frame_type = = KEY_FRAME | | xd - > mode_info_context - > mbmi . ref_frame = = INTRA_FRAME )
{
vp8mt_build_intra_predictors_mbuv_s ( pbi , xd , mb_row , mb_col ) ;
vp8mt_build_intra_predictors_mby_s ( pbi , xd , mb_row , mb_col ) ;
}
else
{
vp8_build_inter_predictors_mb_s ( xd ) ;
}
return ;
}
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
if ( xd - > segmentation_enabled )
mb_init_dequantizer ( pbi , xd ) ;
2010-07-29 22:24:26 +02:00
2010-10-28 01:04:02 +02:00
/* do prediction */
2010-09-16 20:08:52 +02:00
if ( xd - > frame_type = = KEY_FRAME | | xd - > mode_info_context - > mbmi . ref_frame = = INTRA_FRAME )
{
vp8mt_build_intra_predictors_mbuv ( pbi , xd , mb_row , mb_col ) ;
if ( xd - > mode_info_context - > mbmi . mode ! = B_PRED )
{
vp8mt_build_intra_predictors_mby ( pbi , xd , mb_row , mb_col ) ;
} else {
vp8mt_intra_prediction_down_copy ( pbi , xd , mb_row , mb_col ) ;
}
}
else
{
vp8_build_inter_predictors_mb ( xd ) ;
}
2010-07-29 22:24:26 +02:00
2010-10-28 01:04:02 +02:00
/* dequantization and idct */
2010-09-16 20:08:52 +02:00
if ( xd - > mode_info_context - > mbmi . mode ! = B_PRED & & xd - > mode_info_context - > mbmi . mode ! = SPLITMV )
{
BLOCKD * b = & xd - > block [ 24 ] ;
DEQUANT_INVOKE ( & pbi - > dequant , block ) ( b ) ;
2010-07-29 22:24:26 +02:00
2010-10-28 01:04:02 +02:00
/* do 2nd order transform on the dc block */
2010-09-16 20:08:52 +02:00
if ( xd - > eobs [ 24 ] > 1 )
{
IDCT_INVOKE ( RTCD_VTABLE ( idct ) , iwalsh16 ) ( & b - > dqcoeff [ 0 ] , b - > diff ) ;
( ( int * ) b - > qcoeff ) [ 0 ] = 0 ;
( ( int * ) b - > qcoeff ) [ 1 ] = 0 ;
( ( int * ) b - > qcoeff ) [ 2 ] = 0 ;
( ( int * ) b - > qcoeff ) [ 3 ] = 0 ;
( ( int * ) b - > qcoeff ) [ 4 ] = 0 ;
( ( int * ) b - > qcoeff ) [ 5 ] = 0 ;
( ( int * ) b - > qcoeff ) [ 6 ] = 0 ;
( ( int * ) b - > qcoeff ) [ 7 ] = 0 ;
}
else
{
IDCT_INVOKE ( RTCD_VTABLE ( idct ) , iwalsh1 ) ( & b - > dqcoeff [ 0 ] , b - > diff ) ;
( ( int * ) b - > qcoeff ) [ 0 ] = 0 ;
}
DEQUANT_INVOKE ( & pbi - > dequant , dc_idct_add_y_block )
2010-10-22 02:04:30 +02:00
( xd - > qcoeff , xd - > block [ 0 ] . dequant ,
2010-09-16 20:08:52 +02:00
xd - > predictor , xd - > dst . y_buffer ,
xd - > dst . y_stride , xd - > eobs , xd - > block [ 24 ] . diff ) ;
2010-07-29 22:24:26 +02:00
}
2010-09-16 20:08:52 +02:00
else if ( ( xd - > frame_type = = KEY_FRAME | | xd - > mode_info_context - > mbmi . ref_frame = = INTRA_FRAME ) & & xd - > mode_info_context - > mbmi . mode = = B_PRED )
{
for ( i = 0 ; i < 16 ; i + + )
{
BLOCKD * b = & xd - > block [ i ] ;
vp8mt_predict_intra4x4 ( pbi , xd , b - > bmi . mode , b - > predictor , mb_row , mb_col , i ) ;
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
if ( xd - > eobs [ i ] > 1 )
{
DEQUANT_INVOKE ( & pbi - > dequant , idct_add )
2010-10-22 02:04:30 +02:00
( b - > qcoeff , b - > dequant , b - > predictor ,
2010-09-16 20:08:52 +02:00
* ( b - > base_dst ) + b - > dst , 16 , b - > dst_stride ) ;
}
else
{
IDCT_INVOKE ( RTCD_VTABLE ( idct ) , idct1_scalar_add )
2010-10-22 02:04:30 +02:00
( b - > qcoeff [ 0 ] * b - > dequant [ 0 ] , b - > predictor ,
2010-09-16 20:08:52 +02:00
* ( b - > base_dst ) + b - > dst , 16 , b - > dst_stride ) ;
( ( int * ) b - > qcoeff ) [ 0 ] = 0 ;
}
}
}
else
{
DEQUANT_INVOKE ( & pbi - > dequant , idct_add_y_block )
2010-10-22 02:04:30 +02:00
( xd - > qcoeff , xd - > block [ 0 ] . dequant ,
2010-09-16 20:08:52 +02:00
xd - > predictor , xd - > dst . y_buffer ,
xd - > dst . y_stride , xd - > eobs ) ;
}
DEQUANT_INVOKE ( & pbi - > dequant , idct_add_uv_block )
2010-10-22 02:04:30 +02:00
( xd - > qcoeff + 16 * 16 , xd - > block [ 16 ] . dequant ,
2010-09-16 20:08:52 +02:00
xd - > predictor + 16 * 16 , xd - > dst . u_buffer , xd - > dst . v_buffer ,
xd - > dst . uv_stride , xd - > eobs + 16 ) ;
2010-07-29 22:24:26 +02:00
# else
( void ) pbi ;
( void ) xd ;
2010-09-16 20:08:52 +02:00
( void ) mb_row ;
( void ) mb_col ;
2010-07-29 22:24:26 +02:00
# endif
}
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
2010-05-18 17:58:33 +02:00
THREAD_FUNCTION vp8_thread_decoding_proc ( void * p_data )
{
# if CONFIG_MULTITHREAD
int ithread = ( ( DECODETHREAD_DATA * ) p_data ) - > ithread ;
VP8D_COMP * pbi = ( VP8D_COMP * ) ( ( ( DECODETHREAD_DATA * ) p_data ) - > ptr1 ) ;
MB_ROW_DEC * mbrd = ( MB_ROW_DEC * ) ( ( ( DECODETHREAD_DATA * ) p_data ) - > ptr2 ) ;
2010-08-31 16:49:57 +02:00
ENTROPY_CONTEXT_PLANES mb_row_left_context ;
2010-05-18 17:58:33 +02:00
while ( 1 )
{
if ( pbi - > b_multithreaded_rd = = 0 )
break ;
2010-10-28 01:04:02 +02:00
/*if(WaitForSingleObject(pbi->h_event_start_decoding[ithread], INFINITE) == WAIT_OBJECT_0)*/
2010-07-29 22:24:26 +02:00
if ( sem_wait ( & pbi - > h_event_start_decoding [ ithread ] ) = = 0 )
2010-05-18 17:58:33 +02:00
{
if ( pbi - > b_multithreaded_rd = = 0 )
break ;
else
{
VP8_COMMON * pc = & pbi - > common ;
MACROBLOCKD * xd = & mbrd - > mbd ;
2010-07-29 22:24:26 +02:00
int mb_row ;
int num_part = 1 < < pbi - > common . multi_token_partition ;
2010-05-18 17:58:33 +02:00
volatile int * last_row_current_mb_col ;
2010-09-23 19:53:09 +02:00
int nsync = pbi - > sync_range ;
2010-05-18 17:58:33 +02:00
2010-07-29 22:24:26 +02:00
for ( mb_row = ithread + 1 ; mb_row < pc - > mb_rows ; mb_row + = ( pbi - > decoding_thread_count + 1 ) )
2010-05-18 17:58:33 +02:00
{
2010-07-29 22:24:26 +02:00
int i ;
int recon_yoffset , recon_uvoffset ;
int mb_col ;
int ref_fb_idx = pc - > lst_fb_idx ;
int dst_fb_idx = pc - > new_fb_idx ;
int recon_y_stride = pc - > yv12_fb [ ref_fb_idx ] . y_stride ;
int recon_uv_stride = pc - > yv12_fb [ ref_fb_idx ] . uv_stride ;
2010-09-16 20:08:52 +02:00
int filter_level ;
loop_filter_info * lfi = pc - > lf_info ;
int alt_flt_enabled = xd - > segmentation_enabled ;
int Segment ;
2010-07-29 22:24:26 +02:00
pbi - > mb_row_di [ ithread ] . mb_row = mb_row ;
pbi - > mb_row_di [ ithread ] . mbd . current_bc = & pbi - > mbc [ mb_row % num_part ] ;
2010-09-16 20:08:52 +02:00
last_row_current_mb_col = & pbi - > mt_current_mb_col [ mb_row - 1 ] ;
2010-07-29 22:24:26 +02:00
recon_yoffset = mb_row * recon_y_stride * 16 ;
recon_uvoffset = mb_row * recon_uv_stride * 8 ;
2010-10-28 01:04:02 +02:00
/* reset above block coeffs */
2010-07-29 22:24:26 +02:00
2010-08-31 16:49:57 +02:00
xd - > above_context = pc - > above_context ;
xd - > left_context = & mb_row_left_context ;
vpx_memset ( & mb_row_left_context , 0 , sizeof ( mb_row_left_context ) ) ;
2010-07-29 22:24:26 +02:00
xd - > up_available = ( mb_row ! = 0 ) ;
xd - > mb_to_top_edge = - ( ( mb_row * 16 ) ) < < 3 ;
xd - > mb_to_bottom_edge = ( ( pc - > mb_rows - 1 - mb_row ) * 16 ) < < 3 ;
for ( mb_col = 0 ; mb_col < pc - > mb_cols ; mb_col + + )
2010-05-18 17:58:33 +02:00
{
2010-09-23 19:53:09 +02:00
if ( ( mb_col & ( nsync - 1 ) ) = = 0 )
2010-07-29 22:24:26 +02:00
{
2010-09-23 19:53:09 +02:00
while ( mb_col > ( * last_row_current_mb_col - nsync ) & & * last_row_current_mb_col ! = pc - > mb_cols - 1 )
2010-07-29 22:24:26 +02:00
{
x86_pause_hint ( ) ;
thread_sleep ( 0 ) ;
}
}
2010-05-18 17:58:33 +02:00
2010-08-12 22:25:43 +02:00
if ( xd - > mode_info_context - > mbmi . mode = = SPLITMV | | xd - > mode_info_context - > mbmi . mode = = B_PRED )
2010-05-18 17:58:33 +02:00
{
2010-07-29 22:24:26 +02:00
for ( i = 0 ; i < 16 ; i + + )
{
BLOCKD * d = & xd - > block [ i ] ;
vpx_memcpy ( & d - > bmi , & xd - > mode_info_context - > bmi [ i ] , sizeof ( B_MODE_INFO ) ) ;
}
2010-05-18 17:58:33 +02:00
}
2010-09-16 20:08:52 +02:00
if ( pbi - > common . filter_level )
{
2010-10-28 01:04:02 +02:00
/*update loopfilter info*/
2010-09-16 20:08:52 +02:00
Segment = ( alt_flt_enabled ) ? xd - > mode_info_context - > mbmi . segment_id : 0 ;
filter_level = pbi - > mt_baseline_filter_level [ Segment ] ;
2010-10-28 01:04:02 +02:00
/* Distance of Mb to the various image edges.
* These are specified to 8 th pel as they are always compared to values that are in 1 / 8 th pel units
* Apply any context driven MB level adjustment
*/
2010-09-16 20:08:52 +02:00
vp8_adjust_mb_lf_value ( xd , & filter_level ) ;
}
2010-10-28 01:04:02 +02:00
/* Distance of Mb to the various image edges.
* These are specified to 8 th pel as they are always compared to values that are in 1 / 8 th pel units
*/
2010-07-29 22:24:26 +02:00
xd - > mb_to_left_edge = - ( ( mb_col * 16 ) < < 3 ) ;
xd - > mb_to_right_edge = ( ( pc - > mb_cols - 1 - mb_col ) * 16 ) < < 3 ;
2010-05-18 17:58:33 +02:00
2010-07-29 22:24:26 +02:00
xd - > dst . y_buffer = pc - > yv12_fb [ dst_fb_idx ] . y_buffer + recon_yoffset ;
xd - > dst . u_buffer = pc - > yv12_fb [ dst_fb_idx ] . u_buffer + recon_uvoffset ;
xd - > dst . v_buffer = pc - > yv12_fb [ dst_fb_idx ] . v_buffer + recon_uvoffset ;
2010-05-18 17:58:33 +02:00
2010-07-29 22:24:26 +02:00
xd - > left_available = ( mb_col ! = 0 ) ;
2010-07-22 14:07:32 +02:00
2010-10-28 01:04:02 +02:00
/* Select the appropriate reference frame for this MB */
2010-08-12 22:25:43 +02:00
if ( xd - > mode_info_context - > mbmi . ref_frame = = LAST_FRAME )
2010-07-29 22:24:26 +02:00
ref_fb_idx = pc - > lst_fb_idx ;
2010-08-12 22:25:43 +02:00
else if ( xd - > mode_info_context - > mbmi . ref_frame = = GOLDEN_FRAME )
2010-07-29 22:24:26 +02:00
ref_fb_idx = pc - > gld_fb_idx ;
else
ref_fb_idx = pc - > alt_fb_idx ;
2010-05-18 17:58:33 +02:00
2010-07-29 22:24:26 +02:00
xd - > pre . y_buffer = pc - > yv12_fb [ ref_fb_idx ] . y_buffer + recon_yoffset ;
xd - > pre . u_buffer = pc - > yv12_fb [ ref_fb_idx ] . u_buffer + recon_uvoffset ;
xd - > pre . v_buffer = pc - > yv12_fb [ ref_fb_idx ] . v_buffer + recon_uvoffset ;
2010-05-18 17:58:33 +02:00
2010-07-29 22:24:26 +02:00
vp8_build_uvmvs ( xd , pc - > full_pixel ) ;
2010-09-16 20:08:52 +02:00
vp8mt_decode_macroblock ( pbi , xd , mb_row , mb_col ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
if ( pbi - > common . filter_level )
{
if ( mb_row ! = pc - > mb_rows - 1 )
{
2010-10-28 01:04:02 +02:00
/* Save decoded MB last row data for next-row decoding */
2010-09-16 20:08:52 +02:00
vpx_memcpy ( ( pbi - > mt_yabove_row [ mb_row + 1 ] + 32 + mb_col * 16 ) , ( xd - > dst . y_buffer + 15 * recon_y_stride ) , 16 ) ;
vpx_memcpy ( ( pbi - > mt_uabove_row [ mb_row + 1 ] + 16 + mb_col * 8 ) , ( xd - > dst . u_buffer + 7 * recon_uv_stride ) , 8 ) ;
vpx_memcpy ( ( pbi - > mt_vabove_row [ mb_row + 1 ] + 16 + mb_col * 8 ) , ( xd - > dst . v_buffer + 7 * recon_uv_stride ) , 8 ) ;
}
2010-10-28 01:04:02 +02:00
/* save left_col for next MB decoding */
2010-09-16 20:08:52 +02:00
if ( mb_col ! = pc - > mb_cols - 1 )
{
MODE_INFO * next = xd - > mode_info_context + 1 ;
if ( xd - > frame_type = = KEY_FRAME | | next - > mbmi . ref_frame = = INTRA_FRAME )
{
for ( i = 0 ; i < 16 ; i + + )
pbi - > mt_yleft_col [ mb_row ] [ i ] = xd - > dst . y_buffer [ i * recon_y_stride + 15 ] ;
for ( i = 0 ; i < 8 ; i + + )
{
pbi - > mt_uleft_col [ mb_row ] [ i ] = xd - > dst . u_buffer [ i * recon_uv_stride + 7 ] ;
pbi - > mt_vleft_col [ mb_row ] [ i ] = xd - > dst . v_buffer [ i * recon_uv_stride + 7 ] ;
}
}
}
2010-10-28 01:04:02 +02:00
/* loopfilter on this macroblock. */
2010-09-16 20:08:52 +02:00
if ( filter_level )
{
if ( mb_col > 0 )
pc - > lf_mbv ( xd - > dst . y_buffer , xd - > dst . u_buffer , xd - > dst . v_buffer , recon_y_stride , recon_uv_stride , & lfi [ filter_level ] , pc - > simpler_lpf ) ;
if ( xd - > mode_info_context - > mbmi . dc_diff > 0 )
pc - > lf_bv ( xd - > dst . y_buffer , xd - > dst . u_buffer , xd - > dst . v_buffer , recon_y_stride , recon_uv_stride , & lfi [ filter_level ] , pc - > simpler_lpf ) ;
2010-10-28 01:04:02 +02:00
/* don't apply across umv border */
2010-09-16 20:08:52 +02:00
if ( mb_row > 0 )
pc - > lf_mbh ( xd - > dst . y_buffer , xd - > dst . u_buffer , xd - > dst . v_buffer , recon_y_stride , recon_uv_stride , & lfi [ filter_level ] , pc - > simpler_lpf ) ;
if ( xd - > mode_info_context - > mbmi . dc_diff > 0 )
pc - > lf_bh ( xd - > dst . y_buffer , xd - > dst . u_buffer , xd - > dst . v_buffer , recon_y_stride , recon_uv_stride , & lfi [ filter_level ] , pc - > simpler_lpf ) ;
}
}
2010-05-18 17:58:33 +02:00
2010-07-29 22:24:26 +02:00
recon_yoffset + = 16 ;
recon_uvoffset + = 8 ;
2010-05-18 17:58:33 +02:00
2010-07-29 22:24:26 +02:00
+ + xd - > mode_info_context ; /* next mb */
2010-05-18 17:58:33 +02:00
2010-08-31 16:49:57 +02:00
xd - > above_context + + ;
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/*pbi->mb_row_di[ithread].current_mb_col = mb_col;*/
2010-09-16 20:08:52 +02:00
pbi - > mt_current_mb_col [ mb_row ] = mb_col ;
2010-07-29 22:24:26 +02:00
}
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* adjust to the next row of mbs */
2010-09-16 20:08:52 +02:00
if ( pbi - > common . filter_level )
{
if ( mb_row ! = pc - > mb_rows - 1 )
{
int lasty = pc - > yv12_fb [ ref_fb_idx ] . y_width + VP8BORDERINPIXELS ;
int lastuv = ( pc - > yv12_fb [ ref_fb_idx ] . y_width > > 1 ) + ( VP8BORDERINPIXELS > > 1 ) ;
for ( i = 0 ; i < 4 ; i + + )
{
pbi - > mt_yabove_row [ mb_row + 1 ] [ lasty + i ] = pbi - > mt_yabove_row [ mb_row + 1 ] [ lasty - 1 ] ;
pbi - > mt_uabove_row [ mb_row + 1 ] [ lastuv + i ] = pbi - > mt_uabove_row [ mb_row + 1 ] [ lastuv - 1 ] ;
pbi - > mt_vabove_row [ mb_row + 1 ] [ lastuv + i ] = pbi - > mt_vabove_row [ mb_row + 1 ] [ lastuv - 1 ] ;
}
}
} else
vp8_extend_mb_row ( & pc - > yv12_fb [ dst_fb_idx ] , xd - > dst . y_buffer + 16 , xd - > dst . u_buffer + 8 , xd - > dst . v_buffer + 8 ) ;
2010-05-18 17:58:33 +02:00
2010-07-29 22:24:26 +02:00
+ + xd - > mode_info_context ; /* skip prediction column */
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* since we have multithread */
2010-07-29 22:24:26 +02:00
xd - > mode_info_context + = xd - > mode_info_stride * pbi - > decoding_thread_count ;
2010-05-18 17:58:33 +02:00
}
}
}
2010-10-28 01:04:02 +02:00
/* add this to each frame */
2010-07-29 22:24:26 +02:00
if ( ( mbrd - > mb_row = = pbi - > common . mb_rows - 1 ) | | ( ( mbrd - > mb_row = = pbi - > common . mb_rows - 2 ) & & ( pbi - > common . mb_rows % ( pbi - > decoding_thread_count + 1 ) ) = = 1 ) )
{
2010-10-28 01:04:02 +02:00
/*SetEvent(pbi->h_event_end_decoding);*/
2010-07-29 22:24:26 +02:00
sem_post ( & pbi - > h_event_end_decoding ) ;
}
}
2010-05-18 17:58:33 +02:00
# else
( void ) p_data ;
# endif
return 0 ;
}
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
void vp8_decoder_create_threads ( VP8D_COMP * pbi )
2010-05-18 17:58:33 +02:00
{
# if CONFIG_MULTITHREAD
2010-09-16 20:08:52 +02:00
int core_count = 0 ;
int ithread ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
pbi - > b_multithreaded_rd = 0 ;
pbi - > allocated_decoding_thread_count = 0 ;
core_count = ( pbi - > max_threads > 16 ) ? 16 : pbi - > max_threads ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
if ( core_count > 1 )
{
pbi - > b_multithreaded_rd = 1 ;
pbi - > decoding_thread_count = core_count - 1 ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
CHECK_MEM_ERROR ( pbi - > h_decoding_thread , vpx_malloc ( sizeof ( pthread_t ) * pbi - > decoding_thread_count ) ) ;
CHECK_MEM_ERROR ( pbi - > h_event_start_decoding , vpx_malloc ( sizeof ( sem_t ) * pbi - > decoding_thread_count ) ) ;
CHECK_MEM_ERROR ( pbi - > mb_row_di , vpx_memalign ( 32 , sizeof ( MB_ROW_DEC ) * pbi - > decoding_thread_count ) ) ;
vpx_memset ( pbi - > mb_row_di , 0 , sizeof ( MB_ROW_DEC ) * pbi - > decoding_thread_count ) ;
CHECK_MEM_ERROR ( pbi - > de_thread_data , vpx_malloc ( sizeof ( DECODETHREAD_DATA ) * pbi - > decoding_thread_count ) ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
for ( ithread = 0 ; ithread < pbi - > decoding_thread_count ; ithread + + )
{
sem_init ( & pbi - > h_event_start_decoding [ ithread ] , 0 , 0 ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
pbi - > de_thread_data [ ithread ] . ithread = ithread ;
pbi - > de_thread_data [ ithread ] . ptr1 = ( void * ) pbi ;
pbi - > de_thread_data [ ithread ] . ptr2 = ( void * ) & pbi - > mb_row_di [ ithread ] ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
pthread_create ( & pbi - > h_decoding_thread [ ithread ] , 0 , vp8_thread_decoding_proc , ( & pbi - > de_thread_data [ ithread ] ) ) ;
}
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
sem_init ( & pbi - > h_event_end_decoding , 0 , 0 ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
pbi - > allocated_decoding_thread_count = pbi - > decoding_thread_count ;
}
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
# else
( void ) pbi ;
# endif
}
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
void vp8mt_de_alloc_temp_buffers ( VP8D_COMP * pbi , int mb_rows )
{
# if CONFIG_MULTITHREAD
VP8_COMMON * const pc = & pbi - > common ;
int i ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
if ( pbi - > b_multithreaded_rd )
{
if ( pbi - > mt_current_mb_col )
{
vpx_free ( pbi - > mt_current_mb_col ) ;
pbi - > mt_current_mb_col = NULL ;
}
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* Free above_row buffers. */
2010-09-16 20:08:52 +02:00
if ( pbi - > mt_yabove_row )
{
for ( i = 0 ; i < mb_rows ; i + + )
{
if ( pbi - > mt_yabove_row [ i ] )
{
vpx_free ( pbi - > mt_yabove_row [ i ] ) ;
pbi - > mt_yabove_row [ i ] = NULL ;
}
}
vpx_free ( pbi - > mt_yabove_row ) ;
pbi - > mt_yabove_row = NULL ;
}
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
if ( pbi - > mt_uabove_row )
{
for ( i = 0 ; i < mb_rows ; i + + )
{
if ( pbi - > mt_uabove_row [ i ] )
{
vpx_free ( pbi - > mt_uabove_row [ i ] ) ;
pbi - > mt_uabove_row [ i ] = NULL ;
}
}
vpx_free ( pbi - > mt_uabove_row ) ;
pbi - > mt_uabove_row = NULL ;
}
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
if ( pbi - > mt_vabove_row )
{
for ( i = 0 ; i < mb_rows ; i + + )
{
if ( pbi - > mt_vabove_row [ i ] )
{
vpx_free ( pbi - > mt_vabove_row [ i ] ) ;
pbi - > mt_vabove_row [ i ] = NULL ;
}
}
vpx_free ( pbi - > mt_vabove_row ) ;
pbi - > mt_vabove_row = NULL ;
}
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* Free left_col buffers. */
2010-09-16 20:08:52 +02:00
if ( pbi - > mt_yleft_col )
{
for ( i = 0 ; i < mb_rows ; i + + )
{
if ( pbi - > mt_yleft_col [ i ] )
{
vpx_free ( pbi - > mt_yleft_col [ i ] ) ;
pbi - > mt_yleft_col [ i ] = NULL ;
}
}
vpx_free ( pbi - > mt_yleft_col ) ;
pbi - > mt_yleft_col = NULL ;
}
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
if ( pbi - > mt_uleft_col )
{
for ( i = 0 ; i < mb_rows ; i + + )
{
if ( pbi - > mt_uleft_col [ i ] )
{
vpx_free ( pbi - > mt_uleft_col [ i ] ) ;
pbi - > mt_uleft_col [ i ] = NULL ;
2010-07-29 22:24:26 +02:00
}
}
2010-09-16 20:08:52 +02:00
vpx_free ( pbi - > mt_uleft_col ) ;
pbi - > mt_uleft_col = NULL ;
2010-05-18 17:58:33 +02:00
}
2010-09-16 20:08:52 +02:00
if ( pbi - > mt_vleft_col )
2010-07-29 22:24:26 +02:00
{
2010-09-16 20:08:52 +02:00
for ( i = 0 ; i < mb_rows ; i + + )
{
if ( pbi - > mt_vleft_col [ i ] )
{
vpx_free ( pbi - > mt_vleft_col [ i ] ) ;
pbi - > mt_vleft_col [ i ] = NULL ;
}
}
vpx_free ( pbi - > mt_vleft_col ) ;
pbi - > mt_vleft_col = NULL ;
2010-07-29 22:24:26 +02:00
}
2010-09-16 20:08:52 +02:00
}
2010-05-18 17:58:33 +02:00
# else
2010-07-29 22:24:26 +02:00
( void ) pbi ;
2010-05-18 17:58:33 +02:00
# endif
}
2010-09-16 20:08:52 +02:00
2010-11-17 15:13:54 +01:00
void vp8mt_alloc_temp_buffers ( VP8D_COMP * pbi , int width , int prev_mb_rows )
2010-05-18 17:58:33 +02:00
{
# if CONFIG_MULTITHREAD
2010-09-16 20:08:52 +02:00
VP8_COMMON * const pc = & pbi - > common ;
int i ;
int uv_width ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
if ( pbi - > b_multithreaded_rd )
2010-05-18 17:58:33 +02:00
{
2010-09-16 20:08:52 +02:00
vp8mt_de_alloc_temp_buffers ( pbi , prev_mb_rows ) ;
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* our internal buffers are always multiples of 16 */
2010-09-16 20:08:52 +02:00
if ( ( width & 0xf ) ! = 0 )
width + = 16 - ( width & 0xf ) ;
2010-05-18 17:58:33 +02:00
2010-09-23 19:53:09 +02:00
if ( width < 640 ) pbi - > sync_range = 1 ;
else if ( width < = 1280 ) pbi - > sync_range = 8 ;
else if ( width < = 2560 ) pbi - > sync_range = 16 ;
else pbi - > sync_range = 32 ;
2010-09-16 20:08:52 +02:00
uv_width = width > > 1 ;
2010-07-29 22:24:26 +02:00
2010-10-28 01:04:02 +02:00
/* Allocate an int for each mb row. */
2010-09-16 20:08:52 +02:00
CHECK_MEM_ERROR ( pbi - > mt_current_mb_col , vpx_malloc ( sizeof ( int ) * pc - > mb_rows ) ) ;
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* Allocate memory for above_row buffers. */
2010-09-16 20:08:52 +02:00
CHECK_MEM_ERROR ( pbi - > mt_yabove_row , vpx_malloc ( sizeof ( unsigned char * ) * pc - > mb_rows ) ) ;
for ( i = 0 ; i < pc - > mb_rows ; i + + )
CHECK_MEM_ERROR ( pbi - > mt_yabove_row [ i ] , vpx_calloc ( sizeof ( unsigned char ) * ( width + ( VP8BORDERINPIXELS < < 1 ) ) , 1 ) ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
CHECK_MEM_ERROR ( pbi - > mt_uabove_row , vpx_malloc ( sizeof ( unsigned char * ) * pc - > mb_rows ) ) ;
for ( i = 0 ; i < pc - > mb_rows ; i + + )
CHECK_MEM_ERROR ( pbi - > mt_uabove_row [ i ] , vpx_calloc ( sizeof ( unsigned char ) * ( uv_width + VP8BORDERINPIXELS ) , 1 ) ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
CHECK_MEM_ERROR ( pbi - > mt_vabove_row , vpx_malloc ( sizeof ( unsigned char * ) * pc - > mb_rows ) ) ;
for ( i = 0 ; i < pc - > mb_rows ; i + + )
CHECK_MEM_ERROR ( pbi - > mt_vabove_row [ i ] , vpx_calloc ( sizeof ( unsigned char ) * ( uv_width + VP8BORDERINPIXELS ) , 1 ) ) ;
2010-07-29 22:24:26 +02:00
2010-10-28 01:04:02 +02:00
/* Allocate memory for left_col buffers. */
2010-09-16 20:08:52 +02:00
CHECK_MEM_ERROR ( pbi - > mt_yleft_col , vpx_malloc ( sizeof ( unsigned char * ) * pc - > mb_rows ) ) ;
for ( i = 0 ; i < pc - > mb_rows ; i + + )
CHECK_MEM_ERROR ( pbi - > mt_yleft_col [ i ] , vpx_calloc ( sizeof ( unsigned char ) * 16 , 1 ) ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
CHECK_MEM_ERROR ( pbi - > mt_uleft_col , vpx_malloc ( sizeof ( unsigned char * ) * pc - > mb_rows ) ) ;
for ( i = 0 ; i < pc - > mb_rows ; i + + )
CHECK_MEM_ERROR ( pbi - > mt_uleft_col [ i ] , vpx_calloc ( sizeof ( unsigned char ) * 8 , 1 ) ) ;
CHECK_MEM_ERROR ( pbi - > mt_vleft_col , vpx_malloc ( sizeof ( unsigned char * ) * pc - > mb_rows ) ) ;
for ( i = 0 ; i < pc - > mb_rows ; i + + )
CHECK_MEM_ERROR ( pbi - > mt_vleft_col [ i ] , vpx_calloc ( sizeof ( unsigned char ) * 8 , 1 ) ) ;
}
2010-05-18 17:58:33 +02:00
# else
( void ) pbi ;
2010-09-16 20:08:52 +02:00
( void ) width ;
2010-05-18 17:58:33 +02:00
# endif
}
2010-09-16 20:08:52 +02:00
2010-05-18 17:58:33 +02:00
void vp8_decoder_remove_threads ( VP8D_COMP * pbi )
{
# if CONFIG_MULTITHREAD
2010-10-28 01:04:02 +02:00
/* shutdown MB Decoding thread; */
2010-05-18 17:58:33 +02:00
if ( pbi - > b_multithreaded_rd )
{
2010-07-29 22:24:26 +02:00
int i ;
2010-05-18 17:58:33 +02:00
pbi - > b_multithreaded_rd = 0 ;
2010-07-29 22:24:26 +02:00
2010-10-28 01:04:02 +02:00
/* allow all threads to exit */
2010-07-29 22:24:26 +02:00
for ( i = 0 ; i < pbi - > allocated_decoding_thread_count ; i + + )
2010-05-18 17:58:33 +02:00
{
2010-07-29 22:24:26 +02:00
sem_post ( & pbi - > h_event_start_decoding [ i ] ) ;
pthread_join ( pbi - > h_decoding_thread [ i ] , NULL ) ;
2010-05-18 17:58:33 +02:00
}
2010-07-29 22:24:26 +02:00
for ( i = 0 ; i < pbi - > allocated_decoding_thread_count ; i + + )
{
sem_destroy ( & pbi - > h_event_start_decoding [ i ] ) ;
2010-05-18 17:58:33 +02:00
}
2010-07-29 22:24:26 +02:00
sem_destroy ( & pbi - > h_event_end_decoding ) ;
2010-05-18 17:58:33 +02:00
if ( pbi - > h_decoding_thread )
{
vpx_free ( pbi - > h_decoding_thread ) ;
pbi - > h_decoding_thread = NULL ;
}
2010-07-29 22:24:26 +02:00
if ( pbi - > h_event_start_decoding )
2010-05-18 17:58:33 +02:00
{
2010-07-29 22:24:26 +02:00
vpx_free ( pbi - > h_event_start_decoding ) ;
pbi - > h_event_start_decoding = NULL ;
}
2010-05-18 17:58:33 +02:00
if ( pbi - > mb_row_di )
{
vpx_free ( pbi - > mb_row_di ) ;
pbi - > mb_row_di = NULL ;
}
if ( pbi - > de_thread_data )
{
vpx_free ( pbi - > de_thread_data ) ;
pbi - > de_thread_data = NULL ;
}
2010-07-29 22:24:26 +02:00
}
2010-05-18 17:58:33 +02:00
# else
( void ) pbi ;
# endif
}
2010-09-16 20:08:52 +02:00
void vp8mt_lpf_init ( VP8D_COMP * pbi , int default_filt_lvl )
2010-05-18 17:58:33 +02:00
{
# if CONFIG_MULTITHREAD
2010-09-16 20:08:52 +02:00
VP8_COMMON * cm = & pbi - > common ;
MACROBLOCKD * mbd = & pbi - > mb ;
2010-10-28 01:04:02 +02:00
/*YV12_BUFFER_CONFIG *post = &cm->new_frame;*/ /*frame_to_show;*/
2010-09-16 20:08:52 +02:00
loop_filter_info * lfi = cm - > lf_info ;
2010-10-28 01:04:02 +02:00
FRAME_TYPE frame_type = cm - > frame_type ;
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/*int mb_row;
int mb_col ;
int baseline_filter_level [ MAX_MB_SEGMENTS ] ; */
2010-09-16 20:08:52 +02:00
int alt_flt_enabled = mbd - > segmentation_enabled ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
int i ;
2010-10-28 01:04:02 +02:00
/*unsigned char *y_ptr, *u_ptr, *v_ptr;*/
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* Note the baseline filter values for each segment */
2010-09-16 20:08:52 +02:00
if ( alt_flt_enabled )
{
for ( i = 0 ; i < MAX_MB_SEGMENTS ; i + + )
{
2010-10-28 01:04:02 +02:00
/* Abs value */
2010-09-16 20:08:52 +02:00
if ( mbd - > mb_segement_abs_delta = = SEGMENT_ABSDATA )
pbi - > mt_baseline_filter_level [ i ] = mbd - > segment_feature_data [ MB_LVL_ALT_LF ] [ i ] ;
2010-10-28 01:04:02 +02:00
/* Delta Value */
2010-09-16 20:08:52 +02:00
else
{
pbi - > mt_baseline_filter_level [ i ] = default_filt_lvl + mbd - > segment_feature_data [ MB_LVL_ALT_LF ] [ i ] ;
2010-10-28 01:04:02 +02:00
pbi - > mt_baseline_filter_level [ i ] = ( pbi - > mt_baseline_filter_level [ i ] > = 0 ) ? ( ( pbi - > mt_baseline_filter_level [ i ] < = MAX_LOOP_FILTER ) ? pbi - > mt_baseline_filter_level [ i ] : MAX_LOOP_FILTER ) : 0 ; /* Clamp to valid range */
2010-09-16 20:08:52 +02:00
}
}
}
else
{
for ( i = 0 ; i < MAX_MB_SEGMENTS ; i + + )
pbi - > mt_baseline_filter_level [ i ] = default_filt_lvl ;
}
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* Initialize the loop filter for this frame. */
2010-09-16 20:08:52 +02:00
if ( ( cm - > last_filter_type ! = cm - > filter_type ) | | ( cm - > last_sharpness_level ! = cm - > sharpness_level ) )
vp8_init_loop_filter ( cm ) ;
else if ( frame_type ! = cm - > last_frame_type )
vp8_frame_init_loop_filter ( lfi , frame_type ) ;
2010-05-18 17:58:33 +02:00
# else
( void ) pbi ;
2010-09-16 20:08:52 +02:00
( void ) default_filt_lvl ;
2010-05-18 17:58:33 +02:00
# endif
}
2010-09-16 20:08:52 +02:00
void vp8mt_decode_mb_rows ( VP8D_COMP * pbi , MACROBLOCKD * xd )
2010-05-18 17:58:33 +02:00
{
# if CONFIG_MULTITHREAD
int mb_row ;
VP8_COMMON * pc = & pbi - > common ;
int ibc = 0 ;
int num_part = 1 < < pbi - > common . multi_token_partition ;
2011-01-11 13:01:24 +01:00
int i ;
2010-07-29 22:24:26 +02:00
volatile int * last_row_current_mb_col = NULL ;
2010-09-23 19:53:09 +02:00
int nsync = pbi - > sync_range ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
int filter_level ;
loop_filter_info * lfi = pc - > lf_info ;
int alt_flt_enabled = xd - > segmentation_enabled ;
int Segment ;
if ( pbi - > common . filter_level )
{
2010-10-28 01:04:02 +02:00
/* Set above_row buffer to 127 for decoding first MB row */
2010-09-16 20:08:52 +02:00
vpx_memset ( pbi - > mt_yabove_row [ 0 ] + VP8BORDERINPIXELS - 1 , 127 , pc - > yv12_fb [ pc - > lst_fb_idx ] . y_width + 5 ) ;
vpx_memset ( pbi - > mt_uabove_row [ 0 ] + ( VP8BORDERINPIXELS > > 1 ) - 1 , 127 , ( pc - > yv12_fb [ pc - > lst_fb_idx ] . y_width > > 1 ) + 5 ) ;
vpx_memset ( pbi - > mt_vabove_row [ 0 ] + ( VP8BORDERINPIXELS > > 1 ) - 1 , 127 , ( pc - > yv12_fb [ pc - > lst_fb_idx ] . y_width > > 1 ) + 5 ) ;
for ( i = 1 ; i < pc - > mb_rows ; i + + )
{
vpx_memset ( pbi - > mt_yabove_row [ i ] + VP8BORDERINPIXELS - 1 , ( unsigned char ) 129 , 1 ) ;
vpx_memset ( pbi - > mt_uabove_row [ i ] + ( VP8BORDERINPIXELS > > 1 ) - 1 , ( unsigned char ) 129 , 1 ) ;
vpx_memset ( pbi - > mt_vabove_row [ i ] + ( VP8BORDERINPIXELS > > 1 ) - 1 , ( unsigned char ) 129 , 1 ) ;
}
2010-10-28 01:04:02 +02:00
/* Set left_col to 129 initially */
2010-09-16 20:08:52 +02:00
for ( i = 0 ; i < pc - > mb_rows ; i + + )
{
vpx_memset ( pbi - > mt_yleft_col [ i ] , ( unsigned char ) 129 , 16 ) ;
vpx_memset ( pbi - > mt_uleft_col [ i ] , ( unsigned char ) 129 , 8 ) ;
vpx_memset ( pbi - > mt_vleft_col [ i ] , ( unsigned char ) 129 , 8 ) ;
}
vp8mt_lpf_init ( pbi , pc - > filter_level ) ;
}
2010-05-18 17:58:33 +02:00
vp8_setup_decoding_thread_data ( pbi , xd , pbi - > mb_row_di , pbi - > decoding_thread_count ) ;
2010-07-29 22:24:26 +02:00
for ( i = 0 ; i < pbi - > decoding_thread_count ; i + + )
sem_post ( & pbi - > h_event_start_decoding [ i ] ) ;
2010-05-18 17:58:33 +02:00
for ( mb_row = 0 ; mb_row < pc - > mb_rows ; mb_row + = ( pbi - > decoding_thread_count + 1 ) )
{
2010-07-29 22:24:26 +02:00
xd - > current_bc = & pbi - > mbc [ mb_row % num_part ] ;
2010-05-18 17:58:33 +02:00
2010-10-28 01:04:02 +02:00
/* vp8_decode_mb_row(pbi, pc, mb_row, xd); */
2010-05-18 17:58:33 +02:00
{
2010-07-29 22:24:26 +02:00
int i ;
int recon_yoffset , recon_uvoffset ;
int mb_col ;
int ref_fb_idx = pc - > lst_fb_idx ;
int dst_fb_idx = pc - > new_fb_idx ;
int recon_y_stride = pc - > yv12_fb [ ref_fb_idx ] . y_stride ;
int recon_uv_stride = pc - > yv12_fb [ ref_fb_idx ] . uv_stride ;
2010-10-28 01:04:02 +02:00
/* volatile int *last_row_current_mb_col = NULL; */
2010-07-29 22:24:26 +02:00
if ( mb_row > 0 )
2010-09-16 20:08:52 +02:00
last_row_current_mb_col = & pbi - > mt_current_mb_col [ mb_row - 1 ] ;
2010-07-29 22:24:26 +02:00
2010-08-31 16:49:57 +02:00
vpx_memset ( & pc - > left_context , 0 , sizeof ( pc - > left_context ) ) ;
2010-07-29 22:24:26 +02:00
recon_yoffset = mb_row * recon_y_stride * 16 ;
recon_uvoffset = mb_row * recon_uv_stride * 8 ;
2010-10-28 01:04:02 +02:00
/* reset above block coeffs */
2010-07-29 22:24:26 +02:00
2010-08-31 16:49:57 +02:00
xd - > above_context = pc - > above_context ;
2010-07-29 22:24:26 +02:00
xd - > up_available = ( mb_row ! = 0 ) ;
xd - > mb_to_top_edge = - ( ( mb_row * 16 ) ) < < 3 ;
xd - > mb_to_bottom_edge = ( ( pc - > mb_rows - 1 - mb_row ) * 16 ) < < 3 ;
for ( mb_col = 0 ; mb_col < pc - > mb_cols ; mb_col + + )
{
2010-09-23 19:53:09 +02:00
if ( mb_row > 0 & & ( mb_col & ( nsync - 1 ) ) = = 0 ) {
while ( mb_col > ( * last_row_current_mb_col - nsync ) & & * last_row_current_mb_col ! = pc - > mb_cols - 1 )
2010-08-31 00:16:04 +02:00
{
x86_pause_hint ( ) ;
thread_sleep ( 0 ) ;
}
2010-07-29 22:24:26 +02:00
}
2010-05-18 17:58:33 +02:00
2010-08-12 22:25:43 +02:00
if ( xd - > mode_info_context - > mbmi . mode = = SPLITMV | | xd - > mode_info_context - > mbmi . mode = = B_PRED )
2010-07-29 22:24:26 +02:00
{
for ( i = 0 ; i < 16 ; i + + )
{
BLOCKD * d = & xd - > block [ i ] ;
vpx_memcpy ( & d - > bmi , & xd - > mode_info_context - > bmi [ i ] , sizeof ( B_MODE_INFO ) ) ;
}
}
2010-09-16 20:08:52 +02:00
if ( pbi - > common . filter_level )
{
2010-10-28 01:04:02 +02:00
/* update loopfilter info */
2010-09-16 20:08:52 +02:00
Segment = ( alt_flt_enabled ) ? xd - > mode_info_context - > mbmi . segment_id : 0 ;
filter_level = pbi - > mt_baseline_filter_level [ Segment ] ;
2010-10-28 01:04:02 +02:00
/* Distance of Mb to the various image edges.
* These are specified to 8 th pel as they are always compared to values that are in 1 / 8 th pel units
* Apply any context driven MB level adjustment
*/
2010-09-16 20:08:52 +02:00
vp8_adjust_mb_lf_value ( xd , & filter_level ) ;
}
2010-10-28 01:04:02 +02:00
/* Distance of Mb to the various image edges.
* These are specified to 8 th pel as they are always compared to values that are in 1 / 8 th pel units
*/
2010-07-29 22:24:26 +02:00
xd - > mb_to_left_edge = - ( ( mb_col * 16 ) < < 3 ) ;
xd - > mb_to_right_edge = ( ( pc - > mb_cols - 1 - mb_col ) * 16 ) < < 3 ;
xd - > dst . y_buffer = pc - > yv12_fb [ dst_fb_idx ] . y_buffer + recon_yoffset ;
xd - > dst . u_buffer = pc - > yv12_fb [ dst_fb_idx ] . u_buffer + recon_uvoffset ;
xd - > dst . v_buffer = pc - > yv12_fb [ dst_fb_idx ] . v_buffer + recon_uvoffset ;
xd - > left_available = ( mb_col ! = 0 ) ;
2010-10-28 01:04:02 +02:00
/* Select the appropriate reference frame for this MB */
2010-08-12 22:25:43 +02:00
if ( xd - > mode_info_context - > mbmi . ref_frame = = LAST_FRAME )
2010-07-29 22:24:26 +02:00
ref_fb_idx = pc - > lst_fb_idx ;
2010-08-12 22:25:43 +02:00
else if ( xd - > mode_info_context - > mbmi . ref_frame = = GOLDEN_FRAME )
2010-07-29 22:24:26 +02:00
ref_fb_idx = pc - > gld_fb_idx ;
else
ref_fb_idx = pc - > alt_fb_idx ;
xd - > pre . y_buffer = pc - > yv12_fb [ ref_fb_idx ] . y_buffer + recon_yoffset ;
xd - > pre . u_buffer = pc - > yv12_fb [ ref_fb_idx ] . u_buffer + recon_uvoffset ;
xd - > pre . v_buffer = pc - > yv12_fb [ ref_fb_idx ] . v_buffer + recon_uvoffset ;
2010-12-16 16:46:31 +01:00
if ( xd - > mode_info_context - > mbmi . ref_frame ! = INTRA_FRAME )
{
/* propagate errors from reference frames */
xd - > corrupted | = pc - > yv12_fb [ ref_fb_idx ] . corrupted ;
}
2010-07-29 22:24:26 +02:00
vp8_build_uvmvs ( xd , pc - > full_pixel ) ;
2010-09-16 20:08:52 +02:00
vp8mt_decode_macroblock ( pbi , xd , mb_row , mb_col ) ;
2010-12-16 16:46:31 +01:00
/* check if the boolean decoder has suffered an error */
xd - > corrupted | = vp8dx_bool_error ( xd - > current_bc ) ;
2010-09-16 20:08:52 +02:00
if ( pbi - > common . filter_level )
{
2010-10-28 01:04:02 +02:00
/* Save decoded MB last row data for next-row decoding */
2010-09-16 20:08:52 +02:00
if ( mb_row ! = pc - > mb_rows - 1 )
{
vpx_memcpy ( ( pbi - > mt_yabove_row [ mb_row + 1 ] + 32 + mb_col * 16 ) , ( xd - > dst . y_buffer + 15 * recon_y_stride ) , 16 ) ;
vpx_memcpy ( ( pbi - > mt_uabove_row [ mb_row + 1 ] + 16 + mb_col * 8 ) , ( xd - > dst . u_buffer + 7 * recon_uv_stride ) , 8 ) ;
vpx_memcpy ( ( pbi - > mt_vabove_row [ mb_row + 1 ] + 16 + mb_col * 8 ) , ( xd - > dst . v_buffer + 7 * recon_uv_stride ) , 8 ) ;
}
2010-10-28 01:04:02 +02:00
/* save left_col for next MB decoding */
2010-09-16 20:08:52 +02:00
if ( mb_col ! = pc - > mb_cols - 1 )
{
MODE_INFO * next = xd - > mode_info_context + 1 ;
if ( xd - > frame_type = = KEY_FRAME | | next - > mbmi . ref_frame = = INTRA_FRAME )
{
for ( i = 0 ; i < 16 ; i + + )
pbi - > mt_yleft_col [ mb_row ] [ i ] = xd - > dst . y_buffer [ i * recon_y_stride + 15 ] ;
for ( i = 0 ; i < 8 ; i + + )
{
pbi - > mt_uleft_col [ mb_row ] [ i ] = xd - > dst . u_buffer [ i * recon_uv_stride + 7 ] ;
pbi - > mt_vleft_col [ mb_row ] [ i ] = xd - > dst . v_buffer [ i * recon_uv_stride + 7 ] ;
}
}
}
2010-10-28 01:04:02 +02:00
/* loopfilter on this macroblock. */
2010-09-16 20:08:52 +02:00
if ( filter_level )
{
if ( mb_col > 0 )
pc - > lf_mbv ( xd - > dst . y_buffer , xd - > dst . u_buffer , xd - > dst . v_buffer , recon_y_stride , recon_uv_stride , & lfi [ filter_level ] , pc - > simpler_lpf ) ;
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
if ( xd - > mode_info_context - > mbmi . dc_diff > 0 )
pc - > lf_bv ( xd - > dst . y_buffer , xd - > dst . u_buffer , xd - > dst . v_buffer , recon_y_stride , recon_uv_stride , & lfi [ filter_level ] , pc - > simpler_lpf ) ;
2010-10-28 01:04:02 +02:00
/* don't apply across umv border */
2010-09-16 20:08:52 +02:00
if ( mb_row > 0 )
pc - > lf_mbh ( xd - > dst . y_buffer , xd - > dst . u_buffer , xd - > dst . v_buffer , recon_y_stride , recon_uv_stride , & lfi [ filter_level ] , pc - > simpler_lpf ) ;
if ( xd - > mode_info_context - > mbmi . dc_diff > 0 )
pc - > lf_bh ( xd - > dst . y_buffer , xd - > dst . u_buffer , xd - > dst . v_buffer , recon_y_stride , recon_uv_stride , & lfi [ filter_level ] , pc - > simpler_lpf ) ;
}
}
2010-07-29 22:24:26 +02:00
recon_yoffset + = 16 ;
recon_uvoffset + = 8 ;
+ + xd - > mode_info_context ; /* next mb */
2010-08-31 16:49:57 +02:00
xd - > above_context + + ;
2010-07-29 22:24:26 +02:00
2010-09-16 20:08:52 +02:00
pbi - > mt_current_mb_col [ mb_row ] = mb_col ;
2010-07-29 22:24:26 +02:00
}
2010-10-28 01:04:02 +02:00
/* adjust to the next row of mbs */
2010-09-16 20:08:52 +02:00
if ( pbi - > common . filter_level )
{
if ( mb_row ! = pc - > mb_rows - 1 )
{
int lasty = pc - > yv12_fb [ ref_fb_idx ] . y_width + VP8BORDERINPIXELS ;
int lastuv = ( pc - > yv12_fb [ ref_fb_idx ] . y_width > > 1 ) + ( VP8BORDERINPIXELS > > 1 ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
for ( i = 0 ; i < 4 ; i + + )
{
pbi - > mt_yabove_row [ mb_row + 1 ] [ lasty + i ] = pbi - > mt_yabove_row [ mb_row + 1 ] [ lasty - 1 ] ;
pbi - > mt_uabove_row [ mb_row + 1 ] [ lastuv + i ] = pbi - > mt_uabove_row [ mb_row + 1 ] [ lastuv - 1 ] ;
pbi - > mt_vabove_row [ mb_row + 1 ] [ lastuv + i ] = pbi - > mt_vabove_row [ mb_row + 1 ] [ lastuv - 1 ] ;
}
}
} else
vp8_extend_mb_row ( & pc - > yv12_fb [ dst_fb_idx ] , xd - > dst . y_buffer + 16 , xd - > dst . u_buffer + 8 , xd - > dst . v_buffer + 8 ) ;
2010-05-18 17:58:33 +02:00
2010-09-16 20:08:52 +02:00
+ + xd - > mode_info_context ; /* skip prediction column */
2010-07-29 22:24:26 +02:00
}
2010-05-18 17:58:33 +02:00
xd - > mode_info_context + = xd - > mode_info_stride * pbi - > decoding_thread_count ;
2010-07-29 22:24:26 +02:00
}
2010-10-28 01:04:02 +02:00
sem_wait ( & pbi - > h_event_end_decoding ) ; /* add back for each frame */
2010-07-29 22:24:26 +02:00
# else
( void ) pbi ;
( void ) xd ;
# endif
}