annotate h264_direct.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 7dd2a45249a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1168
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
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
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
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
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
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
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
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
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
15 * Lesser General Public License for more details.
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
16 *
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
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
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
20 */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2962
diff changeset
21
1168
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
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
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
25 * @author Michael Niedermayer <michaelni@gmx.at>
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
26 */
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
27
9012
15a3df8c01fd More approved hunks for VAAPI & our new and cleaner hwaccel API.
michael
parents: 9004
diff changeset
28 #include "internal.h"
1168
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
29 #include "dsputil.h"
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
30 #include "avcodec.h"
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
31 #include "mpegvideo.h"
4975
9a6a0818e93f split h264.c to move parser in its own file
aurel
parents: 4931
diff changeset
32 #include "h264.h"
6020
c531defb03ee Make fill_rectangle() available for other decoders
kostya
parents: 6019
diff changeset
33 #include "rectangle.h"
1168
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
34
3284
a224d9752912 don't force asserts in release builds. 2% faster h264.
lorenm
parents: 3219
diff changeset
35 //#undef NDEBUG
1168
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
36 #include <assert.h>
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
37
5af9aeadbdc3 H264 decoder & demuxer
michaelni
parents:
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
65 }
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
d4222f5b6dea Fix colocated map.
michael
parents: 11085
diff changeset
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
d4222f5b6dea Fix colocated map.
michael
parents: 11085
diff changeset
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
d4222f5b6dea Fix colocated map.
michael
parents: 11085
diff changeset
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
7d897cb94a31 Remove unused variable.
diego
parents: 7926
diff changeset
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
8eb69709a934 A few empty lines for readability.
michael
parents: 7906
diff changeset
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
8eb69709a934 A few empty lines for readability.
michael
parents: 7906
diff changeset
114
7482
ecf3c774f5e1 Fill ref_count/ref_poc for both fields of frames.
michael
parents: 7481
diff changeset
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
ecf3c774f5e1 Fill ref_count/ref_poc for both fields of frames.
michael
parents: 7481
diff changeset
118 }
7907
8eb69709a934 A few empty lines for readability.
michael
parents: 7906
diff changeset
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
8eb69709a934 A few empty lines for readability.
michael
parents: 7906
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
142
11139
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
143 static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
151 const int is_b8x8 = IS_8X8(*mb_type);
11174
421c6cd2fb9f 10l ;; gcc 2.95 compilation fix by mike
michael
parents: 11173
diff changeset
152 unsigned int sub_mb_type= MB_TYPE_L0L1;
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
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
10c06a9bd3d9 H264: use alias-safe macros
mru
parents: 11174
diff changeset
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
10c06a9bd3d9 H264: use alias-safe macros
mru
parents: 11174
diff changeset
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
10c06a9bd3d9 H264: use alias-safe macros
mru
parents: 11174
diff changeset
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
8bfe0dae50b2 Simplify if()
michael
parents: 11142
diff changeset
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
37f62a3dc645 Correct comment in the direct mode code.
michael
parents: 7899
diff changeset
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
michael
parents: 7900
diff changeset
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
michael
parents: 7493
diff changeset
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
michael
parents: 7493
diff changeset
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
michael
parents: 7496
diff changeset
263 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
michael
parents: 7496
diff changeset
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
f96c14041e48 Simplify l1mv/l1ref calculation.
michael
parents: 7495
diff changeset
267 if(!b8_stride){
f96c14041e48 Simplify l1mv/l1ref calculation.
michael
parents: 7495
diff changeset
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
f96c14041e48 Simplify l1mv/l1ref calculation.
michael
parents: 7495
diff changeset
271 l1mv0 += 2*b4_stride;
f96c14041e48 Simplify l1mv/l1ref calculation.
michael
parents: 7495
diff changeset
272 l1mv1 += 2*b4_stride;
f96c14041e48 Simplify l1mv/l1ref calculation.
michael
parents: 7495
diff changeset
273 }
7493
e5b93d01b472 Factorize some code between temporal and spatial direct mode.
michael
parents: 7488
diff changeset
274 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2962
diff changeset
275
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
279 for(i8=0; i8<4; i8++){
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
280 int x8 = i8&1;
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
281 int y8 = i8>>1;
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
282 int xy8 = x8+y8*b8_stride;
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
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
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
285
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
286 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
287 continue;
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
288 h->sub_mb_type[i8] = sub_mb_type;
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
289
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
290 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1);
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
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
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
293 && ( (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFABS(l1mv0[xy4][1]) <= 1)
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
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
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
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
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
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
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
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
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
304 }
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
305 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4);
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
306 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4);
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
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
af4b8e1f9b6c mbaff spatial direct
lorenm
parents: 6216
diff changeset
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
d81e41071424 factorize fill_rectangle() calls
michael
parents: 4534
diff changeset
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
34fdffe98bd0 Rename ABS macro to FFABS.
diego
parents: 4000
diff changeset
316 && ( (l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && FFABS(l1mv0[0][1]) <= 1)
34fdffe98bd0 Rename ABS macro to FFABS.
diego
parents: 4000
diff changeset
317 || (l1ref0[0] < 0 && l1ref1[0] == 0 && FFABS(l1mv1[0][0]) <= 1 && FFABS(l1mv1[0][1]) <= 1
11097
7e5d7873fad9 Set x264_build so that checks are simpler.
michael
parents: 11095
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
d81e41071424 factorize fill_rectangle() calls
michael
parents: 4534
diff changeset
327 }
d81e41071424 factorize fill_rectangle() calls
michael
parents: 4534
diff changeset
328 fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4);
d81e41071424 factorize fill_rectangle() calls
michael
parents: 4534
diff changeset
329 fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4);
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
332 for(i8=0; i8<4; i8++){
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
333 const int x8 = i8&1;
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
334 const int y8 = i8>>1;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2962
diff changeset
335
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
336 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
337 continue;
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
338 h->sub_mb_type[i8] = sub_mb_type;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2962
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2962
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e5d7873fad9 Set x264_build so that checks are simpler.
michael
parents: 11095
diff changeset
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
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
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
34fdffe98bd0 Rename ABS macro to FFABS.
diego
parents: 4000
diff changeset
353 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){
3002
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
354 if(ref[0] == 0)
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
355 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
356 if(ref[1] == 0)
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
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
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
359 }
11103
3bc0125e19fe Detect equal 4x4 blocks in spatial direct MBs.
michael
parents: 11101
diff changeset
360 }else{
3bc0125e19fe Detect equal 4x4 blocks in spatial direct MBs.
michael
parents: 11101
diff changeset
361 int m=0;
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
34fdffe98bd0 Rename ABS macro to FFABS.
diego
parents: 4000
diff changeset
364 if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
365 if(ref[0] == 0)
11203
10c06a9bd3d9 H264: use alias-safe macros
mru
parents: 11174
diff changeset
366 AV_ZERO32(h->mv_cache[0][scan8[i8*4+i4]]);
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
367 if(ref[1] == 0)
11203
10c06a9bd3d9 H264: use alias-safe macros
mru
parents: 11174
diff changeset
368 AV_ZERO32(h->mv_cache[1][scan8[i8*4+i4]]);
11103
3bc0125e19fe Detect equal 4x4 blocks in spatial direct MBs.
michael
parents: 11101
diff changeset
369 m++;
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
370 }
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
371 }
11103
3bc0125e19fe Detect equal 4x4 blocks in spatial direct MBs.
michael
parents: 11101
diff changeset
372 if(!(m&3))
3bc0125e19fe Detect equal 4x4 blocks in spatial direct MBs.
michael
parents: 11101
diff changeset
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
3bc0125e19fe Detect equal 4x4 blocks in spatial direct MBs.
michael
parents: 11101
diff changeset
375 }
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
376 }
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
380 }
11139
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
381 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
382
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
383 static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
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
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
386 int b4_stride = h->b_stride;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
387 int mb_xy = h->mb_xy;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
388 int mb_type_col[2];
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
389 const int16_t (*l1mv0)[2], (*l1mv1)[2];
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
390 const int8_t *l1ref0, *l1ref1;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
391 const int is_b8x8 = IS_8X8(*mb_type);
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
392 unsigned int sub_mb_type;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
393 int i8, i4;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
394
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
395 assert(h->ref_list[1][0].reference&3);
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
396
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
397 if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
398 if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
399 mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
400 b8_stride = 0;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
401 }else{
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
402 mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
403 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
404 goto single_col;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
405 }else{ // AFL/AFR/FR/FL -> AFR/FR
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
406 if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
407 mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
408 mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
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
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
411 b4_stride *= 6;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
412
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
413 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
414
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
415 if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
416 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA)
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
417 && !is_b8x8){
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
418 *mb_type |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_16x8 */
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
419 }else{
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
420 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
421 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
422 }else{ // AFR/FR -> AFR/FR
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
423 single_col:
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
424 mb_type_col[0] =
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
425 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
426
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
427 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
428 if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
429 *mb_type |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
430 }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
431 *mb_type |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16));
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
432 }else{
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
433 if(!h->sps.direct_8x8_inference_flag){
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
434 /* FIXME save sub mb types from previous frames (or derive from MVs)
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
435 * so we know exactly what block size to use */
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
436 sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
437 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
438 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
439 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
440 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
441 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
442
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
443 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
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
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
447 if(!b8_stride){
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
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
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
451 l1mv0 += 2*b4_stride;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
452 l1mv1 += 2*b4_stride;
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
453 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
454 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
455
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
456 {
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
457 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]};
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
458 const int *dist_scale_factor = h->dist_scale_factor;
11101
a82b9c88682f Branchless calculation of ref_offset.
michael
parents: 11100
diff changeset
459 int ref_offset;
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
460
7494
michael
parents: 7493
diff changeset
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
a82b9c88682f Branchless calculation of ref_offset.
michael
parents: 11100
diff changeset
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
michael
parents: 7493
diff changeset
468 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){
7495
2090d67bbf16 simplify y_shift/ref_shift code
michael
parents: 7494
diff changeset
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
michael
parents: 7493
diff changeset
471
michael
parents: 7493
diff changeset
472 for(i8=0; i8<4; i8++){
michael
parents: 7493
diff changeset
473 const int x8 = i8&1;
michael
parents: 7493
diff changeset
474 const int y8 = i8>>1;
michael
parents: 7493
diff changeset
475 int ref0, scale;
michael
parents: 7493
diff changeset
476 const int16_t (*l1mv)[2]= l1mv0;
michael
parents: 7493
diff changeset
477
michael
parents: 7493
diff changeset
478 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
michael
parents: 7493
diff changeset
479 continue;
michael
parents: 7493
diff changeset
480 h->sub_mb_type[i8] = sub_mb_type;
michael
parents: 7493
diff changeset
481
michael
parents: 7493
diff changeset
482 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1);
michael
parents: 7493
diff changeset
483 if(IS_INTRA(mb_type_col[y8])){
michael
parents: 7493
diff changeset
484 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1);
michael
parents: 7493
diff changeset
485 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);
michael
parents: 7493
diff changeset
486 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);
michael
parents: 7493
diff changeset
487 continue;
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
488 }
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
489
7494
michael
parents: 7493
diff changeset
490 ref0 = l1ref0[x8 + y8*b8_stride];
michael
parents: 7493
diff changeset
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
michael
parents: 7493
diff changeset
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
michael
parents: 7493
diff changeset
495 l1mv= l1mv1;
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
496 }
7494
michael
parents: 7493
diff changeset
497 scale = dist_scale_factor[ref0];
michael
parents: 7493
diff changeset
498 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1);
michael
parents: 7493
diff changeset
499
michael
parents: 7493
diff changeset
500 {
michael
parents: 7493
diff changeset
501 const int16_t *mv_col = l1mv[x8*3 + y8*b4_stride];
michael
parents: 7493
diff changeset
502 int my_col = (mv_col[1]<<y_shift)/2;
michael
parents: 7493
diff changeset
503 int mx = (scale * mv_col[0] + 128) >> 8;
michael
parents: 7493
diff changeset
504 int my = (scale * my_col + 128) >> 8;
michael
parents: 7493
diff changeset
505 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4);
michael
parents: 7493
diff changeset
506 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-my_col), 4);
michael
parents: 7493
diff changeset
507 }
michael
parents: 7493
diff changeset
508 }
michael
parents: 7493
diff changeset
509 return;
michael
parents: 7493
diff changeset
510 }
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
511
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
512 /* one-to-one mv scaling */
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
513
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
514 if(IS_16X16(*mb_type)){
4541
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
515 int ref, mv0, mv1;
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
516
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
519 ref=mv0=mv1=0;
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
525 int mv_l0[2];
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
526 mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
527 mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
4541
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
528 ref= ref0;
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
529 mv0= pack16to32(mv_l0[0],mv_l0[1]);
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
530 mv1= pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]);
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
531 }
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
532 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
533 fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4);
1c8bc533da57 factorize more calls to fill_rectangle()
michael
parents: 4540
diff changeset
534 fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4);
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
535 }else{
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
536 for(i8=0; i8<4; i8++){
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
537 const int x8 = i8&1;
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
538 const int y8 = i8>>1;
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
539 int ref0, scale;
2834
fd5d7c732c6b kill a bunch of compiler warnings
mru
parents: 2815
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
542 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
543 continue;
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
544 h->sub_mb_type[i8] = sub_mb_type;
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
547 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1);
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
548 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
549 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
550 continue;
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
551 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2962
diff changeset
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
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
561 scale = dist_scale_factor[ref0];
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2962
diff changeset
562
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
563 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1);
3002
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
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
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
566 int mx = (scale * mv_col[0] + 128) >> 8;
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
567 int my = (scale * mv_col[1] + 128) >> 8;
3002
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
568 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4);
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
569 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-mv_col[1]), 4);
68d252a8ecd2 fix direct_8x8_inference_flag with 4x4 mvs.
lorenm
parents: 3001
diff changeset
570 }else
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
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
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
573 int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]];
3316
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
574 mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
7278f730af27 h264: MBAFF interlaced decoding
lorenm
parents: 3315
diff changeset
575 mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
11203
10c06a9bd3d9 H264: use alias-safe macros
mru
parents: 11174
diff changeset
576 AV_WN32A(h->mv_cache[1][scan8[i8*4+i4]],
10c06a9bd3d9 H264: use alias-safe macros
mru
parents: 11174
diff changeset
577 pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]));
2396
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
578 }
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
579 }
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
580 }
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
581 }
7e360068b653 implement B_DIRECT and B_SKIP macroblock types.
lorenm
parents: 2395
diff changeset
582 }
11139
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
583
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
584 void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
585 if(h->direct_spatial_mv_pred){
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
586 pred_spatial_direct_motion(h, mb_type);
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
587 }else{
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
588 pred_temp_direct_motion(h, mb_type);
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
589 }
d988e0a6f391 Split spatial and temporal direct MV generation.
michael
parents: 11137
diff changeset
590 }