summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libmpeg3/video/motion.c
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video/motion.c') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/motion.c230
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
11static 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/*
32int *dmvector, * differential motion vector *
33int mvx, int mvy * decoded mv components (always in field format) *
34*/
35void 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
78static 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
115static 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
132void 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
166int 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}