Mercurial > libavcodec.hg
annotate h264_direct.c @ 12197:fbf4d5b1b664 libavcodec
Remove FF_MM_SSE2/3 flags for CPUs where this is generally not faster than
regular MMX code. Examples of this are the Core1 CPU. Instead, set a new flag,
FF_MM_SSE2/3SLOW, which can be checked for particular SSE2/3 functions that
have been checked specifically on such CPUs and are actually faster than
their MMX counterparts.
In addition, use this flag to enable particular VP8 and LPC SSE2 functions
that are faster than their MMX counterparts.
Based on a patch by Loren Merritt <lorenm AT u washington edu>.
author | rbultje |
---|---|
date | Mon, 19 Jul 2010 22:38:23 +0000 |
parents | 7dd2a45249a9 |
children |
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 /** |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11292
diff
changeset
|
23 * @file |
10857
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 |
11139 | 143 static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ |
2396 | 144 MpegEncContext * const s = &h->s; |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
145 int b8_stride = 2; |
7493
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); |
11174 | 152 unsigned int sub_mb_type= MB_TYPE_L0L1; |
2396 | 153 int i8, i4; |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
154 int ref[2]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
155 int mv[2]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
156 int list; |
2396 | 157 |
9416
d863de897b41
Assert that the first list1 entry is a reference frame.
michael
parents:
9415
diff
changeset
|
158 assert(h->ref_list[1][0].reference&3); |
d863de897b41
Assert that the first list1 entry is a reference frame.
michael
parents:
9415
diff
changeset
|
159 |
3316 | 160 #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
|
161 |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
162 |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
163 /* ref = min(neighbors) */ |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
164 for(list=0; list<2; list++){ |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
165 int left_ref = h->ref_cache[list][scan8[0] - 1]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
166 int top_ref = h->ref_cache[list][scan8[0] - 8]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
167 int refc = h->ref_cache[list][scan8[0] - 8 + 4]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
168 const int16_t *C= h->mv_cache[list][ scan8[0] - 8 + 4]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
169 if(refc == PART_NOT_AVAILABLE){ |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
170 refc = h->ref_cache[list][scan8[0] - 8 - 1]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
171 C = h-> mv_cache[list][scan8[0] - 8 - 1]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
172 } |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
173 ref[list] = FFMIN3((unsigned)left_ref, (unsigned)top_ref, (unsigned)refc); |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
174 if(ref[list] >= 0){ |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
175 //this is just pred_motion() but with the cases removed that cannot happen for direct blocks |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
176 const int16_t * const A= h->mv_cache[list][ scan8[0] - 1 ]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
177 const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ]; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
178 |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
179 int match_count= (left_ref==ref[list]) + (top_ref==ref[list]) + (refc==ref[list]); |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
180 if(match_count > 1){ //most common |
11173
0010335497ad
10l use pack16to32(), should fix big endian h264 failures.
michael
parents:
11164
diff
changeset
|
181 mv[list]= pack16to32(mid_pred(A[0], B[0], C[0]), |
0010335497ad
10l use pack16to32(), should fix big endian h264 failures.
michael
parents:
11164
diff
changeset
|
182 mid_pred(A[1], B[1], C[1]) ); |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
183 }else { |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
184 assert(match_count==1); |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
185 if(left_ref==ref[list]){ |
11203 | 186 mv[list]= AV_RN32A(A); |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
187 }else if(top_ref==ref[list]){ |
11203 | 188 mv[list]= AV_RN32A(B); |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
189 }else{ |
11203 | 190 mv[list]= AV_RN32A(C); |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
191 } |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
192 } |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
193 }else{ |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
194 int mask= ~(MB_TYPE_L0 << (2*list)); |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
195 mv[list] = 0; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
196 ref[list] = -1; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
197 if(!is_b8x8) |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
198 *mb_type &= mask; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
199 sub_mb_type &= mask; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
200 } |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
201 } |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
202 if(ref[0] < 0 && ref[1] < 0){ |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
203 ref[0] = ref[1] = 0; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
204 if(!is_b8x8) |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
205 *mb_type |= MB_TYPE_L0L1; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
206 sub_mb_type |= MB_TYPE_L0L1; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
207 } |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
208 |
11143 | 209 if(!(is_b8x8|mv[0]|mv[1])){ |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
210 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
211 fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1); |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
212 fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
213 fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4); |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
214 *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; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
215 return; |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
216 } |
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
217 |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
218 if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL |
7900 | 219 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
|
220 mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; |
7901 | 221 b8_stride = 0; |
11093
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
222 }else{ |
788db3371366
Precalculate a few variables for direct mv prediction for interlaced MBs.
michael
parents:
11092
diff
changeset
|
223 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
|
224 } |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
225 goto single_col; |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
226 }else{ // AFL/AFR/FR/FL -> AFR/FR |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
227 if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
228 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
|
229 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
|
230 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
231 b8_stride = 2+4*s->mb_stride; |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
232 b4_stride *= 6; |
11090
eda7b4f6db51
Remove FIXMEs for cases that are disallowed by the spec.
michael
parents:
11088
diff
changeset
|
233 |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
234 sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
235 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
|
236 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
237 && !is_b8x8){ |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
238 *mb_type |= MB_TYPE_16x8 |MB_TYPE_DIRECT2; /* B_16x8 */ |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
239 }else{ |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
240 *mb_type |= MB_TYPE_8x8; |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
241 } |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
242 }else{ // AFR/FR -> AFR/FR |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
243 single_col: |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
244 mb_type_col[0] = |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
245 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; |
11106
f85c5cb2c402
Reorder and factorize mb_type ifs, 1 cpu cycle faster and simpler.
michael
parents:
11105
diff
changeset
|
246 |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
247 sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ |
11106
f85c5cb2c402
Reorder and factorize mb_type ifs, 1 cpu cycle faster and simpler.
michael
parents:
11105
diff
changeset
|
248 if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
249 *mb_type |= MB_TYPE_16x16|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
|
250 }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){ |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
251 *mb_type |= MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)); |
7494 | 252 }else{ |
11106
f85c5cb2c402
Reorder and factorize mb_type ifs, 1 cpu cycle faster and simpler.
michael
parents:
11105
diff
changeset
|
253 if(!h->sps.direct_8x8_inference_flag){ |
f85c5cb2c402
Reorder and factorize mb_type ifs, 1 cpu cycle faster and simpler.
michael
parents:
11105
diff
changeset
|
254 /* FIXME save sub mb types from previous frames (or derive from MVs) |
f85c5cb2c402
Reorder and factorize mb_type ifs, 1 cpu cycle faster and simpler.
michael
parents:
11105
diff
changeset
|
255 * so we know exactly what block size to use */ |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
256 sub_mb_type += (MB_TYPE_8x8-MB_TYPE_16x16); /* B_SUB_4x4 */ |
11106
f85c5cb2c402
Reorder and factorize mb_type ifs, 1 cpu cycle faster and simpler.
michael
parents:
11105
diff
changeset
|
257 } |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
258 *mb_type |= MB_TYPE_8x8; |
7494 | 259 } |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
260 } |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
261 } |
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
262 |
7497 | 263 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; |
264 l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; | |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
265 l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy]; |
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
266 l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy]; |
7496 | 267 if(!b8_stride){ |
268 if(s->mb_y&1){ | |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
269 l1ref0 += 2; |
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
270 l1ref1 += 2; |
7496 | 271 l1mv0 += 2*b4_stride; |
272 l1mv1 += 2*b4_stride; | |
273 } | |
7493
e5b93d01b472
Factorize some code between temporal and spatial direct mode.
michael
parents:
7488
diff
changeset
|
274 } |
2967 | 275 |
2396 | 276 |
11140
9004c61e3aa0
Restructure spatial direct MV generation so that the zero predictior shortcut
michael
parents:
11139
diff
changeset
|
277 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ |
11105
77c5116751b7
Set partitioning to 16x16 for spatial direct MBs with mixed interlacing.
michael
parents:
11104
diff
changeset
|
278 int n=0; |
6309 | 279 for(i8=0; i8<4; i8++){ |
280 int x8 = i8&1; | |
281 int y8 = i8>>1; | |
282 int xy8 = x8+y8*b8_stride; | |
283 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
|
284 int a,b; |
6309 | 285 |
286 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) | |
287 continue; | |
288 h->sub_mb_type[i8] = sub_mb_type; | |
289 | |
290 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1); | |
291 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
|
292 if(!IS_INTRA(mb_type_col[y8]) && !h->ref_list[1][0].long_ref |
6309 | 293 && ( (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFABS(l1mv0[xy4][1]) <= 1) |
294 || (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
|
295 a=b=0; |
6309 | 296 if(ref[0] > 0) |
11136
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
297 a= mv[0]; |
6309 | 298 if(ref[1] > 0) |
11136
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
299 b= mv[1]; |
11105
77c5116751b7
Set partitioning to 16x16 for spatial direct MBs with mixed interlacing.
michael
parents:
11104
diff
changeset
|
300 n++; |
6309 | 301 }else{ |
11136
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
302 a= mv[0]; |
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
303 b= mv[1]; |
6309 | 304 } |
305 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4); | |
306 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4); | |
307 } | |
11105
77c5116751b7
Set partitioning to 16x16 for spatial direct MBs with mixed interlacing.
michael
parents:
11104
diff
changeset
|
308 if(!is_b8x8 && !(n&3)) |
77c5116751b7
Set partitioning to 16x16 for spatial direct MBs with mixed interlacing.
michael
parents:
11104
diff
changeset
|
309 *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; |
6309 | 310 }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
|
311 int a,b; |
4540 | 312 |
3001
b52d8ee430f6
fix some potential arithmetic overflows in pred_direct_motion() and
lorenm
parents:
2979
diff
changeset
|
313 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
|
314 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
|
315 if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref |
4001 | 316 && ( (l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && FFABS(l1mv0[0][1]) <= 1) |
317 || (l1ref0[0] < 0 && l1ref1[0] == 0 && FFABS(l1mv1[0][0]) <= 1 && FFABS(l1mv1[0][1]) <= 1 | |
11097 | 318 && h->x264_build>33U))){ |
11095
2aeb7a1d1c7f
Zero a/b only in the branch where they need to be zeroed.
michael
parents:
11094
diff
changeset
|
319 a=b=0; |
2396 | 320 if(ref[0] > 0) |
11136
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
321 a= mv[0]; |
2396 | 322 if(ref[1] > 0) |
11136
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
323 b= mv[1]; |
2396 | 324 }else{ |
11136
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
325 a= mv[0]; |
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
326 b= mv[1]; |
4540 | 327 } |
328 fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4); | |
329 fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4); | |
2396 | 330 }else{ |
11104
bb877c9cb102
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
michael
parents:
11103
diff
changeset
|
331 int n=0; |
2396 | 332 for(i8=0; i8<4; i8++){ |
333 const int x8 = i8&1; | |
334 const int y8 = i8>>1; | |
2967 | 335 |
2396 | 336 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) |
337 continue; | |
338 h->sub_mb_type[i8] = sub_mb_type; | |
2967 | 339 |
11136
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
340 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, mv[0], 4); |
a0c52e951a29
Pack MVs together from the begin for spatial direct, this simplifies the code
michael
parents:
11106
diff
changeset
|
341 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, mv[1], 4); |
3001
b52d8ee430f6
fix some potential arithmetic overflows in pred_direct_motion() and
lorenm
parents:
2979
diff
changeset
|
342 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
|
343 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1); |
2967 | 344 |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
345 assert(b8_stride==2); |
2396 | 346 /* col_zero_flag */ |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
347 if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref && ( l1ref0[i8] == 0 |
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
348 || (l1ref0[i8] < 0 && l1ref1[i8] == 0 |
11097 | 349 && h->x264_build>33U))){ |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
350 const int16_t (*l1mv)[2]= l1ref0[i8] == 0 ? l1mv0 : l1mv1; |
3002 | 351 if(IS_SUB_8X8(sub_mb_type)){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
352 const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; |
4001 | 353 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ |
3002 | 354 if(ref[0] == 0) |
355 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); | |
356 if(ref[1] == 0) | |
357 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
|
358 n+=4; |
3002 | 359 } |
11103 | 360 }else{ |
361 int m=0; | |
2396 | 362 for(i4=0; i4<4; i4++){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
363 const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride]; |
4001 | 364 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ |
2396 | 365 if(ref[0] == 0) |
11203 | 366 AV_ZERO32(h->mv_cache[0][scan8[i8*4+i4]]); |
2396 | 367 if(ref[1] == 0) |
11203 | 368 AV_ZERO32(h->mv_cache[1][scan8[i8*4+i4]]); |
11103 | 369 m++; |
2396 | 370 } |
371 } | |
11103 | 372 if(!(m&3)) |
373 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
|
374 n+=m; |
11103 | 375 } |
2396 | 376 } |
377 } | |
11104
bb877c9cb102
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
michael
parents:
11103
diff
changeset
|
378 if(!is_b8x8 && !(n&15)) |
bb877c9cb102
Detect spatial direct MBs partitioned smaller than 16x16 that can be partitioned
michael
parents:
11103
diff
changeset
|
379 *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 | 380 } |
11139 | 381 } |
382 | |
383 static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ | |
384 MpegEncContext * const s = &h->s; | |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
385 int b8_stride = 2; |
11139 | 386 int b4_stride = h->b_stride; |
387 int mb_xy = h->mb_xy; | |
388 int mb_type_col[2]; | |
389 const int16_t (*l1mv0)[2], (*l1mv1)[2]; | |
390 const int8_t *l1ref0, *l1ref1; | |
391 const int is_b8x8 = IS_8X8(*mb_type); | |
392 unsigned int sub_mb_type; | |
393 int i8, i4; | |
394 | |
395 assert(h->ref_list[1][0].reference&3); | |
396 | |
397 if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL | |
398 if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL | |
399 mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; | |
400 b8_stride = 0; | |
401 }else{ | |
402 mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity | |
403 } | |
404 goto single_col; | |
405 }else{ // AFL/AFR/FR/FL -> AFR/FR | |
406 if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR | |
407 mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride; | |
408 mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; | |
409 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; | |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
410 b8_stride = 2+4*s->mb_stride; |
11139 | 411 b4_stride *= 6; |
412 | |
413 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ | |
414 | |
415 if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) | |
416 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) | |
417 && !is_b8x8){ | |
418 *mb_type |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_16x8 */ | |
419 }else{ | |
420 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | |
421 } | |
422 }else{ // AFR/FR -> AFR/FR | |
423 single_col: | |
424 mb_type_col[0] = | |
425 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; | |
426 | |
427 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ | |
428 if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ | |
429 *mb_type |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */ | |
430 }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){ | |
431 *mb_type |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)); | |
432 }else{ | |
433 if(!h->sps.direct_8x8_inference_flag){ | |
434 /* FIXME save sub mb types from previous frames (or derive from MVs) | |
435 * so we know exactly what block size to use */ | |
436 sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */ | |
437 } | |
438 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | |
439 } | |
440 } | |
441 } | |
442 | |
443 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; | |
444 l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; | |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
445 l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy]; |
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
446 l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy]; |
11139 | 447 if(!b8_stride){ |
448 if(s->mb_y&1){ | |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
449 l1ref0 += 2; |
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
450 l1ref1 += 2; |
11139 | 451 l1mv0 += 2*b4_stride; |
452 l1mv1 += 2*b4_stride; | |
453 } | |
454 } | |
455 | |
456 { | |
3316 | 457 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; |
458 const int *dist_scale_factor = h->dist_scale_factor; | |
11101 | 459 int ref_offset; |
3316 | 460 |
7494 | 461 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ |
7898
a33287a39a55
Make MBAFF temporal direct mode closer to the spec.
michael
parents:
7897
diff
changeset
|
462 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
|
463 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
|
464 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
|
465 } |
11101 | 466 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
|
467 |
7494 | 468 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ |
7495 | 469 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
|
470 assert(h->sps.direct_8x8_inference_flag); |
7494 | 471 |
472 for(i8=0; i8<4; i8++){ | |
473 const int x8 = i8&1; | |
474 const int y8 = i8>>1; | |
475 int ref0, scale; | |
476 const int16_t (*l1mv)[2]= l1mv0; | |
477 | |
478 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) | |
479 continue; | |
480 h->sub_mb_type[i8] = sub_mb_type; | |
481 | |
482 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); | |
483 if(IS_INTRA(mb_type_col[y8])){ | |
484 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1); | |
485 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); | |
486 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); | |
487 continue; | |
3316 | 488 } |
489 | |
7494 | 490 ref0 = l1ref0[x8 + y8*b8_stride]; |
491 if(ref0 >= 0) | |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
492 ref0 = map_col_to_list0[0][ref0 + ref_offset]; |
7494 | 493 else{ |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
494 ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; |
7494 | 495 l1mv= l1mv1; |
3316 | 496 } |
7494 | 497 scale = dist_scale_factor[ref0]; |
498 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); | |
499 | |
500 { | |
501 const int16_t *mv_col = l1mv[x8*3 + y8*b4_stride]; | |
502 int my_col = (mv_col[1]<<y_shift)/2; | |
503 int mx = (scale * mv_col[0] + 128) >> 8; | |
504 int my = (scale * my_col + 128) >> 8; | |
505 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4); | |
506 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-my_col), 4); | |
507 } | |
508 } | |
509 return; | |
510 } | |
3316 | 511 |
512 /* one-to-one mv scaling */ | |
513 | |
2396 | 514 if(IS_16X16(*mb_type)){ |
4541 | 515 int ref, mv0, mv1; |
516 | |
2396 | 517 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
|
518 if(IS_INTRA(mb_type_col[0])){ |
4541 | 519 ref=mv0=mv1=0; |
2396 | 520 }else{ |
7906
5be944626072
Another try to fix temporal direct mode references.
michael
parents:
7902
diff
changeset
|
521 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
|
522 : map_col_to_list0[1][l1ref1[0] + ref_offset]; |
3316 | 523 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
|
524 const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; |
2396 | 525 int mv_l0[2]; |
3316 | 526 mv_l0[0] = (scale * mv_col[0] + 128) >> 8; |
527 mv_l0[1] = (scale * mv_col[1] + 128) >> 8; | |
4541 | 528 ref= ref0; |
529 mv0= pack16to32(mv_l0[0],mv_l0[1]); | |
530 mv1= pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]); | |
531 } | |
532 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); | |
533 fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4); | |
534 fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4); | |
2396 | 535 }else{ |
536 for(i8=0; i8<4; i8++){ | |
537 const int x8 = i8&1; | |
538 const int y8 = i8>>1; | |
3316 | 539 int ref0, scale; |
2834 | 540 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
|
541 |
2396 | 542 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) |
543 continue; | |
544 h->sub_mb_type[i8] = sub_mb_type; | |
3316 | 545 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
|
546 if(IS_INTRA(mb_type_col[0])){ |
2396 | 547 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1); |
548 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); | |
549 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); | |
550 continue; | |
551 } | |
2967 | 552 |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
553 assert(b8_stride == 2); |
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
554 ref0 = l1ref0[i8]; |
2537
14fef0f3f532
H.264: decode arbitrary frame orders and allow B-frames as references.
lorenm
parents:
2536
diff
changeset
|
555 if(ref0 >= 0) |
11083
a270b4c67089
ref_offset must be added after checking references validity.
michael
parents:
11078
diff
changeset
|
556 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
|
557 else{ |
11292
411ab09ada91
Get rid of mb2b8_xy and b8_stride, change arrays organized based on b8_stride to
michael
parents:
11203
diff
changeset
|
558 ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset]; |
2809
75400dfbe117
fixing colocated mv if colocated block is L1 predicted for the temporal direct case
michael
parents:
2808
diff
changeset
|
559 l1mv= l1mv1; |
75400dfbe117
fixing colocated mv if colocated block is L1 predicted for the temporal direct case
michael
parents:
2808
diff
changeset
|
560 } |
3316 | 561 scale = dist_scale_factor[ref0]; |
2967 | 562 |
2396 | 563 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); |
3002 | 564 if(IS_SUB_8X8(sub_mb_type)){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
565 const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; |
3316 | 566 int mx = (scale * mv_col[0] + 128) >> 8; |
567 int my = (scale * mv_col[1] + 128) >> 8; | |
3002 | 568 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4); |
569 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-mv_col[1]), 4); | |
570 }else | |
2396 | 571 for(i4=0; i4<4; i4++){ |
7498
e7006afcb1c6
Use local variabes for *stride, where local variables exist.
michael
parents:
7497
diff
changeset
|
572 const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride]; |
2396 | 573 int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; |
3316 | 574 mv_l0[0] = (scale * mv_col[0] + 128) >> 8; |
575 mv_l0[1] = (scale * mv_col[1] + 128) >> 8; | |
11203 | 576 AV_WN32A(h->mv_cache[1][scan8[i8*4+i4]], |
577 pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1])); | |
2396 | 578 } |
579 } | |
580 } | |
581 } | |
582 } | |
11139 | 583 |
584 void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){ | |
585 if(h->direct_spatial_mv_pred){ | |
586 pred_spatial_direct_motion(h, mb_type); | |
587 }else{ | |
588 pred_temp_direct_motion(h, mb_type); | |
589 } | |
590 } |