Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video/motion.c') (more/less context) (show whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libmpeg3/video/motion.c | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libmpeg3/video/motion.c b/core/multimedia/opieplayer/libmpeg3/video/motion.c new file mode 100644 index 0000000..4d2f681 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/motion.c | |||
@@ -0,0 +1,230 @@ | |||
1 | #include "mpeg3video.h" | ||
2 | #include "../libmpeg3.h" | ||
3 | #include "../mpeg3protos.h" | ||
4 | #include "vlc.h" | ||
5 | |||
6 | #include <stdio.h> | ||
7 | |||
8 | |||
9 | /* calculate motion vector component */ | ||
10 | |||
11 | static inline void mpeg3video_calc_mv(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector) | ||
12 | { | ||
13 | int lim = 16 << r_size; | ||
14 | int vec = full_pel_vector ? (*pred >> 1) : (*pred); | ||
15 | |||
16 | if(motion_code > 0) | ||
17 | { | ||
18 | vec += ((motion_code - 1) << r_size) + motion_r + 1; | ||
19 | if(vec >= lim) vec -= lim + lim; | ||
20 | } | ||
21 | else | ||
22 | if(motion_code < 0) | ||
23 | { | ||
24 | vec -= ((-motion_code - 1) << r_size) + motion_r + 1; | ||
25 | if(vec < -lim) vec += lim + lim; | ||
26 | } | ||
27 | *pred = full_pel_vector ? (vec << 1) : vec; | ||
28 | } | ||
29 | |||
30 | |||
31 | /* | ||
32 | int *dmvector, * differential motion vector * | ||
33 | int mvx, int mvy * decoded mv components (always in field format) * | ||
34 | */ | ||
35 | void mpeg3video_calc_dmv(mpeg3video_t *video, | ||
36 | int DMV[][2], | ||
37 | int *dmvector, | ||
38 | int mvx, | ||
39 | int mvy) | ||
40 | { | ||
41 | if(video->pict_struct == FRAME_PICTURE) | ||
42 | { | ||
43 | if(video->topfirst) | ||
44 | { | ||
45 | /* vector for prediction of top field from bottom field */ | ||
46 | DMV[0][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0]; | ||
47 | DMV[0][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] - 1; | ||
48 | |||
49 | /* vector for prediction of bottom field from top field */ | ||
50 | DMV[1][0] = ((3 * mvx + (mvx > 0)) >> 1) + dmvector[0]; | ||
51 | DMV[1][1] = ((3 * mvy + (mvy > 0)) >> 1) + dmvector[1] + 1; | ||
52 | } | ||
53 | else | ||
54 | { | ||
55 | /* vector for prediction of top field from bottom field */ | ||
56 | DMV[0][0] = ((3 * mvx + (mvx>0)) >> 1) + dmvector[0]; | ||
57 | DMV[0][1] = ((3 * mvy + (mvy>0)) >> 1) + dmvector[1] - 1; | ||
58 | |||
59 | /* vector for prediction of bottom field from top field */ | ||
60 | DMV[1][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0]; | ||
61 | DMV[1][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] + 1; | ||
62 | } | ||
63 | } | ||
64 | else | ||
65 | { | ||
66 | /* vector for prediction from field of opposite 'parity' */ | ||
67 | DMV[0][0] = ((mvx + (mvx > 0)) >> 1) + dmvector[0]; | ||
68 | DMV[0][1] = ((mvy + (mvy > 0)) >> 1) + dmvector[1]; | ||
69 | |||
70 | /* correct for vertical field shift */ | ||
71 | if(video->pict_struct == TOP_FIELD) | ||
72 | DMV[0][1]--; | ||
73 | else | ||
74 | DMV[0][1]++; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static inline int mpeg3video_get_mv(mpeg3_slice_t *slice) | ||
79 | { | ||
80 | int code; | ||
81 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
82 | |||
83 | if(mpeg3slice_getbit(slice_buffer)) | ||
84 | { | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | if((code = mpeg3slice_showbits9(slice_buffer)) >= 64) | ||
89 | { | ||
90 | code >>= 6; | ||
91 | mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab0[code].len); | ||
92 | return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab0[code].val : mpeg3_MVtab0[code].val; | ||
93 | } | ||
94 | |||
95 | if(code >= 24) | ||
96 | { | ||
97 | code >>= 3; | ||
98 | mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab1[code].len); | ||
99 | return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab1[code].val : mpeg3_MVtab1[code].val; | ||
100 | } | ||
101 | |||
102 | if((code -= 12) < 0) | ||
103 | { | ||
104 | /* fprintf(stdout,"mpeg3video_get_mv: invalid motion_vector code\n"); */ | ||
105 | slice->fault = 1; | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab2[code].len); | ||
110 | return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab2[code].val : mpeg3_MVtab2[code].val; | ||
111 | } | ||
112 | |||
113 | /* get differential motion vector (for dual prime prediction) */ | ||
114 | |||
115 | static inline int mpeg3video_get_dmv(mpeg3_slice_t *slice) | ||
116 | { | ||
117 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
118 | if(mpeg3slice_getbit(slice_buffer)) | ||
119 | { | ||
120 | return mpeg3slice_getbit(slice_buffer) ? -1 : 1; | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | return 0; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | |||
129 | |||
130 | /* get and decode motion vector and differential motion vector */ | ||
131 | |||
132 | void mpeg3video_motion_vector(mpeg3_slice_t *slice, | ||
133 | mpeg3video_t *video, | ||
134 | int *PMV, | ||
135 | int *dmvector, | ||
136 | int h_r_size, | ||
137 | int v_r_size, | ||
138 | int dmv, | ||
139 | int mvscale, | ||
140 | int full_pel_vector) | ||
141 | { | ||
142 | int motion_r; | ||
143 | int motion_code = mpeg3video_get_mv(slice); | ||
144 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
145 | |||
146 | if(slice->fault) return; | ||
147 | motion_r = (h_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, h_r_size) : 0; | ||
148 | |||
149 | mpeg3video_calc_mv(&PMV[0], h_r_size, motion_code, motion_r, full_pel_vector); | ||
150 | |||
151 | if(dmv) dmvector[0] = mpeg3video_get_dmv(slice); | ||
152 | |||
153 | motion_code = mpeg3video_get_mv(slice); | ||
154 | if(slice->fault) return; | ||
155 | motion_r = (v_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, v_r_size) : 0; | ||
156 | |||
157 | /* DIV 2 */ | ||
158 | if(mvscale) PMV[1] >>= 1; | ||
159 | |||
160 | mpeg3video_calc_mv(&PMV[1], v_r_size, motion_code, motion_r, full_pel_vector); | ||
161 | |||
162 | if(mvscale) PMV[1] <<= 1; | ||
163 | if(dmv) dmvector[1] = mpeg3video_get_dmv(slice); | ||
164 | } | ||
165 | |||
166 | int mpeg3video_motion_vectors(mpeg3_slice_t *slice, | ||
167 | mpeg3video_t *video, | ||
168 | int PMV[2][2][2], | ||
169 | int dmvector[2], | ||
170 | int mv_field_sel[2][2], | ||
171 | int s, | ||
172 | int mv_count, | ||
173 | int mv_format, | ||
174 | int h_r_size, | ||
175 | int v_r_size, | ||
176 | int dmv, | ||
177 | int mvscale) | ||
178 | { | ||
179 | int result = 0; | ||
180 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
181 | if(mv_count == 1) | ||
182 | { | ||
183 | if(mv_format == MV_FIELD && !dmv) | ||
184 | { | ||
185 | mv_field_sel[1][s] = mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer); | ||
186 | } | ||
187 | |||
188 | mpeg3video_motion_vector(slice, | ||
189 | video, | ||
190 | PMV[0][s], | ||
191 | dmvector, | ||
192 | h_r_size, | ||
193 | v_r_size, | ||
194 | dmv, | ||
195 | mvscale, | ||
196 | 0); | ||
197 | if(slice->fault) return 1; | ||
198 | |||
199 | /* update other motion vector predictors */ | ||
200 | PMV[1][s][0] = PMV[0][s][0]; | ||
201 | PMV[1][s][1] = PMV[0][s][1]; | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer); | ||
206 | mpeg3video_motion_vector(slice, | ||
207 | video, | ||
208 | PMV[0][s], | ||
209 | dmvector, | ||
210 | h_r_size, | ||
211 | v_r_size, | ||
212 | dmv, | ||
213 | mvscale, | ||
214 | 0); | ||
215 | if(slice->fault) return 1; | ||
216 | |||
217 | mv_field_sel[1][s] = mpeg3slice_getbit(slice_buffer); | ||
218 | mpeg3video_motion_vector(slice, | ||
219 | video, | ||
220 | PMV[1][s], | ||
221 | dmvector, | ||
222 | h_r_size, | ||
223 | v_r_size, | ||
224 | dmv, | ||
225 | mvscale, | ||
226 | 0); | ||
227 | if(slice->fault) return 1; | ||
228 | } | ||
229 | return 0; | ||
230 | } | ||