OLD | NEW |
1 /* | 1 /* |
2 * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding | 2 * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding |
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | 3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> |
4 * | 4 * |
5 * This file is part of FFmpeg. | 5 * This file is part of FFmpeg. |
6 * | 6 * |
7 * FFmpeg is free software; you can redistribute it and/or | 7 * FFmpeg is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2.1 of the License, or (at your option) any later version. | 10 * version 2.1 of the License, or (at your option) any later version. |
(...skipping 12 matching lines...) Expand all Loading... |
23 * @file libavcodec/h264_direct.c | 23 * @file libavcodec/h264_direct.c |
24 * H.264 / AVC / MPEG4 part10 direct mb/block decoding. | 24 * H.264 / AVC / MPEG4 part10 direct mb/block decoding. |
25 * @author Michael Niedermayer <michaelni@gmx.at> | 25 * @author Michael Niedermayer <michaelni@gmx.at> |
26 */ | 26 */ |
27 | 27 |
28 #include "internal.h" | 28 #include "internal.h" |
29 #include "dsputil.h" | 29 #include "dsputil.h" |
30 #include "avcodec.h" | 30 #include "avcodec.h" |
31 #include "mpegvideo.h" | 31 #include "mpegvideo.h" |
32 #include "h264.h" | 32 #include "h264.h" |
33 #include "h264_mvpred.h" | |
34 #include "rectangle.h" | 33 #include "rectangle.h" |
35 #include "thread.h" | 34 #include "thread.h" |
36 | 35 |
37 //#undef NDEBUG | 36 //#undef NDEBUG |
38 #include <assert.h> | 37 #include <assert.h> |
39 | 38 |
40 | 39 |
41 static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){ | 40 static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){ |
42 int poc0 = h->ref_list[0][i].poc; | 41 int poc0 = h->ref_list[0][i].poc; |
43 int td = av_clip(poc1 - poc0, -128, 127); | 42 int td = av_clip(poc1 - poc0, -128, 127); |
(...skipping 21 matching lines...) Expand all Loading... |
65 for(i=0; i<h->ref_count[0]; i++){ | 64 for(i=0; i<h->ref_count[0]; i++){ |
66 h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i); | 65 h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i); |
67 } | 66 } |
68 } | 67 } |
69 | 68 |
70 static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field,
int colfield, int mbafi){ | 69 static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field,
int colfield, int mbafi){ |
71 MpegEncContext * const s = &h->s; | 70 MpegEncContext * const s = &h->s; |
72 Picture * const ref1 = &h->ref_list[1][0]; | 71 Picture * const ref1 = &h->ref_list[1][0]; |
73 int j, old_ref, rfield; | 72 int j, old_ref, rfield; |
74 int start= mbafi ? 16 : 0; | 73 int start= mbafi ? 16 : 0; |
75 int end = mbafi ? 16+2*h->ref_count[list] : h->ref_count[list]; | 74 int end = mbafi ? 16+2*h->ref_count[0] : h->ref_count[0]; |
76 int interl= mbafi || s->picture_structure != PICT_FRAME; | 75 int interl= mbafi || s->picture_structure != PICT_FRAME; |
77 | 76 |
78 /* bogus; fills in for missing frames */ | 77 /* bogus; fills in for missing frames */ |
79 memset(map[list], 0, sizeof(map[list])); | 78 memset(map[list], 0, sizeof(map[list])); |
80 | 79 |
81 for(rfield=0; rfield<2; rfield++){ | 80 for(rfield=0; rfield<2; rfield++){ |
82 for(old_ref=0; old_ref<ref1->ref_count[colfield][list]; old_ref++){ | 81 for(old_ref=0; old_ref<ref1->ref_count[colfield][list]; old_ref++){ |
83 int poc = ref1->ref_poc[colfield][list][old_ref]; | 82 int poc = ref1->ref_poc[colfield][list][old_ref]; |
84 | 83 |
85 if (!interl) | 84 if (!interl) |
86 poc |= 3; | 85 poc |= 3; |
87 else if( interl && (poc&3) == 3) //FIXME store all MBAFF references
so this isnt needed | 86 else if( interl && (poc&3) == 3) //FIXME store all MBAFF references
so this isnt needed |
88 poc= (poc&~3) + rfield + 1; | 87 poc= (poc&~3) + rfield + 1; |
89 | 88 |
90 for(j=start; j<end; j++){ | 89 for(j=start; j<end; j++){ |
91 if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].refe
rence&3) == poc){ | 90 if(4*h->ref_list[0][j].frame_num + (h->ref_list[0][j].reference&
3) == poc){ |
92 int cur_ref= mbafi ? (j-16)^field : j; | 91 int cur_ref= mbafi ? (j-16)^field : j; |
93 map[list][2*old_ref + (rfield^field) + 16] = cur_ref; | 92 map[list][2*old_ref + (rfield^field) + 16] = cur_ref; |
94 if(rfield == field) | 93 if(rfield == field || !interl) |
95 map[list][old_ref] = cur_ref; | 94 map[list][old_ref] = cur_ref; |
96 break; | 95 break; |
97 } | 96 } |
98 } | 97 } |
99 } | 98 } |
100 } | 99 } |
101 } | 100 } |
102 | 101 |
103 void ff_h264_direct_ref_list_init(H264Context * const h){ | 102 void ff_h264_direct_ref_list_init(H264Context * const h){ |
104 MpegEncContext * const s = &h->s; | 103 MpegEncContext * const s = &h->s; |
105 Picture * const ref1 = &h->ref_list[1][0]; | 104 Picture * const ref1 = &h->ref_list[1][0]; |
106 Picture * const cur = s->current_picture_ptr; | 105 Picture * const cur = s->current_picture_ptr; |
107 int list, j, field; | 106 int list, j, field; |
108 int sidx= (s->picture_structure&1)^1; | 107 int sidx= (s->picture_structure&1)^1; |
109 int ref1sidx= (ref1->reference&1)^1; | 108 int ref1sidx= (ref1->reference&1)^1; |
110 | 109 |
111 for(list=0; list<2; list++){ | 110 for(list=0; list<2; list++){ |
112 cur->ref_count[sidx][list] = h->ref_count[list]; | 111 cur->ref_count[sidx][list] = h->ref_count[list]; |
113 for(j=0; j<h->ref_count[list]; j++) | 112 for(j=0; j<h->ref_count[list]; j++) |
114 cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h-
>ref_list[list][j].reference&3); | 113 cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h-
>ref_list[list][j].reference&3); |
115 } | 114 } |
116 | 115 |
117 if(s->picture_structure == PICT_FRAME){ | 116 if(s->picture_structure == PICT_FRAME){ |
118 memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); | 117 memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); |
119 memcpy(cur->ref_poc [1], cur->ref_poc [0], sizeof(cur->ref_poc [0])); | 118 memcpy(cur->ref_poc [1], cur->ref_poc [0], sizeof(cur->ref_poc [0])); |
120 } | 119 } |
121 | 120 |
122 cur->mbaff= FRAME_MBAFF; | 121 cur->mbaff= FRAME_MBAFF; |
123 | 122 |
| 123 h->col_fieldoff= 0; |
| 124 if(s->picture_structure == PICT_FRAME){ |
| 125 int cur_poc = s->current_picture_ptr->poc; |
| 126 int *col_poc = h->ref_list[1]->field_poc; |
| 127 h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_po
c)); |
| 128 ref1sidx=sidx= h->col_parity; |
| 129 }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->ref_li
st[1][0].mbaff){ // FL -> FL & differ parity |
| 130 h->col_fieldoff= 2*(h->ref_list[1][0].reference) - 3; |
| 131 } |
| 132 |
124 if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) | 133 if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) |
125 return; | 134 return; |
126 | 135 |
127 for(list=0; list<2; list++){ | 136 for(list=0; list<2; list++){ |
128 fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0); | 137 fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0); |
| 138 if(FRAME_MBAFF) |
129 for(field=0; field<2; field++) | 139 for(field=0; field<2; field++) |
130 fill_colmap(h, h->map_col_to_list0_field[field], list, field, field,
1); | 140 fill_colmap(h, h->map_col_to_list0_field[field], list, field, field,
1); |
131 } | 141 } |
132 } | 142 } |
133 | 143 |
134 static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y
) | 144 static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y
) |
135 { | 145 { |
136 int ref_field = ref->reference - 1; | 146 int ref_field = ref->reference - 1; |
137 int ref_field_picture = ref->field_picture; | 147 int ref_field_picture = ref->field_picture; |
138 int ref_height = 16*h->s.mb_height >> ref_field_picture; | 148 int ref_height = 16*h->s.mb_height >> ref_field_picture; |
139 | 149 |
140 if(!HAVE_PTHREADS || !(h->s.avctx->active_thread_type&FF_THREAD_FRAME)) | 150 if(!HAVE_PTHREADS || !(h->s.avctx->active_thread_type&FF_THREAD_FRAME)) |
141 return; | 151 return; |
142 | 152 |
143 //FIXME it can be safe to access mb stuff | 153 //FIXME it can be safe to access mb stuff |
144 //even if pixels aren't deblocked yet | 154 //even if pixels aren't deblocked yet |
145 | 155 |
146 ff_thread_await_progress((AVFrame*)ref, FFMIN(16*mb_y >> ref_field_picture,
ref_height-1), | 156 ff_thread_await_progress((AVFrame*)ref, FFMIN(16*mb_y >> ref_field_picture,
ref_height-1), |
147 ref_field_picture && ref_field); | 157 ref_field_picture && ref_field); |
148 } | 158 } |
149 | 159 |
150 void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){ | 160 static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ |
151 MpegEncContext * const s = &h->s; | 161 MpegEncContext * const s = &h->s; |
152 int b8_stride = h->b8_stride; | 162 int b8_stride = 2; |
153 int b4_stride = h->b_stride; | 163 int b4_stride = h->b_stride; |
154 int mb_xy = h->mb_xy, mb_y = s->mb_y; | 164 int mb_xy = h->mb_xy, mb_y = s->mb_y; |
155 int mb_type_col[2]; | 165 int mb_type_col[2]; |
156 const int16_t (*l1mv0)[2], (*l1mv1)[2]; | 166 const int16_t (*l1mv0)[2], (*l1mv1)[2]; |
157 const int8_t *l1ref0, *l1ref1; | 167 const int8_t *l1ref0, *l1ref1; |
158 const int is_b8x8 = IS_8X8(*mb_type); | 168 const int is_b8x8 = IS_8X8(*mb_type); |
159 unsigned int sub_mb_type; | 169 unsigned int sub_mb_type= MB_TYPE_L0L1; |
160 int i8, i4; | 170 int i8, i4; |
| 171 int ref[2]; |
| 172 int mv[2]; |
| 173 int list; |
161 | 174 |
162 assert(h->ref_list[1][0].reference&3); | 175 assert(h->ref_list[1][0].reference&3); |
163 | 176 |
164 await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_
type)); | 177 await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_
type)); |
165 | 178 |
166 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x1
6|MB_TYPE_INTRA_PCM) | 179 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x1
6|MB_TYPE_INTRA_PCM) |
167 | 180 |
| 181 |
| 182 /* ref = min(neighbors) */ |
| 183 for(list=0; list<2; list++){ |
| 184 int left_ref = h->ref_cache[list][scan8[0] - 1]; |
| 185 int top_ref = h->ref_cache[list][scan8[0] - 8]; |
| 186 int refc = h->ref_cache[list][scan8[0] - 8 + 4]; |
| 187 const int16_t *C= h->mv_cache[list][ scan8[0] - 8 + 4]; |
| 188 if(refc == PART_NOT_AVAILABLE){ |
| 189 refc = h->ref_cache[list][scan8[0] - 8 - 1]; |
| 190 C = h-> mv_cache[list][scan8[0] - 8 - 1]; |
| 191 } |
| 192 ref[list] = FFMIN3((unsigned)left_ref, (unsigned)top_ref, (unsigned)refc
); |
| 193 if(ref[list] >= 0){ |
| 194 //this is just pred_motion() but with the cases removed that cannot
happen for direct blocks |
| 195 const int16_t * const A= h->mv_cache[list][ scan8[0] - 1 ]; |
| 196 const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ]; |
| 197 |
| 198 int match_count= (left_ref==ref[list]) + (top_ref==ref[list]) + (ref
c==ref[list]); |
| 199 if(match_count > 1){ //most common |
| 200 mv[list]= pack16to32(mid_pred(A[0], B[0], C[0]), |
| 201 mid_pred(A[1], B[1], C[1]) ); |
| 202 }else { |
| 203 assert(match_count==1); |
| 204 if(left_ref==ref[list]){ |
| 205 mv[list]= AV_RN32A(A); |
| 206 }else if(top_ref==ref[list]){ |
| 207 mv[list]= AV_RN32A(B); |
| 208 }else{ |
| 209 mv[list]= AV_RN32A(C); |
| 210 } |
| 211 } |
| 212 }else{ |
| 213 int mask= ~(MB_TYPE_L0 << (2*list)); |
| 214 mv[list] = 0; |
| 215 ref[list] = -1; |
| 216 if(!is_b8x8) |
| 217 *mb_type &= mask; |
| 218 sub_mb_type &= mask; |
| 219 } |
| 220 } |
| 221 if(ref[0] < 0 && ref[1] < 0){ |
| 222 ref[0] = ref[1] = 0; |
| 223 if(!is_b8x8) |
| 224 *mb_type |= MB_TYPE_L0L1; |
| 225 sub_mb_type |= MB_TYPE_L0L1; |
| 226 } |
| 227 |
| 228 if(!(is_b8x8|mv[0]|mv[1])){ |
| 229 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); |
| 230 fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1); |
| 231 fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); |
| 232 fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4); |
| 233 *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1
L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2; |
| 234 return; |
| 235 } |
| 236 |
168 if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL
/FL | 237 if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL
/FL |
169 if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL
/FL | 238 if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL
/FL |
170 int cur_poc = s->current_picture_ptr->poc; | 239 mb_y = (s->mb_y&~1) + h->col_parity; |
171 int *col_poc = h->ref_list[1]->field_poc; | 240 mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; |
172 int col_parity = FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - c
ur_poc); | |
173 mb_y = (s->mb_y&~1) + col_parity; | |
174 mb_xy= s->mb_x + mb_y*s->mb_stride; | |
175 b8_stride = 0; | 241 b8_stride = 0; |
176 }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->re
f_list[1][0].mbaff){// FL -> FL & differ parity | 242 }else{ |
177 int fieldoff= 2*(h->ref_list[1][0].reference)-3; | 243 mb_y += h->col_fieldoff; |
178 mb_y += fieldoff; | 244 mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & di
ffer parity |
179 mb_xy += s->mb_stride*fieldoff; | |
180 } | 245 } |
181 goto single_col; | 246 goto single_col; |
182 }else{ // AFL/AFR/FR/FL -> AFR
/FR | 247 }else{ // AFL/AFR/FR/FL -> AFR
/FR |
183 if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR
/FR | 248 if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR
/FR |
184 mb_y = s->mb_y&~1; | 249 mb_y = s->mb_y&~1; |
185 mb_xy= s->mb_x + mb_y*s->mb_stride; | 250 mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride; |
186 mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; | 251 mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; |
187 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; | 252 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; |
188 b8_stride *= 3; | 253 b8_stride = 2+4*s->mb_stride; |
189 b4_stride *= 6; | 254 b4_stride *= 6; |
190 //FIXME IS_8X8(mb_type_col[0]) && !h->sps.direct_8x8_inference_flag | 255 |
| 256 sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ |
191 if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) | 257 if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) |
192 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) | 258 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) |
193 && !is_b8x8){ | 259 && !is_b8x8){ |
194 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DI
RECT2; /* B_SUB_8x8 */ | 260 *mb_type |= MB_TYPE_16x8 |MB_TYPE_DIRECT2; /* B_16x8 */ |
195 *mb_type |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_1
6x8 */ | |
196 }else{ | 261 }else{ |
197 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DI
RECT2; /* B_SUB_8x8 */ | 262 *mb_type |= MB_TYPE_8x8; |
198 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | |
199 } | 263 } |
200 }else{ // AFR/FR -> AFR
/FR | 264 }else{ // AFR/FR -> AFR
/FR |
201 single_col: | 265 single_col: |
202 mb_type_col[0] = | 266 mb_type_col[0] = |
203 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; | 267 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; |
204 if(IS_8X8(mb_type_col[0]) && !h->sps.direct_8x8_inference_flag){ | 268 |
205 /* FIXME save sub mb types from previous frames (or derive from
MVs) | 269 sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ |
206 * so we know exactly what block size to use */ | 270 if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ |
207 sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRE
CT2; /* B_SUB_4x4 */ | 271 *mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_16x16 */ |
208 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | 272 }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)))
{ |
209 }else if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ | 273 *mb_type |= MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|
MB_TYPE_8x16)); |
210 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DI
RECT2; /* B_SUB_8x8 */ | |
211 *mb_type |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DI
RECT2; /* B_16x16 */ | |
212 }else{ | 274 }else{ |
213 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DI
RECT2; /* B_SUB_8x8 */ | 275 if(!h->sps.direct_8x8_inference_flag){ |
214 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | 276 /* FIXME save sub mb types from previous frames (or derive f
rom MVs) |
| 277 * so we know exactly what block size to use */ |
| 278 sub_mb_type += (MB_TYPE_8x8-MB_TYPE_16x16); /* B_SUB_4x4 */ |
| 279 } |
| 280 *mb_type |= MB_TYPE_8x8; |
215 } | 281 } |
216 } | 282 } |
217 } | 283 } |
218 | 284 |
219 await_reference_mb_row(h, &h->ref_list[1][0], mb_y); | 285 await_reference_mb_row(h, &h->ref_list[1][0], mb_y); |
220 | 286 |
221 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; | 287 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; |
222 l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; | 288 l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; |
223 l1ref0 = &h->ref_list[1][0].ref_index [0][h->mb2b8_xy[mb_xy]]; | 289 l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy]; |
224 l1ref1 = &h->ref_list[1][0].ref_index [1][h->mb2b8_xy[mb_xy]]; | 290 l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy]; |
225 if(!b8_stride){ | 291 if(!b8_stride){ |
226 if(s->mb_y&1){ | 292 if(s->mb_y&1){ |
227 l1ref0 += h->b8_stride; | 293 l1ref0 += 2; |
228 l1ref1 += h->b8_stride; | 294 l1ref1 += 2; |
229 l1mv0 += 2*b4_stride; | 295 l1mv0 += 2*b4_stride; |
230 l1mv1 += 2*b4_stride; | 296 l1mv1 += 2*b4_stride; |
231 } | 297 } |
232 } | 298 } |
233 | 299 |
234 if(h->direct_spatial_mv_pred){ | |
235 int ref[2]; | |
236 int mv[2][2]; | |
237 int list; | |
238 | |
239 /* FIXME interlacing + spatial direct uses wrong colocated block positio
ns */ | |
240 | |
241 /* ref = min(neighbors) */ | |
242 for(list=0; list<2; list++){ | |
243 int refa = h->ref_cache[list][scan8[0] - 1]; | |
244 int refb = h->ref_cache[list][scan8[0] - 8]; | |
245 int refc = h->ref_cache[list][scan8[0] - 8 + 4]; | |
246 if(refc == PART_NOT_AVAILABLE) | |
247 refc = h->ref_cache[list][scan8[0] - 8 - 1]; | |
248 ref[list] = FFMIN3((unsigned)refa, (unsigned)refb, (unsigned)refc); | |
249 if(ref[list] < 0) | |
250 ref[list] = -1; | |
251 } | |
252 | |
253 if(ref[0] < 0 && ref[1] < 0){ | |
254 ref[0] = ref[1] = 0; | |
255 mv[0][0] = mv[0][1] = | |
256 mv[1][0] = mv[1][1] = 0; | |
257 }else{ | |
258 for(list=0; list<2; list++){ | |
259 if(ref[list] >= 0) | |
260 pred_motion(h, 0, 4, list, ref[list], &mv[list][0], &mv[list
][1]); | |
261 else | |
262 mv[list][0] = mv[list][1] = 0; | |
263 } | |
264 } | |
265 | |
266 if(ref[1] < 0){ | |
267 if(!is_b8x8) | |
268 *mb_type &= ~MB_TYPE_L1; | |
269 sub_mb_type &= ~MB_TYPE_L1; | |
270 }else if(ref[0] < 0){ | |
271 if(!is_b8x8) | |
272 *mb_type &= ~MB_TYPE_L0; | |
273 sub_mb_type &= ~MB_TYPE_L0; | |
274 } | |
275 | 300 |
276 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ | 301 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ |
| 302 int n=0; |
277 for(i8=0; i8<4; i8++){ | 303 for(i8=0; i8<4; i8++){ |
278 int x8 = i8&1; | 304 int x8 = i8&1; |
279 int y8 = i8>>1; | 305 int y8 = i8>>1; |
280 int xy8 = x8+y8*b8_stride; | 306 int xy8 = x8+y8*b8_stride; |
281 int xy4 = 3*x8+y8*b4_stride; | 307 int xy4 = 3*x8+y8*b4_stride; |
282 int a=0, b=0; | 308 int a,b; |
283 | 309 |
284 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) | 310 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) |
285 continue; | 311 continue; |
286 h->sub_mb_type[i8] = sub_mb_type; | 312 h->sub_mb_type[i8] = sub_mb_type; |
287 | 313 |
288 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)
ref[0], 1); | 314 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)
ref[0], 1); |
289 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)
ref[1], 1); | 315 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)
ref[1], 1); |
290 if(!IS_INTRA(mb_type_col[y8]) | 316 if(!IS_INTRA(mb_type_col[y8]) && !h->ref_list[1][0].long_ref |
291 && ( (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFAB
S(l1mv0[xy4][1]) <= 1) | 317 && ( (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFAB
S(l1mv0[xy4][1]) <= 1) |
292 || (l1ref0[xy8] < 0 && l1ref1[xy8] == 0 && FFABS(l1mv1[x
y4][0]) <= 1 && FFABS(l1mv1[xy4][1]) <= 1))){ | 318 || (l1ref0[xy8] < 0 && l1ref1[xy8] == 0 && FFABS(l1mv1[x
y4][0]) <= 1 && FFABS(l1mv1[xy4][1]) <= 1))){ |
| 319 a=b=0; |
293 if(ref[0] > 0) | 320 if(ref[0] > 0) |
294 a= pack16to32(mv[0][0],mv[0][1]); | 321 a= mv[0]; |
295 if(ref[1] > 0) | 322 if(ref[1] > 0) |
296 b= pack16to32(mv[1][0],mv[1][1]); | 323 b= mv[1]; |
| 324 n++; |
297 }else{ | 325 }else{ |
298 a= pack16to32(mv[0][0],mv[0][1]); | 326 a= mv[0]; |
299 b= pack16to32(mv[1][0],mv[1][1]); | 327 b= mv[1]; |
300 } | 328 } |
301 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4); | 329 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4); |
302 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4); | 330 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4); |
303 } | 331 } |
| 332 if(!is_b8x8 && !(n&3)) |
| 333 *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB
_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2; |
304 }else if(IS_16X16(*mb_type)){ | 334 }else if(IS_16X16(*mb_type)){ |
305 int a=0, b=0; | 335 int a,b; |
306 | 336 |
307 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0],
1); | 337 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0],
1); |
308 fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1],
1); | 338 fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1],
1); |
309 if(!IS_INTRA(mb_type_col[0]) | 339 if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref |
310 && ( (l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && FFABS(l1mv0[
0][1]) <= 1) | 340 && ( (l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && FFABS(l1mv0[
0][1]) <= 1) |
311 || (l1ref0[0] < 0 && l1ref1[0] == 0 && FFABS(l1mv1[0][0]) <=
1 && FFABS(l1mv1[0][1]) <= 1 | 341 || (l1ref0[0] < 0 && l1ref1[0] == 0 && FFABS(l1mv1[0][0]) <=
1 && FFABS(l1mv1[0][1]) <= 1 |
312 && (h->x264_build>33 || !h->x264_build)))){ | 342 && h->x264_build>33U))){ |
| 343 a=b=0; |
313 if(ref[0] > 0) | 344 if(ref[0] > 0) |
314 a= pack16to32(mv[0][0],mv[0][1]); | 345 a= mv[0]; |
315 if(ref[1] > 0) | 346 if(ref[1] > 0) |
316 b= pack16to32(mv[1][0],mv[1][1]); | 347 b= mv[1]; |
317 }else{ | 348 }else{ |
318 a= pack16to32(mv[0][0],mv[0][1]); | 349 a= mv[0]; |
319 b= pack16to32(mv[1][0],mv[1][1]); | 350 b= mv[1]; |
320 } | 351 } |
321 fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4); | 352 fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4); |
322 fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4); | 353 fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4); |
323 }else{ | 354 }else{ |
| 355 int n=0; |
324 for(i8=0; i8<4; i8++){ | 356 for(i8=0; i8<4; i8++){ |
325 const int x8 = i8&1; | 357 const int x8 = i8&1; |
326 const int y8 = i8>>1; | 358 const int y8 = i8>>1; |
327 | 359 |
328 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) | 360 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) |
329 continue; | 361 continue; |
330 h->sub_mb_type[i8] = sub_mb_type; | 362 h->sub_mb_type[i8] = sub_mb_type; |
331 | 363 |
332 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32
(mv[0][0],mv[0][1]), 4); | 364 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, mv[0], 4); |
333 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32
(mv[1][0],mv[1][1]), 4); | 365 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, mv[1], 4); |
334 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)
ref[0], 1); | 366 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)
ref[0], 1); |
335 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)
ref[1], 1); | 367 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)
ref[1], 1); |
336 | 368 |
| 369 assert(b8_stride==2); |
337 /* col_zero_flag */ | 370 /* col_zero_flag */ |
338 if(!IS_INTRA(mb_type_col[0]) && ( l1ref0[x8 + y8*b8_stride] ==
0 | 371 if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref && (
l1ref0[i8] == 0 |
339 || (l1ref0[x8 + y8*b8_stride] < 0
&& l1ref1[x8 + y8*b8_stride] == 0 | 372 || (l1ref0[i8] < 0 && l1ref1[i8] =
= 0 |
340 && (h->x264_build>33 || !h->x2
64_build)))){ | 373 && h->x264_build>33U))){ |
341 const int16_t (*l1mv)[2]= l1ref0[x8 + y8*b8_stride] == 0 ? l
1mv0 : l1mv1; | 374 const int16_t (*l1mv)[2]= l1ref0[i8] == 0 ? l1mv0 : l1mv1; |
342 if(IS_SUB_8X8(sub_mb_type)){ | 375 if(IS_SUB_8X8(sub_mb_type)){ |
343 const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; | 376 const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; |
344 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ | 377 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ |
345 if(ref[0] == 0) | 378 if(ref[0] == 0) |
346 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2,
2, 8, 0, 4); | 379 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2,
2, 8, 0, 4); |
347 if(ref[1] == 0) | 380 if(ref[1] == 0) |
348 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2,
2, 8, 0, 4); | 381 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2,
2, 8, 0, 4); |
| 382 n+=4; |
349 } | 383 } |
350 }else | 384 }else{ |
| 385 int m=0; |
351 for(i4=0; i4<4; i4++){ | 386 for(i4=0; i4<4; i4++){ |
352 const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4
>>1))*b4_stride]; | 387 const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4
>>1))*b4_stride]; |
353 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ | 388 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ |
354 if(ref[0] == 0) | 389 if(ref[0] == 0) |
355 *(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0; | 390 AV_ZERO32(h->mv_cache[0][scan8[i8*4+i4]]); |
356 if(ref[1] == 0) | 391 if(ref[1] == 0) |
357 *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = 0; | 392 AV_ZERO32(h->mv_cache[1][scan8[i8*4+i4]]); |
| 393 m++; |
358 } | 394 } |
359 } | 395 } |
| 396 if(!(m&3)) |
| 397 h->sub_mb_type[i8]+= MB_TYPE_16x16 - MB_TYPE_8x8; |
| 398 n+=m; |
| 399 } |
360 } | 400 } |
361 } | 401 } |
| 402 if(!is_b8x8 && !(n&15)) |
| 403 *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB
_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2; |
362 } | 404 } |
363 }else{ /* direct temporal mv pred */ | 405 } |
| 406 |
| 407 static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ |
| 408 MpegEncContext * const s = &h->s; |
| 409 int b8_stride = 2; |
| 410 int b4_stride = h->b_stride; |
| 411 int mb_xy = h->mb_xy, mb_y = s->mb_y; |
| 412 int mb_type_col[2]; |
| 413 const int16_t (*l1mv0)[2], (*l1mv1)[2]; |
| 414 const int8_t *l1ref0, *l1ref1; |
| 415 const int is_b8x8 = IS_8X8(*mb_type); |
| 416 unsigned int sub_mb_type; |
| 417 int i8, i4; |
| 418 |
| 419 assert(h->ref_list[1][0].reference&3); |
| 420 |
| 421 await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_
type)); |
| 422 |
| 423 if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL
/FL |
| 424 if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL
/FL |
| 425 mb_y = (s->mb_y&~1) + h->col_parity; |
| 426 mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; |
| 427 b8_stride = 0; |
| 428 }else{ |
| 429 mb_y += h->col_fieldoff; |
| 430 mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & di
ffer parity |
| 431 } |
| 432 goto single_col; |
| 433 }else{ // AFL/AFR/FR/FL -> AFR
/FR |
| 434 if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR
/FR |
| 435 mb_y = s->mb_y&~1; |
| 436 mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride; |
| 437 mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; |
| 438 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; |
| 439 b8_stride = 2+4*s->mb_stride; |
| 440 b4_stride *= 6; |
| 441 |
| 442 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT
2; /* B_SUB_8x8 */ |
| 443 |
| 444 if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) |
| 445 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) |
| 446 && !is_b8x8){ |
| 447 *mb_type |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_1
6x8 */ |
| 448 }else{ |
| 449 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; |
| 450 } |
| 451 }else{ // AFR/FR -> AFR
/FR |
| 452 single_col: |
| 453 mb_type_col[0] = |
| 454 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; |
| 455 |
| 456 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT
2; /* B_SUB_8x8 */ |
| 457 if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ |
| 458 *mb_type |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DI
RECT2; /* B_16x16 */ |
| 459 }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)))
{ |
| 460 *mb_type |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (
MB_TYPE_16x8|MB_TYPE_8x16)); |
| 461 }else{ |
| 462 if(!h->sps.direct_8x8_inference_flag){ |
| 463 /* FIXME save sub mb types from previous frames (or derive f
rom MVs) |
| 464 * so we know exactly what block size to use */ |
| 465 sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_
DIRECT2; /* B_SUB_4x4 */ |
| 466 } |
| 467 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; |
| 468 } |
| 469 } |
| 470 } |
| 471 |
| 472 await_reference_mb_row(h, &h->ref_list[1][0], mb_y); |
| 473 |
| 474 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; |
| 475 l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; |
| 476 l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy]; |
| 477 l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy]; |
| 478 if(!b8_stride){ |
| 479 if(s->mb_y&1){ |
| 480 l1ref0 += 2; |
| 481 l1ref1 += 2; |
| 482 l1mv0 += 2*b4_stride; |
| 483 l1mv1 += 2*b4_stride; |
| 484 } |
| 485 } |
| 486 |
| 487 { |
364 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_
list0[1]}; | 488 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_
list0[1]}; |
365 const int *dist_scale_factor = h->dist_scale_factor; | 489 const int *dist_scale_factor = h->dist_scale_factor; |
366 int ref_offset= 0; | 490 int ref_offset; |
367 | 491 |
368 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ | 492 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ |
369 map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; | 493 map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; |
370 map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; | 494 map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; |
371 dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; | 495 dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; |
372 } | 496 } |
373 if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) | 497 ref_offset = (h->ref_list[1][0].mbaff<<4) & (mb_type_col[0]>>3); //if(h-
>ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) ref_offset=16 else 0 |
374 ref_offset += 16; | |
375 | 498 |
376 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ | 499 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ |
377 /* FIXME assumes direct_8x8_inference == 1 */ | |
378 int y_shift = 2*!IS_INTERLACED(*mb_type); | 500 int y_shift = 2*!IS_INTERLACED(*mb_type); |
| 501 assert(h->sps.direct_8x8_inference_flag); |
379 | 502 |
380 for(i8=0; i8<4; i8++){ | 503 for(i8=0; i8<4; i8++){ |
381 const int x8 = i8&1; | 504 const int x8 = i8&1; |
382 const int y8 = i8>>1; | 505 const int y8 = i8>>1; |
383 int ref0, scale; | 506 int ref0, scale; |
384 const int16_t (*l1mv)[2]= l1mv0; | 507 const int16_t (*l1mv)[2]= l1mv0; |
385 | 508 |
386 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) | 509 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) |
387 continue; | 510 continue; |
388 h->sub_mb_type[i8] = sub_mb_type; | 511 h->sub_mb_type[i8] = sub_mb_type; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 continue; | 574 continue; |
452 h->sub_mb_type[i8] = sub_mb_type; | 575 h->sub_mb_type[i8] = sub_mb_type; |
453 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); | 576 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); |
454 if(IS_INTRA(mb_type_col[0])){ | 577 if(IS_INTRA(mb_type_col[0])){ |
455 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1)
; | 578 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1)
; |
456 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4)
; | 579 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4)
; |
457 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4)
; | 580 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4)
; |
458 continue; | 581 continue; |
459 } | 582 } |
460 | 583 |
461 ref0 = l1ref0[x8 + y8*b8_stride] + ref_offset; | 584 assert(b8_stride == 2); |
| 585 ref0 = l1ref0[i8]; |
462 if(ref0 >= 0) | 586 if(ref0 >= 0) |
463 ref0 = map_col_to_list0[0][ref0]; | 587 ref0 = map_col_to_list0[0][ref0 + ref_offset]; |
464 else{ | 588 else{ |
465 ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_o
ffset]; | 589 ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset]; |
466 l1mv= l1mv1; | 590 l1mv= l1mv1; |
467 } | 591 } |
468 scale = dist_scale_factor[ref0]; | 592 scale = dist_scale_factor[ref0]; |
469 | 593 |
470 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); | 594 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); |
471 if(IS_SUB_8X8(sub_mb_type)){ | 595 if(IS_SUB_8X8(sub_mb_type)){ |
472 const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; | 596 const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; |
473 int mx = (scale * mv_col[0] + 128) >> 8; | 597 int mx = (scale * mv_col[0] + 128) >> 8; |
474 int my = (scale * mv_col[1] + 128) >> 8; | 598 int my = (scale * mv_col[1] + 128) >> 8; |
475 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16
to32(mx,my), 4); | 599 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16
to32(mx,my), 4); |
476 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16
to32(mx-mv_col[0],my-mv_col[1]), 4); | 600 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16
to32(mx-mv_col[0],my-mv_col[1]), 4); |
477 }else | 601 }else |
478 for(i4=0; i4<4; i4++){ | 602 for(i4=0; i4<4; i4++){ |
479 const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1)
)*b4_stride]; | 603 const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1)
)*b4_stride]; |
480 int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; | 604 int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; |
481 mv_l0[0] = (scale * mv_col[0] + 128) >> 8; | 605 mv_l0[0] = (scale * mv_col[0] + 128) >> 8; |
482 mv_l0[1] = (scale * mv_col[1] + 128) >> 8; | 606 mv_l0[1] = (scale * mv_col[1] + 128) >> 8; |
483 *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = | 607 AV_WN32A(h->mv_cache[1][scan8[i8*4+i4]], |
484 pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]); | 608 pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1])); |
485 } | 609 } |
486 } | 610 } |
487 } | 611 } |
488 } | 612 } |
489 } | 613 } |
| 614 |
| 615 void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){ |
| 616 if(h->direct_spatial_mv_pred){ |
| 617 pred_spatial_direct_motion(h, mb_type); |
| 618 }else{ |
| 619 pred_temp_direct_motion(h, mb_type); |
| 620 } |
| 621 } |
OLD | NEW |