Commit e6287f07 authored by Anton Khirnov's avatar Anton Khirnov

h264: move {mv,ref}_cache into the per-slice context

parent f69574cf
......@@ -71,8 +71,8 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
ref = 0;
fill_rectangle(&h->cur_pic.ref_index[0][4 * h->mb_xy],
2, 2, 2, ref, 1);
fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8,
pack16to32((*mv)[0][0][0], (*mv)[0][0][1]), 4);
assert(!FRAME_MBAFF(h));
ff_h264_hl_decode_mb(h, &h->slice_ctx[0]);
......@@ -484,12 +484,14 @@ int ff_h264_context_init(H264Context *h)
FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[1],
h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
h->ref_cache[0][scan8[5] + 1] =
h->ref_cache[0][scan8[7] + 1] =
h->ref_cache[0][scan8[13] + 1] =
h->ref_cache[1][scan8[5] + 1] =
h->ref_cache[1][scan8[7] + 1] =
h->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
for (i = 0; i < h->nb_slice_ctx; i++) {
h->slice_ctx[i].ref_cache[0][scan8[5] + 1] =
h->slice_ctx[i].ref_cache[0][scan8[7] + 1] =
h->slice_ctx[i].ref_cache[0][scan8[13] + 1] =
h->slice_ctx[i].ref_cache[1][scan8[5] + 1] =
h->slice_ctx[i].ref_cache[1][scan8[7] + 1] =
h->slice_ctx[i].ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
}
if (CONFIG_ERROR_RESILIENCE) {
/* init ER */
......
......@@ -347,6 +347,12 @@ typedef struct H264SliceContext {
* is 64 if not available.
*/
DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15 * 8];
/**
* Motion vector cache.
*/
DECLARE_ALIGNED(16, int16_t, mv_cache)[2][5 * 8][2];
DECLARE_ALIGNED(8, int8_t, ref_cache)[2][5 * 8];
} H264SliceContext;
/**
......@@ -389,11 +395,6 @@ typedef struct H264Context {
uint8_t (*non_zero_count)[48];
/**
* Motion vector cache.
*/
DECLARE_ALIGNED(16, int16_t, mv_cache)[2][5 * 8][2];
DECLARE_ALIGNED(8, int8_t, ref_cache)[2][5 * 8];
#define LIST_NOT_USED -1 // FIXME rename?
#define PART_NOT_AVAILABLE -2
......@@ -821,7 +822,8 @@ void h264_init_dequant_tables(H264Context *h);
void ff_h264_direct_dist_scale_factor(H264Context *const h);
void ff_h264_direct_ref_list_init(H264Context *const h);
void ff_h264_pred_direct_motion(H264Context *const h, int *mb_type);
void ff_h264_pred_direct_motion(H264Context *const h, H264SliceContext *sl,
int *mb_type);
void ff_h264_filter_mb_fast(H264Context *h, H264SliceContext *sl, int mb_x, int mb_y,
uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
......@@ -969,12 +971,13 @@ static av_always_inline void write_back_non_zero_count(H264Context *h,
}
static av_always_inline void write_back_motion_list(H264Context *h,
H264SliceContext *sl,
int b_stride,
int b_xy, int b8_xy,
int mb_type, int list)
{
int16_t(*mv_dst)[2] = &h->cur_pic.motion_val[list][b_xy];
int16_t(*mv_src)[2] = &h->mv_cache[list][scan8[0]];
int16_t(*mv_src)[2] = &sl->mv_cache[list][scan8[0]];
AV_COPY128(mv_dst + 0 * b_stride, mv_src + 8 * 0);
AV_COPY128(mv_dst + 1 * b_stride, mv_src + 8 * 1);
AV_COPY128(mv_dst + 2 * b_stride, mv_src + 8 * 2);
......@@ -995,7 +998,7 @@ static av_always_inline void write_back_motion_list(H264Context *h,
{
int8_t *ref_index = &h->cur_pic.ref_index[list][b8_xy];
int8_t *ref_cache = h->ref_cache[list];
int8_t *ref_cache = sl->ref_cache[list];
ref_index[0 + 0 * 2] = ref_cache[scan8[0]];
ref_index[1 + 0 * 2] = ref_cache[scan8[4]];
ref_index[0 + 1 * 2] = ref_cache[scan8[8]];
......@@ -1003,20 +1006,22 @@ static av_always_inline void write_back_motion_list(H264Context *h,
}
}
static av_always_inline void write_back_motion(H264Context *h, int mb_type)
static av_always_inline void write_back_motion(H264Context *h,
H264SliceContext *sl,
int mb_type)
{
const int b_stride = h->b_stride;
const int b_xy = 4 * h->mb_x + 4 * h->mb_y * h->b_stride; // try mb2b(8)_xy
const int b8_xy = 4 * h->mb_xy;
if (USES_LIST(mb_type, 0)) {
write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 0);
write_back_motion_list(h, sl, b_stride, b_xy, b8_xy, mb_type, 0);
} else {
fill_rectangle(&h->cur_pic.ref_index[0][b8_xy],
2, 2, 2, (uint8_t)LIST_NOT_USED, 1);
}
if (USES_LIST(mb_type, 1))
write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 1);
write_back_motion_list(h, sl, b_stride, b_xy, b8_xy, mb_type, 1);
if (h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC(h)) {
if (IS_8X8(mb_type)) {
......
This diff is collapsed.
......@@ -845,11 +845,11 @@ decode_intra_mb:
h->sub_mb_type[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].type;
}
if( IS_DIRECT(h->sub_mb_type[0]|h->sub_mb_type[1]|h->sub_mb_type[2]|h->sub_mb_type[3])) {
ff_h264_pred_direct_motion(h, &mb_type);
h->ref_cache[0][scan8[4]] =
h->ref_cache[1][scan8[4]] =
h->ref_cache[0][scan8[12]] =
h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
ff_h264_pred_direct_motion(h, sl, &mb_type);
sl->ref_cache[0][scan8[4]] =
sl->ref_cache[1][scan8[4]] =
sl->ref_cache[0][scan8[12]] =
sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
}
}else{
assert(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
......@@ -895,11 +895,11 @@ decode_intra_mb:
for(list=0; list<h->list_count; list++){
for(i=0; i<4; i++){
if(IS_DIRECT(h->sub_mb_type[i])) {
h->ref_cache[list][ scan8[4*i] ] = h->ref_cache[list][ scan8[4*i]+1 ];
sl->ref_cache[list][ scan8[4*i] ] = sl->ref_cache[list][ scan8[4*i]+1 ];
continue;
}
h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]=
h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];
sl->ref_cache[list][ scan8[4*i] ]=sl->ref_cache[list][ scan8[4*i]+1 ]=
sl->ref_cache[list][ scan8[4*i]+8 ]=sl->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];
if(IS_DIR(h->sub_mb_type[i], 0, list)){
const int sub_mb_type= h->sub_mb_type[i];
......@@ -907,8 +907,8 @@ decode_intra_mb:
for(j=0; j<sub_partition_count[i]; j++){
int mx, my;
const int index= 4*i + block_width*j;
int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];
pred_motion(h, sl, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);
int16_t (* mv_cache)[2]= &sl->mv_cache[list][ scan8[index] ];
pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my);
mx += get_se_golomb(&h->gb);
my += get_se_golomb(&h->gb);
tprintf(h->avctx, "final mv:%d %d\n", mx, my);
......@@ -929,14 +929,14 @@ decode_intra_mb:
mv_cache[ 0 ][1]= my;
}
}else{
uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0];
uint32_t *p= (uint32_t *)&sl->mv_cache[list][ scan8[4*i] ][0];
p[0] = p[1]=
p[8] = p[9]= 0;
}
}
}
}else if(IS_DIRECT(mb_type)){
ff_h264_pred_direct_motion(h, &mb_type);
ff_h264_pred_direct_motion(h, sl, &mb_type);
dct8x8_allowed &= h->sps.direct_8x8_inference_flag;
}else{
int list, mx, my, i;
......@@ -957,17 +957,17 @@ decode_intra_mb:
return -1;
}
}
fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);
fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);
}
}
for(list=0; list<h->list_count; list++){
if(IS_DIR(mb_type, 0, list)){
pred_motion(h, sl, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my);
mx += get_se_golomb(&h->gb);
my += get_se_golomb(&h->gb);
tprintf(h->avctx, "final mv:%d %d\n", mx, my);
fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
}
}
}
......@@ -990,14 +990,14 @@ decode_intra_mb:
}
}else
val= LIST_NOT_USED&0xFF;
fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1);
fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1);
}
}
for(list=0; list<h->list_count; list++){
for(i=0; i<2; i++){
unsigned int val;
if(IS_DIR(mb_type, i, list)){
pred_16x8_motion(h, sl, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);
pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my);
mx += get_se_golomb(&h->gb);
my += get_se_golomb(&h->gb);
tprintf(h->avctx, "final mv:%d %d\n", mx, my);
......@@ -1005,7 +1005,7 @@ decode_intra_mb:
val= pack16to32(mx,my);
}else
val=0;
fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4);
fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4);
}
}
}else{
......@@ -1028,14 +1028,14 @@ decode_intra_mb:
}
}else
val= LIST_NOT_USED&0xFF;
fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1);
fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1);
}
}
for(list=0; list<h->list_count; list++){
for(i=0; i<2; i++){
unsigned int val;
if(IS_DIR(mb_type, i, list)){
pred_8x16_motion(h, sl, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
mx += get_se_golomb(&h->gb);
my += get_se_golomb(&h->gb);
tprintf(h->avctx, "final mv:%d %d\n", mx, my);
......@@ -1043,14 +1043,14 @@ decode_intra_mb:
val= pack16to32(mx,my);
}else
val=0;
fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4);
fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4);
}
}
}
}
if(IS_INTER(mb_type))
write_back_motion(h, mb_type);
write_back_motion(h, sl, mb_type);
if(!IS_INTRA16x16(mb_type)){
cbp= get_ue_golomb(&h->gb);
......
This diff is collapsed.
......@@ -371,7 +371,7 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
int mask_edge0 = 3*((mask_edge1>>1) & ((5*left_type)>>5)&1); // (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) && (h->left_type[LTOP] & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : 0;
int step = 1+(mb_type>>24); //IS_8x8DCT(mb_type) ? 2 : 1;
edges = 4 - 3*((mb_type>>3) & !(h->cbp & 15)); //(mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4;
h->h264dsp.h264_loop_filter_strength(bS, sl->non_zero_count_cache, h->ref_cache, h->mv_cache,
h->h264dsp.h264_loop_filter_strength(bS, sl->non_zero_count_cache, sl->ref_cache, sl->mv_cache,
h->list_count==2, edges, step, mask_edge0, mask_edge1, FIELD_PICTURE(h));
}
if( IS_INTRA(left_type) )
......@@ -438,29 +438,30 @@ void ff_h264_filter_mb_fast(H264Context *h, H264SliceContext *sl,
#endif
}
static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
static int check_mv(H264Context *h, H264SliceContext *sl, long b_idx, long bn_idx, int mvy_limit)
{
int v;
v= h->ref_cache[0][b_idx] != h->ref_cache[0][bn_idx];
if(!v && h->ref_cache[0][b_idx]!=-1)
v= h->mv_cache[0][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U |
FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit;
v = sl->ref_cache[0][b_idx] != sl->ref_cache[0][bn_idx];
if (!v && sl->ref_cache[0][b_idx] != -1)
v = sl->mv_cache[0][b_idx][0] - sl->mv_cache[0][bn_idx][0] + 3 >= 7U |
FFABS(sl->mv_cache[0][b_idx][1] - sl->mv_cache[0][bn_idx][1]) >= mvy_limit;
if(h->list_count==2){
if(!v)
v = h->ref_cache[1][b_idx] != h->ref_cache[1][bn_idx] |
h->mv_cache[1][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U |
FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit;
v = sl->ref_cache[1][b_idx] != sl->ref_cache[1][bn_idx] |
sl->mv_cache[1][b_idx][0] - sl->mv_cache[1][bn_idx][0] + 3 >= 7U |
FFABS(sl->mv_cache[1][b_idx][1] - sl->mv_cache[1][bn_idx][1]) >= mvy_limit;
if(v){
if(h->ref_cache[0][b_idx] != h->ref_cache[1][bn_idx] |
h->ref_cache[1][b_idx] != h->ref_cache[0][bn_idx])
if (sl->ref_cache[0][b_idx] != sl->ref_cache[1][bn_idx] |
sl->ref_cache[1][b_idx] != sl->ref_cache[0][bn_idx])
return 1;
return
h->mv_cache[0][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U |
FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit |
h->mv_cache[1][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U |
FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit;
sl->mv_cache[0][b_idx][0] - sl->mv_cache[1][bn_idx][0] + 3 >= 7U |
FFABS(sl->mv_cache[0][b_idx][1] - sl->mv_cache[1][bn_idx][1]) >= mvy_limit |
sl->mv_cache[1][b_idx][0] - sl->mv_cache[0][bn_idx][0] + 3 >= 7U |
FFABS(sl->mv_cache[1][b_idx][1] - sl->mv_cache[0][bn_idx][1]) >= mvy_limit;
}
}
......@@ -564,7 +565,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl,
int b_idx= 8 + 4;
int bn_idx= b_idx - (dir ? 8:1);
bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, 8 + 4, bn_idx, mvy_limit);
bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, sl, 8 + 4, bn_idx, mvy_limit);
mv_done = 1;
}
else
......@@ -582,7 +583,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl,
}
else if(!mv_done)
{
bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit);
bS[i] = check_mv(h, sl, b_idx, bn_idx, mvy_limit);
}
}
}
......@@ -645,7 +646,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl,
int b_idx= 8 + 4 + edge * (dir ? 8:1);
int bn_idx= b_idx - (dir ? 8:1);
bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, b_idx, bn_idx, mvy_limit);
bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, sl, b_idx, bn_idx, mvy_limit);
mv_done = 1;
}
else
......@@ -663,7 +664,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl,
}
else if(!mv_done)
{
bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit);
bS[i] = check_mv(h, sl, b_idx, bn_idx, mvy_limit);
}
}
......
This diff is collapsed.
......@@ -81,13 +81,13 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h, H264SliceContext *sl)
if (!USES_LIST(mb_type, list))
continue;
if (IS_16X16(mb_type)) {
int8_t *ref = &h->ref_cache[list][scan8[0]];
int8_t *ref = &sl->ref_cache[list][scan8[0]];
fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1);
} else {
for (i = 0; i < 16; i += 4) {
int ref = h->ref_cache[list][scan8[i]];
int ref = sl->ref_cache[list][scan8[i]];
if (ref >= 0)
fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
fill_rectangle(&sl->ref_cache[list][scan8[i]], 2, 2,
8, (16 + ref) ^ (h->mb_y & 1), 1);
}
}
......@@ -306,13 +306,13 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h, H264SliceContext
if (!USES_LIST(mb_type, list))
continue;
if (IS_16X16(mb_type)) {
int8_t *ref = &h->ref_cache[list][scan8[0]];
int8_t *ref = &sl->ref_cache[list][scan8[0]];
fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1);
} else {
for (i = 0; i < 16; i += 4) {
int ref = h->ref_cache[list][scan8[i]];
int ref = sl->ref_cache[list][scan8[i]];
if (ref >= 0)
fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
fill_rectangle(&sl->ref_cache[list][scan8[i]], 2, 2,
8, (16 + ref) ^ (h->mb_y & 1), 1);
}
}
......
......@@ -49,14 +49,14 @@ static void mc_part(H264Context *h, H264SliceContext *sl,
int list0, int list1)
{
if ((sl->use_weight == 2 && list0 && list1 &&
(sl->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->mb_y & 1] != 32)) ||
(sl->implicit_weight[sl->ref_cache[0][scan8[n]]][sl->ref_cache[1][scan8[n]]][h->mb_y & 1] != 32)) ||
sl->use_weight == 1)
mc_part_weighted(h, sl, n, square, height, delta, dest_y, dest_cb, dest_cr,
x_offset, y_offset, qpix_put, chroma_put,
weight_op[0], weight_op[1], weight_avg[0],
weight_avg[1], list0, list1, PIXEL_SHIFT, CHROMA_IDC);
else
mc_part_std(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
mc_part_std(h, sl, n, square, height, delta, dest_y, dest_cb, dest_cr,
x_offset, y_offset, qpix_put, chroma_put, qpix_avg,
chroma_avg, list0, list1, PIXEL_SHIFT, CHROMA_IDC);
}
......@@ -77,8 +77,8 @@ static void MCFUNC(hl_motion)(H264Context *h, H264SliceContext *sl,
assert(IS_INTER(mb_type));
if (HAVE_THREADS && (h->avctx->active_thread_type & FF_THREAD_FRAME))
await_references(h);
prefetch_motion(h, 0, PIXEL_SHIFT, CHROMA_IDC);
await_references(h, sl);
prefetch_motion(h, sl, 0, PIXEL_SHIFT, CHROMA_IDC);
if (IS_16X16(mb_type)) {
mc_part(h, sl, 0, 1, 16, 0, dest_y, dest_cb, dest_cr, 0, 0,
......@@ -158,6 +158,6 @@ static void MCFUNC(hl_motion)(H264Context *h, H264SliceContext *sl,
}
}
prefetch_motion(h, 1, PIXEL_SHIFT, CHROMA_IDC);
prefetch_motion(h, sl, 1, PIXEL_SHIFT, CHROMA_IDC);
}
......@@ -39,7 +39,7 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, H264SliceContext *
const int16_t **C,
int i, int list, int part_width)
{
const int topright_ref = h->ref_cache[list][i - 8 + part_width];
const int topright_ref = sl->ref_cache[list][i - 8 + part_width];
/* there is no consistent mapping of mvs to neighboring locations that will
* make mbaff happy, so we can't move all this logic to fill_caches */
......@@ -50,17 +50,17 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, H264SliceContext *
if (!USES_LIST(mb_type, list)) \
return LIST_NOT_USED; \
mv = h->cur_pic_ptr->motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
h->mv_cache[list][scan8[0] - 2][0] = mv[0]; \
h->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP; \
sl->mv_cache[list][scan8[0] - 2][0] = mv[0]; \
sl->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP; \
return h->cur_pic_ptr->ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
if (topright_ref == PART_NOT_AVAILABLE
&& i >= scan8[0] + 8 && (i & 7) == 4
&& h->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
&& sl->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
const uint32_t *mb_types = h->cur_pic_ptr->mb_type;
const int16_t *mv;
AV_ZERO32(h->mv_cache[list][scan8[0] - 2]);
*C = h->mv_cache[list][scan8[0] - 2];
AV_ZERO32(sl->mv_cache[list][scan8[0] - 2]);
*C = sl->mv_cache[list][scan8[0] - 2];
if (!MB_FIELD(h) && IS_INTERLACED(sl->left_type[0])) {
SET_DIAG_MV(* 2, >> 1, sl->left_mb_xy[0] + h->mb_stride,
......@@ -75,13 +75,13 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, H264SliceContext *
}
if (topright_ref != PART_NOT_AVAILABLE) {
*C = h->mv_cache[list][i - 8 + part_width];
*C = sl->mv_cache[list][i - 8 + part_width];
return topright_ref;
} else {
tprintf(h->avctx, "topright MV not available\n");
*C = h->mv_cache[list][i - 8 - 1];
return h->ref_cache[list][i - 8 - 1];
*C = sl->mv_cache[list][i - 8 - 1];
return sl->ref_cache[list][i - 8 - 1];
}
}
......@@ -99,10 +99,10 @@ static av_always_inline void pred_motion(H264Context *const h,
int *const mx, int *const my)
{
const int index8 = scan8[n];
const int top_ref = h->ref_cache[list][index8 - 8];
const int left_ref = h->ref_cache[list][index8 - 1];
const int16_t *const A = h->mv_cache[list][index8 - 1];
const int16_t *const B = h->mv_cache[list][index8 - 8];
const int top_ref = sl->ref_cache[list][index8 - 8];
const int left_ref = sl->ref_cache[list][index8 - 1];
const int16_t *const A = sl->mv_cache[list][index8 - 1];
const int16_t *const B = sl->mv_cache[list][index8 - 8];
const int16_t *C;
int diagonal_ref, match_count;
......@@ -163,8 +163,8 @@ static av_always_inline void pred_16x8_motion(H264Context *const h,
int *const mx, int *const my)
{
if (n == 0) {
const int top_ref = h->ref_cache[list][scan8[0] - 8];
const int16_t *const B = h->mv_cache[list][scan8[0] - 8];
const int top_ref = sl->ref_cache[list][scan8[0] - 8];
const int16_t *const B = sl->mv_cache[list][scan8[0] - 8];
tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
top_ref, B[0], B[1], h->mb_x, h->mb_y, n, list);
......@@ -175,8 +175,8 @@ static av_always_inline void pred_16x8_motion(H264Context *const h,
return;
}
} else {
const int left_ref = h->ref_cache[list][scan8[8] - 1];
const int16_t *const A = h->mv_cache[list][scan8[8] - 1];
const int left_ref = sl->ref_cache[list][scan8[8] - 1];
const int16_t *const A = sl->mv_cache[list][scan8[8] - 1];
tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list);
......@@ -204,8 +204,8 @@ static av_always_inline void pred_8x16_motion(H264Context *const h,
int *const mx, int *const my)
{
if (n == 0) {
const int left_ref = h->ref_cache[list][scan8[0] - 1];
const int16_t *const A = h->mv_cache[list][scan8[0] - 1];
const int left_ref = sl->ref_cache[list][scan8[0] - 1];
const int16_t *const A = sl->mv_cache[list][scan8[0] - 1];
tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list);
......@@ -265,7 +265,7 @@ static av_always_inline void pred_pskip_motion(H264Context *const h,
const int16_t *A, *B, *C;
int b_stride = h->b_stride;
fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
/* To avoid doing an entire fill_decode_caches, we inline the relevant
* parts here.
......@@ -345,11 +345,11 @@ static av_always_inline void pred_pskip_motion(H264Context *const h,
my = mid_pred(A[1], B[1], C[1]);
}
fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx, my), 4);
fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx, my), 4);
return;
zeromv:
fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
return;
}
......@@ -607,9 +607,9 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type
int list;
int b_stride = h->b_stride;
for (list = 0; list < h->list_count; list++) {
int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
int8_t *ref_cache = &sl->ref_cache[list][scan8[0]];
int8_t *ref = h->cur_pic.ref_index[list];
int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
int16_t(*mv_cache)[2] = &sl->mv_cache[list][scan8[0]];
int16_t(*mv)[2] = h->cur_pic.motion_val[list];
if (!USES_LIST(mb_type, list))
continue;
......@@ -770,9 +770,9 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type
if (MB_FIELD(h)) {
#define MAP_F2F(idx, mb_type) \
if (!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0) { \
h->ref_cache[list][idx] <<= 1; \
h->mv_cache[list][idx][1] /= 2; \
if (!IS_INTERLACED(mb_type) && sl->ref_cache[list][idx] >= 0) { \
sl->ref_cache[list][idx] <<= 1; \
sl->mv_cache[list][idx][1] /= 2; \
h->mvd_cache[list][idx][1] >>= 1; \
}
......@@ -781,9 +781,9 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type
#undef MAP_F2F
#define MAP_F2F(idx, mb_type) \
if (IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0) { \
h->ref_cache[list][idx] >>= 1; \
h->mv_cache[list][idx][1] <<= 1; \
if (IS_INTERLACED(mb_type) && sl->ref_cache[list][idx] >= 0) { \
sl->ref_cache[list][idx] >>= 1; \
sl->mv_cache[list][idx][1] <<= 1; \
h->mvd_cache[list][idx][1] <<= 1; \
}
......@@ -817,7 +817,7 @@ static void av_unused decode_mb_skip(H264Context *h, H264SliceContext *sl)
fill_decode_neighbors(h, sl, mb_type);
fill_decode_caches(h, sl, mb_type); //FIXME check what is needed and what not ...
}
ff_h264_pred_direct_motion(h, &mb_type);
ff_h264_pred_direct_motion(h, sl, &mb_type);
mb_type |= MB_TYPE_SKIP;
} else {
mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_SKIP;
......@@ -826,7 +826,7 @@ static void av_unused decode_mb_skip(H264Context *h, H264SliceContext *sl)
pred_pskip_motion(h, sl);
}
write_back_motion(h, mb_type);
write_back_motion(h, sl, mb_type);
h->cur_pic.mb_type[mb_xy] = mb_type;
h->cur_pic.qscale_table[mb_xy] = sl->qscale;
h->slice_table[mb_xy] = h->slice_num;
......
......@@ -1822,6 +1822,7 @@ int ff_h264_get_slice_type(const H264Context *h)
}
static av_always_inline void fill_filter_caches_inter(H264Context *h,
H264SliceContext *sl,
int mb_type, int top_xy,
int left_xy[LEFT_MBS],
int top_type,
......@@ -1829,8 +1830,8 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
int mb_xy, int list)
{
int b_stride = h->b_stride;
int16_t(*mv_dst)[2] = &h->mv_cache[list][scan8[0]];
int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
int16_t(*mv_dst)[2] = &sl->mv_cache[list][scan8[0]];
int8_t *ref_cache = &sl->ref_cache[list][scan8[0]];
if (IS_INTER(mb_type) || IS_DIRECT(mb_type)) {
if (USES_LIST(top_type, list)) {
const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride;
......@@ -1979,10 +1980,10 @@ static int fill_filter_caches(H264Context *h, H264SliceContext *sl, int mb_type)
if (IS_INTRA(mb_type))
return 0;
fill_filter_caches_inter(h, mb_type, top_xy, left_xy,
fill_filter_caches_inter(h, sl, mb_type, top_xy, left_xy,
top_type, left_type, mb_xy, 0);
if (h->list_count == 2)
fill_filter_caches_inter(h, mb_type, top_xy, left_xy,
fill_filter_caches_inter(h, sl, mb_type, top_xy, left_xy,
top_type, left_type, mb_xy, 1);
nnz = h->non_zero_count[mb_xy];
......
......@@ -459,15 +459,15 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
int32_t mv = pack16to32(mx, my);
if (part_height == 8 && i < 8) {
AV_WN32A(h->mv_cache[dir][scan8[k] + 1 * 8], mv);
AV_WN32A(sl->mv_cache[dir][scan8[k] + 1 * 8], mv);
if (part_width == 8 && j < 8)
AV_WN32A(h->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv);
AV_WN32A(sl->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv);
}
if (part_width == 8 && j < 8)
AV_WN32A(h->mv_cache[dir][scan8[k] + 1], mv);
AV_WN32A(sl->mv_cache[dir][scan8[k] + 1], mv);
if (part_width == 4 || part_height == 4)
AV_WN32A(h->mv_cache[dir][scan8[k]], mv);
AV_WN32A(sl->mv_cache[dir][scan8[k]], mv);
}
/* write back motion vectors */
......@@ -535,36 +535,36 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
for (m = 0; m < 2; m++) {
if (h->mb_x > 0 && sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
for (i = 0; i < 4; i++)
AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i * 8],
AV_COPY32(sl->mv_cache[m][scan8[0] - 1 + i * 8],
h->cur_pic.motion_val[m][b_xy - 1 + i * h->b_stride]);
} else {
for (i = 0; i < 4; i++)
AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i * 8]);
AV_ZERO32(sl->mv_cache[m][scan8[0] - 1 + i * 8]);
}
if (h->mb_y > 0) {
memcpy(h->mv_cache[m][scan8[0] - 1 * 8],
memcpy(sl->mv_cache[m][scan8[0] - 1 * 8],
h->cur_pic.motion_val[m][b_xy - h->b_stride],
4 * 2 * sizeof(int16_t));
memset(&h->ref_cache[m][scan8[0] - 1 * 8],
memset(&sl->ref_cache[m][scan8[0] - 1 * 8],
(sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
if (h->mb_x < h->mb_width - 1) {
AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1 * 8],
AV_COPY32(sl->mv_cache[m][scan8[0] + 4 - 1 * 8],
h->cur_pic.motion_val[m][b_xy - h->b_stride + 4]);
h->ref_cache[m][scan8[0] + 4 - 1 * 8] =
sl->ref_cache[m][scan8[0] + 4 - 1 * 8] =
(sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 ||
sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
} else
h->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;
sl->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;
if (h->mb_x > 0) {
AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1 * 8],
AV_COPY32(sl->mv_cache[m][scan8[0] - 1 - 1 * 8],
h->cur_pic.motion_val[m][b_xy - h->b_stride - 1]);
h->ref_cache[m][scan8[0] - 1 - 1 * 8] =
sl->ref_cache[m][scan8[0] - 1 - 1 * 8] =
(sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
} else
h->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE;
sl->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE;
} else
memset(&h->ref_cache[m][scan8[0] - 1 * 8 - 1],
memset(&sl->ref_cache[m][scan8[0] - 1 * 8 - 1],
PART_NOT_AVAILABLE, 8);
if (h->pict_type != AV_PICTURE_TYPE_B)
......@@ -1111,6 +1111,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
const uint8_t *buf = avpkt->data;
SVQ3Context *s = avctx->priv_data;
H264Context *h = &s->h;
H264SliceContext *sl = &h->slice_ctx[0];
int buf_size = avpkt->size;
int ret, m, i;
......@@ -1235,9 +1236,9 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
for (i = 0; i < 4; i++) {
int j;
for (j = -1; j < 4; j++)
h->ref_cache[m][scan8[0] + 8 * i + j] = 1;
sl->ref_cache[m][scan8[0] + 8 * i + j] = 1;
if (i < 3)
h->ref_cache[m][scan8[0] + 8 * i + j] = PART_NOT_AVAILABLE;
sl->ref_cache[m][scan8[0] + 8 * i + j] = PART_NOT_AVAILABLE;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment