Mercurial > libavcodec.hg
annotate h264_direct.c @ 11104:bb877c9cb102 libavcodec
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
as 16x16 (except ones changing interlacing relative to the colocated MB).
20 cycles slower during MV generation
175 cycles faster during MC
author | michael |
---|---|
date | Mon, 08 Feb 2010 16:23:05 +0000 |
parents | 3bc0125e19fe |
children | 77c5116751b7 |
rev | line source |
---|---|
1168 | 1 /* |
10857
b20434143fd5
Split direct mode (macro)block decoding off h264.c.
michael
parents:
10854
diff
changeset
|
2 * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding |
1168 | 3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3927
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3927
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3927
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1168 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3927
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1168 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3927
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1168 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3927
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
3029
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1168 | 20 */ |
2967 | 21 |
1168 | 22 /** |
10857
b20434143fd5
Split direct mode (macro)block decoding off h264.c.
michael
parents:
10854
diff
changeset
|
23 * @file libavcodec/h264_direct.c |
b20434143fd5
Split direct mode (macro)block decoding off h264.c.
michael
parents:
10854
diff
changeset
|
24 * H.264 / AVC / MPEG4 part10 direct mb/block decoding. |
1168 | 25 * @author Michael Niedermayer <michaelni@gmx.at> |
26 */ | |
27 | |
9012
15a3df8c01fd
More approved hunks for VAAPI & our new and cleaner hwaccel API.
michael
parents:
9004
diff
changeset
|
28 #include "internal.h" |
1168 | 29 #include "dsputil.h" |
30 #include "avcodec.h" | |
31 #include "mpegvideo.h" | |
4975 | 32 #include "h264.h" |
6020 | 33 #include "rectangle.h" |
1168 | 34 |
3284
a224d9752912
don't force asserts in release builds. 2% faster h264.
lorenm
parents:
3219
diff
changeset
|
35 //#undef NDEBUG |
1168 | 36 #include <assert.h> |
37 | |
38 | |
7898
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
39 static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){ |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
40 int poc0 = h->ref_list[0][i].poc; |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
41 int td = av_clip(poc1 - poc0, -128, 127); |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
42 if(td == 0 || h->ref_list[0][i].long_ref){ |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
43 return 256; |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
44 }else{ |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
45 int tb = av_clip(poc - poc0, -128, 127); |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
46 int tx = (16384 + (FFABS(td) >> 1)) / td; |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
47 return av_clip((tb*tx + 32) >> 6, -1024, 1023); |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
48 } |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
49 } |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
50 |
10857
b20434143fd5
Split direct mode (macro)block decoding off h264.c.
michael
parents:
10854
diff
changeset
|
51 void ff_h264_direct_dist_scale_factor(H264Context * const h){ |
7462
5cbf11f56c02
Picture.ref_count/ref_poc have to be stored per field (actually also per
michael
parents:
7450
diff
changeset
|
52 MpegEncContext * const s = &h->s; |
5cbf11f56c02
Picture.ref_count/ref_poc have to be stored per field (actually also per
michael
parents:
7450
diff
changeset
|
53 const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ]; |
2396 | 54 const int poc1 = h->ref_list[1][0].poc; |
7898
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
55 int i, field; |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
56 for(field=0; field<2; field++){ |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
57 const int poc = h->s.current_picture_ptr->field_poc[field]; |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
58 const int poc1 = h->ref_list[1][0].field_poc[field]; |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
59 for(i=0; i < 2*h->ref_count[0]; i++) |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
60 h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, poc, poc1, i+16); |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
61 } |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
62 |
2396 | 63 for(i=0; i<h->ref_count[0]; i++){ |
7898
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
64 h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i); |
3316 | 65 } |
2396 | 66 } |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
67 |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
68 static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){ |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
69 MpegEncContext * const s = &h->s; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
70 Picture * const ref1 = &h->ref_list[1][0]; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
71 int j, old_ref, rfield; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
72 int start= mbafi ? 16 : 0; |
11086 | 73 int end = mbafi ? 16+2*h->ref_count[0] : h->ref_count[0]; |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
74 int interl= mbafi || s->picture_structure != PICT_FRAME; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
75 |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
76 /* bogus; fills in for missing frames */ |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
77 memset(map[list], 0, sizeof(map[list])); |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
78 |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
79 for(rfield=0; rfield<2; rfield++){ |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
80 for(old_ref=0; old_ref<ref1->ref_count[colfield][list]; old_ref++){ |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
81 int poc = ref1->ref_poc[colfield][list][old_ref]; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
82 |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
83 if (!interl) |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
84 poc |= 3; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
85 else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
86 poc= (poc&~3) + rfield + 1; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
87 |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
88 for(j=start; j<end; j++){ |
11086 | 89 if(4*h->ref_list[0][j].frame_num + (h->ref_list[0][j].reference&3) == poc){ |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
90 int cur_ref= mbafi ? (j-16)^field : j; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
91 map[list][2*old_ref + (rfield^field) + 16] = cur_ref; |
11086 | 92 if(rfield == field || !interl) |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
93 map[list][old_ref] = cur_ref; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
94 break; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
95 } |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
96 } |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
97 } |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
98 } |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
99 } |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
100 |
10857
b20434143fd5
Split direct mode (macro)block decoding off h264.c.
michael
parents:
10854
diff
changeset
|
101 void ff_h264_direct_ref_list_init(H264Context * const h){ |
2537
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
102 MpegEncContext * const s = &h->s; |
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
103 Picture * const ref1 = &h->ref_list[1][0]; |
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
104 Picture * const cur = s->current_picture_ptr; |
7928 | 105 int list, j, field; |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
106 int sidx= (s->picture_structure&1)^1; |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
107 int ref1sidx= (ref1->reference&1)^1; |
7907 | 108 |
2537
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
109 for(list=0; list<2; list++){ |
7462
5cbf11f56c02
Picture.ref_count/ref_poc have to be stored per field (actually also per
michael
parents:
7450
diff
changeset
|
110 cur->ref_count[sidx][list] = h->ref_count[list]; |
2537
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
111 for(j=0; j<h->ref_count[list]; j++) |
7487
13937730e79d
Use frame_num and reference instead of poc for matching frames for direct
michael
parents:
7486
diff
changeset
|
112 cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3); |
2537
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
113 } |
7907 | 114 |
7482 | 115 if(s->picture_structure == PICT_FRAME){ |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
116 memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
117 memcpy(cur->ref_poc [1], cur->ref_poc [0], sizeof(cur->ref_poc [0])); |
7482 | 118 } |
7907 | 119 |
7902
8b8be8f2b647
Fix ref_shift so that it is correct for more/all? MBAFF/PAFF mixes.
michael
parents:
7901
diff
changeset
|
120 cur->mbaff= FRAME_MBAFF; |
7907 | 121 |
11093
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
122 h->col_fieldoff= 0; |
11085
27b5a2bd1dfe
Fix reference selection for colocated MBs from frames to fields.
michael
parents:
11084
diff
changeset
|
123 if(s->picture_structure == PICT_FRAME){ |
27b5a2bd1dfe
Fix reference selection for colocated MBs from frames to fields.
michael
parents:
11084
diff
changeset
|
124 int cur_poc = s->current_picture_ptr->poc; |
27b5a2bd1dfe
Fix reference selection for colocated MBs from frames to fields.
michael
parents:
11084
diff
changeset
|
125 int *col_poc = h->ref_list[1]->field_poc; |
11093
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
126 h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc)); |
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
127 ref1sidx=sidx= h->col_parity; |
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
128 }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff){ // FL -> FL & differ parity |
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
129 h->col_fieldoff= s->mb_stride*(2*(h->ref_list[1][0].reference) - 3); |
11085
27b5a2bd1dfe
Fix reference selection for colocated MBs from frames to fields.
michael
parents:
11084
diff
changeset
|
130 } |
27b5a2bd1dfe
Fix reference selection for colocated MBs from frames to fields.
michael
parents:
11084
diff
changeset
|
131 |
11093
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
132 if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) |
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
133 return; |
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
134 |
2537
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
135 for(list=0; list<2; list++){ |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
136 fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0); |
11088
1bfb70c225bb
Skip the fill_colmap() case thats for MBAFF if we dont have an MBAFF frame.
michael
parents:
11086
diff
changeset
|
137 if(FRAME_MBAFF) |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
138 for(field=0; field<2; field++) |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
139 fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1); |
2537
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
140 } |
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
141 } |
2396 | 142 |
10857
b20434143fd5
Split direct mode (macro)block decoding off h264.c.
michael
parents:
10854
diff
changeset
|
143 void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){ |
2396 | 144 MpegEncContext * const s = &h->s; |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
145 int b8_stride = h->b8_stride; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
146 int b4_stride = h->b_stride; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
147 int mb_xy = h->mb_xy; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
148 int mb_type_col[2]; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
149 const int16_t (*l1mv0)[2], (*l1mv1)[2]; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
150 const int8_t *l1ref0, *l1ref1; |
2396 | 151 const int is_b8x8 = IS_8X8(*mb_type); |
4365
9cebff821565
checking bitstream values and other related changes
michael
parents:
4364
diff
changeset
|
152 unsigned int sub_mb_type; |
2396 | 153 int i8, i4; |
154 | |
9416
d863de897b41
Assert that the first list1 entry is a reference frame.
michael
parents:
9415
diff
changeset
|
155 assert(h->ref_list[1][0].reference&3); |
d863de897b41
Assert that the first list1 entry is a reference frame.
michael
parents:
9415
diff
changeset
|
156 |
3316 | 157 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM) |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
158 |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
159 if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL |
7900 | 160 if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL |
11093
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
161 mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; |
7901 | 162 b8_stride = 0; |
11093
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
163 }else{ |
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
164 mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
165 } |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
166 goto single_col; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
167 }else{ // AFL/AFR/FR/FL -> AFR/FR |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
168 if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
169 mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
170 mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
171 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
172 b8_stride *= 3; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
173 b4_stride *= 6; |
11090
eda7b4f6db51
Remove FIXMEs for cases that are disallowed by the spec.
michael
parents:
11088
diff
changeset
|
174 |
11091 | 175 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
176 if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
177 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
178 && !is_b8x8){ |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
179 *mb_type |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_16x8 */ |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
180 }else{ |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
181 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
182 } |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
183 }else{ // AFR/FR -> AFR/FR |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
184 single_col: |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
185 mb_type_col[0] = |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
186 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; |
7494 | 187 if(IS_8X8(mb_type_col[0]) && !h->sps.direct_8x8_inference_flag){ |
188 /* FIXME save sub mb types from previous frames (or derive from MVs) | |
189 * so we know exactly what block size to use */ | |
190 sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */ | |
191 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | |
192 }else if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ | |
193 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ | |
194 *mb_type |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */ | |
11092
64c36264b13f
Set direct MB partitioning for 16x8 and 8x16 colocated MBs to the respective true partitioning.
michael
parents:
11091
diff
changeset
|
195 }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){ |
64c36264b13f
Set direct MB partitioning for 16x8 and 8x16 colocated MBs to the respective true partitioning.
michael
parents:
11091
diff
changeset
|
196 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ |
64c36264b13f
Set direct MB partitioning for 16x8 and 8x16 colocated MBs to the respective true partitioning.
michael
parents:
11091
diff
changeset
|
197 *mb_type |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)); |
7494 | 198 }else{ |
199 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ | |
200 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | |
201 } | |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
202 } |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
203 } |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
204 |
7497 | 205 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; |
206 l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; | |
207 l1ref0 = &h->ref_list[1][0].ref_index [0][h->mb2b8_xy[mb_xy]]; | |
208 l1ref1 = &h->ref_list[1][0].ref_index [1][h->mb2b8_xy[mb_xy]]; | |
7496 | 209 if(!b8_stride){ |
210 if(s->mb_y&1){ | |
211 l1ref0 += h->b8_stride; | |
212 l1ref1 += h->b8_stride; | |
213 l1mv0 += 2*b4_stride; | |
214 l1mv1 += 2*b4_stride; | |
215 } | |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
216 } |
2967 | 217 |
2396 | 218 if(h->direct_spatial_mv_pred){ |
219 int ref[2]; | |
220 int mv[2][2]; | |
221 int list; | |
222 | |
223 /* ref = min(neighbors) */ | |
224 for(list=0; list<2; list++){ | |
11099
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
225 int left_ref = h->ref_cache[list][scan8[0] - 1]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
226 int top_ref = h->ref_cache[list][scan8[0] - 8]; |
2396 | 227 int refc = h->ref_cache[list][scan8[0] - 8 + 4]; |
11099
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
228 const int16_t *C= h->mv_cache[list][ scan8[0] - 8 + 4]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
229 if(refc == PART_NOT_AVAILABLE){ |
2396 | 230 refc = h->ref_cache[list][scan8[0] - 8 - 1]; |
11099
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
231 C = h-> mv_cache[list][scan8[0] - 8 - 1]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
232 } |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
233 ref[list] = FFMIN3((unsigned)left_ref, (unsigned)top_ref, (unsigned)refc); |
11094
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
234 if(ref[list] >= 0){ |
11099
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
235 //this is just pred_motion() but with the cases removed that cannot happen for direct blocks |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
236 const int16_t * const A= h->mv_cache[list][ scan8[0] - 1 ]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
237 const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
238 |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
239 int match_count= (left_ref==ref[list]) + (top_ref==ref[list]) + (refc==ref[list]); |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
240 if(match_count > 1){ //most common |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
241 mv[list][0]= mid_pred(A[0], B[0], C[0]); |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
242 mv[list][1]= mid_pred(A[1], B[1], C[1]); |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
243 }else { |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
244 assert(match_count==1); |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
245 if(left_ref==ref[list]){ |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
246 mv[list][0]= A[0]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
247 mv[list][1]= A[1]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
248 }else if(top_ref==ref[list]){ |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
249 mv[list][0]= B[0]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
250 mv[list][1]= B[1]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
251 }else{ |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
252 mv[list][0]= C[0]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
253 mv[list][1]= C[1]; |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
254 } |
8023ba45995f
Replace call to pred_motion() in direct spatial mv pred by code
michael
parents:
11097
diff
changeset
|
255 } |
11094
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
256 }else{ |
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
257 int mask= ~(MB_TYPE_L0 << (2*list)); |
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
258 mv[list][0] = mv[list][1] = 0; |
2396 | 259 ref[list] = -1; |
11094
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
260 if(!is_b8x8) |
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
261 *mb_type &= mask; |
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
262 sub_mb_type &= mask; |
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
263 } |
2396 | 264 } |
265 if(ref[0] < 0 && ref[1] < 0){ | |
266 ref[0] = ref[1] = 0; | |
6309 | 267 if(!is_b8x8) |
11094
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
268 *mb_type |= MB_TYPE_L0L1; |
323491bb995c
Merge mv&ref related code for spatial direct MV code.
michael
parents:
11093
diff
changeset
|
269 sub_mb_type |= MB_TYPE_L0L1; |
6309 | 270 } |
271 | |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
272 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ |
6309 | 273 for(i8=0; i8<4; i8++){ |
274 int x8 = i8&1; | |
275 int y8 = i8>>1; | |
276 int xy8 = x8+y8*b8_stride; | |
277 int xy4 = 3*x8+y8*b4_stride; | |
11095
2aeb7a1d1c7f
Zero a/b only in the branch where they need to be zeroed.
michael
parents:
11094
diff
changeset
|
278 int a,b; |
6309 | 279 |
280 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) | |
281 continue; | |
282 h->sub_mb_type[i8] = sub_mb_type; | |
283 | |
284 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1); | |
285 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1); | |
11078
e1eb8879e368
Long term references behave different from short term in spatial direct MV calculation.
michael
parents:
10929
diff
changeset
|
286 if(!IS_INTRA(mb_type_col[y8]) && !h->ref_list[1][0].long_ref |
6309 | 287 && ( (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFABS(l1mv0[xy4][1]) <= 1) |
288 || (l1ref0[xy8] < 0 && l1ref1[xy8] == 0 && FFABS(l1mv1[xy4][0]) <= 1 && FFABS(l1mv1[xy4][1]) <= 1))){ | |
11095
2aeb7a1d1c7f
Zero a/b only in the branch where they need to be zeroed.
michael
parents:
11094
diff
changeset
|
289 a=b=0; |
6309 | 290 if(ref[0] > 0) |
291 a= pack16to32(mv[0][0],mv[0][1]); | |
292 if(ref[1] > 0) | |
293 b= pack16to32(mv[1][0],mv[1][1]); | |
294 }else{ | |
295 a= pack16to32(mv[0][0],mv[0][1]); | |
296 b= pack16to32(mv[1][0],mv[1][1]); | |
297 } | |
298 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4); | |
299 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4); | |
300 } | |
301 }else if(IS_16X16(*mb_type)){ | |
11095
2aeb7a1d1c7f
Zero a/b only in the branch where they need to be zeroed.
michael
parents:
11094
diff
changeset
|
302 int a,b; |
4540 | 303 |
3001
b52d8ee430f6
fix some potential arithmetic overflows in pred_direct_motion() and
lorenm
parents:
2979
diff
changeset
|
304 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); |
b52d8ee430f6
fix some potential arithmetic overflows in pred_direct_motion() and
lorenm
parents:
2979
diff
changeset
|
305 fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1); |
11078
e1eb8879e368
Long term references behave different from short term in spatial direct MV calculation.
michael
parents:
10929
diff
changeset
|
306 if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref |
4001 | 307 && ( (l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && FFABS(l1mv0[0][1]) <= 1) |
308 || (l1ref0[0] < 0 && l1ref1[0] == 0 && FFABS(l1mv1[0][0]) <= 1 && FFABS(l1mv1[0][1]) <= 1 | |
11097 | 309 && h->x264_build>33U))){ |
11095
2aeb7a1d1c7f
Zero a/b only in the branch where they need to be zeroed.
michael
parents:
11094
diff
changeset
|
310 a=b=0; |
2396 | 311 if(ref[0] > 0) |
4540 | 312 a= pack16to32(mv[0][0],mv[0][1]); |
2396 | 313 if(ref[1] > 0) |
4540 | 314 b= pack16to32(mv[1][0],mv[1][1]); |
2396 | 315 }else{ |
4540 | 316 a= pack16to32(mv[0][0],mv[0][1]); |
317 b= pack16to32(mv[1][0],mv[1][1]); | |
318 } | |
319 fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4); | |
320 fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4); | |
2396 | 321 }else{ |
11104
bb877c9cb102
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
michael
parents:
11103
diff
changeset
|
322 int n=0; |
2396 | 323 for(i8=0; i8<4; i8++){ |
324 const int x8 = i8&1; | |
325 const int y8 = i8>>1; | |
2967 | 326 |
2396 | 327 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) |
328 continue; | |
329 h->sub_mb_type[i8] = sub_mb_type; | |
2967 | 330 |
2396 | 331 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mv[0][0],mv[0][1]), 4); |
332 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mv[1][0],mv[1][1]), 4); | |
3001
b52d8ee430f6
fix some potential arithmetic overflows in pred_direct_motion() and
lorenm
parents:
2979
diff
changeset
|
333 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1); |
b52d8ee430f6
fix some potential arithmetic overflows in pred_direct_motion() and
lorenm
parents:
2979
diff
changeset
|
334 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1); |
2967 | 335 |
2396 | 336 /* col_zero_flag */ |
11078
e1eb8879e368
Long term references behave different from short term in spatial direct MV calculation.
michael
parents:
10929
diff
changeset
|
337 if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref && ( l1ref0[x8 + y8*b8_stride] == 0 |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
338 || (l1ref0[x8 + y8*b8_stride] < 0 && l1ref1[x8 + y8*b8_stride] == 0 |
11097 | 339 && h->x264_build>33U))){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
340 const int16_t (*l1mv)[2]= l1ref0[x8 + y8*b8_stride] == 0 ? l1mv0 : l1mv1; |
3002 | 341 if(IS_SUB_8X8(sub_mb_type)){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
342 const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; |
4001 | 343 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ |
3002 | 344 if(ref[0] == 0) |
345 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); | |
346 if(ref[1] == 0) | |
347 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); | |
11104
bb877c9cb102
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
michael
parents:
11103
diff
changeset
|
348 n+=4; |
3002 | 349 } |
11103 | 350 }else{ |
351 int m=0; | |
2396 | 352 for(i4=0; i4<4; i4++){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
353 const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride]; |
4001 | 354 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ |
2396 | 355 if(ref[0] == 0) |
356 *(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0; | |
357 if(ref[1] == 0) | |
358 *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = 0; | |
11103 | 359 m++; |
2396 | 360 } |
361 } | |
11103 | 362 if(!(m&3)) |
363 h->sub_mb_type[i8]+= MB_TYPE_16x16 - MB_TYPE_8x8; | |
11104
bb877c9cb102
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
michael
parents:
11103
diff
changeset
|
364 n+=m; |
11103 | 365 } |
2396 | 366 } |
367 } | |
11104
bb877c9cb102
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
michael
parents:
11103
diff
changeset
|
368 if(!is_b8x8 && !(n&15)) |
bb877c9cb102
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
michael
parents:
11103
diff
changeset
|
369 *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; |
2396 | 370 } |
371 }else{ /* direct temporal mv pred */ | |
3316 | 372 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; |
373 const int *dist_scale_factor = h->dist_scale_factor; | |
11101 | 374 int ref_offset; |
3316 | 375 |
7494 | 376 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ |
7898
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
377 map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
378 map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; |
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
379 dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; |
7902
8b8be8f2b647
Fix ref_shift so that it is correct for more/all? MBAFF/PAFF mixes.
michael
parents:
7901
diff
changeset
|
380 } |
11101 | 381 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 |
7902
8b8be8f2b647
Fix ref_shift so that it is correct for more/all? MBAFF/PAFF mixes.
michael
parents:
7901
diff
changeset
|
382 |
7494 | 383 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ |
7495 | 384 int y_shift = 2*!IS_INTERLACED(*mb_type); |
11084
6e564ab180d1
Add assert(sps.direct_8x8_inference_flag) to FIXME comment.
michael
parents:
11083
diff
changeset
|
385 assert(h->sps.direct_8x8_inference_flag); |
7494 | 386 |
387 for(i8=0; i8<4; i8++){ | |
388 const int x8 = i8&1; | |
389 const int y8 = i8>>1; | |
390 int ref0, scale; | |
391 const int16_t (*l1mv)[2]= l1mv0; | |
392 | |
393 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) | |
394 continue; | |
395 h->sub_mb_type[i8] = sub_mb_type; | |
396 | |
397 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); | |
398 if(IS_INTRA(mb_type_col[y8])){ | |
399 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1); | |
400 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); | |
401 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); | |
402 continue; | |
3316 | 403 } |
404 | |
7494 | 405 ref0 = l1ref0[x8 + y8*b8_stride]; |
406 if(ref0 >= 0) | |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
407 ref0 = map_col_to_list0[0][ref0 + ref_offset]; |
7494 | 408 else{ |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
409 ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; |
7494 | 410 l1mv= l1mv1; |
3316 | 411 } |
7494 | 412 scale = dist_scale_factor[ref0]; |
413 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); | |
414 | |
415 { | |
416 const int16_t *mv_col = l1mv[x8*3 + y8*b4_stride]; | |
417 int my_col = (mv_col[1]<<y_shift)/2; | |
418 int mx = (scale * mv_col[0] + 128) >> 8; | |
419 int my = (scale * my_col + 128) >> 8; | |
420 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4); | |
421 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-my_col), 4); | |
422 } | |
423 } | |
424 return; | |
425 } | |
3316 | 426 |
427 /* one-to-one mv scaling */ | |
428 | |
2396 | 429 if(IS_16X16(*mb_type)){ |
4541 | 430 int ref, mv0, mv1; |
431 | |
2396 | 432 fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
433 if(IS_INTRA(mb_type_col[0])){ |
4541 | 434 ref=mv0=mv1=0; |
2396 | 435 }else{ |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
436 const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset] |
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
437 : map_col_to_list0[1][l1ref1[0] + ref_offset]; |
3316 | 438 const int scale = dist_scale_factor[ref0]; |
2809
75400dfbe117
fixing colocated mv if colocated block is L1 predicted for the temporal direct case
michael
parents:
2808
diff
changeset
|
439 const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; |
2396 | 440 int mv_l0[2]; |
3316 | 441 mv_l0[0] = (scale * mv_col[0] + 128) >> 8; |
442 mv_l0[1] = (scale * mv_col[1] + 128) >> 8; | |
4541 | 443 ref= ref0; |
444 mv0= pack16to32(mv_l0[0],mv_l0[1]); | |
445 mv1= pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]); | |
446 } | |
447 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); | |
448 fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4); | |
449 fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4); | |
2396 | 450 }else{ |
451 for(i8=0; i8<4; i8++){ | |
452 const int x8 = i8&1; | |
453 const int y8 = i8>>1; | |
3316 | 454 int ref0, scale; |
2834 | 455 const int16_t (*l1mv)[2]= l1mv0; |
2809
75400dfbe117
fixing colocated mv if colocated block is L1 predicted for the temporal direct case
michael
parents:
2808
diff
changeset
|
456 |
2396 | 457 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) |
458 continue; | |
459 h->sub_mb_type[i8] = sub_mb_type; | |
3316 | 460 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
461 if(IS_INTRA(mb_type_col[0])){ |
2396 | 462 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1); |
463 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); | |
464 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); | |
465 continue; | |
466 } | |
2967 | 467 |
11083
a270b4c67089
ref_offset must be added after checking references validity.
michael
parents:
11078
diff
changeset
|
468 ref0 = l1ref0[x8 + y8*b8_stride]; |
2537
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
469 if(ref0 >= 0) |
11083
a270b4c67089
ref_offset must be added after checking references validity.
michael
parents:
11078
diff
changeset
|
470 ref0 = map_col_to_list0[0][ref0 + ref_offset]; |
2809
75400dfbe117
fixing colocated mv if colocated block is L1 predicted for the temporal direct case
michael
parents:
2808
diff
changeset
|
471 else{ |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
472 ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; |
2809
75400dfbe117
fixing colocated mv if colocated block is L1 predicted for the temporal direct case
michael
parents:
2808
diff
changeset
|
473 l1mv= l1mv1; |
75400dfbe117
fixing colocated mv if colocated block is L1 predicted for the temporal direct case
michael
parents:
2808
diff
changeset
|
474 } |
3316 | 475 scale = dist_scale_factor[ref0]; |
2967 | 476 |
2396 | 477 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); |
3002 | 478 if(IS_SUB_8X8(sub_mb_type)){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
479 const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; |
3316 | 480 int mx = (scale * mv_col[0] + 128) >> 8; |
481 int my = (scale * mv_col[1] + 128) >> 8; | |
3002 | 482 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4); |
483 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-mv_col[1]), 4); | |
484 }else | |
2396 | 485 for(i4=0; i4<4; i4++){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
486 const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride]; |
2396 | 487 int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; |
3316 | 488 mv_l0[0] = (scale * mv_col[0] + 128) >> 8; |
489 mv_l0[1] = (scale * mv_col[1] + 128) >> 8; | |
2396 | 490 *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = |
491 pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]); | |
492 } | |
493 } | |
494 } | |
495 } | |
496 } |