author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/multimedia/opieplayer/libmpeg3/video/macroblocks.c | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video/macroblocks.c') (more/less context) (show whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libmpeg3/video/macroblocks.c | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c new file mode 100644 index 0000000..11e17c1 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c | |||
@@ -0,0 +1,338 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include "slice.h" | ||
5 | #include "vlc.h" | ||
6 | |||
7 | #include <stdio.h> | ||
8 | |||
9 | int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice) | ||
10 | { | ||
11 | int code, val = 0; | ||
12 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
13 | |||
14 | while((code = mpeg3slice_showbits(slice_buffer, 11)) < 24) | ||
15 | { | ||
16 | /* Is not macroblock_stuffing */ | ||
17 | if(code != 15) | ||
18 | { | ||
19 | /* Is macroblock_escape */ | ||
20 | if(code == 8) | ||
21 | { | ||
22 | val += 33; | ||
23 | } | ||
24 | else | ||
25 | { | ||
26 | /* fprintf(stderr, "mpeg3video_get_macroblock_address: invalid macroblock_address_increment code\n"); */ | ||
27 | slice->fault = 1; | ||
28 | return 1; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | mpeg3slice_flushbits(slice_buffer, 11); | ||
33 | } | ||
34 | |||
35 | if(code >= 1024) | ||
36 | { | ||
37 | mpeg3slice_flushbit(slice_buffer); | ||
38 | return val + 1; | ||
39 | } | ||
40 | |||
41 | if(code >= 128) | ||
42 | { | ||
43 | code >>= 6; | ||
44 | mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab1[code].len); | ||
45 | return val + mpeg3_MBAtab1[code].val; | ||
46 | } | ||
47 | |||
48 | code -= 24; | ||
49 | mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab2[code].len); | ||
50 | |||
51 | return val + mpeg3_MBAtab2[code].val; | ||
52 | } | ||
53 | |||
54 | /* macroblock_type for pictures with spatial scalability */ | ||
55 | |||
56 | static inline int mpeg3video_getsp_imb_type(mpeg3_slice_t *slice) | ||
57 | { | ||
58 | // ### This looks wrong. | ||
59 | // slice_buffer is used without being initialised and slice is not used | ||
60 | //mpeg3_slice_buffer_t *slice_buffer = slice_buffer; | ||
61 | // I think this would make more sense and might be what is intended | ||
62 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
63 | unsigned int code = mpeg3slice_showbits(slice_buffer, 4); | ||
64 | if(!code) | ||
65 | { | ||
66 | /* fprintf(stderr,"mpeg3video_getsp_imb_type: invalid macroblock_type code\n"); */ | ||
67 | slice->fault = 1; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | mpeg3slice_flushbits(slice_buffer, mpeg3_spIMBtab[code].len); | ||
72 | return mpeg3_spIMBtab[code].val; | ||
73 | } | ||
74 | |||
75 | static inline int mpeg3video_getsp_pmb_type(mpeg3_slice_t *slice) | ||
76 | { | ||
77 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
78 | int code = mpeg3slice_showbits(slice_buffer, 7); | ||
79 | if(code < 2) | ||
80 | { | ||
81 | /* fprintf(stderr,"mpeg3video_getsp_pmb_type: invalid macroblock_type code\n"); */ | ||
82 | slice->fault = 1; | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | if(code >= 16) | ||
87 | { | ||
88 | code >>= 3; | ||
89 | mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab0[code].len); | ||
90 | |||
91 | return mpeg3_spPMBtab0[code].val; | ||
92 | } | ||
93 | |||
94 | mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab1[code].len); | ||
95 | return mpeg3_spPMBtab1[code].val; | ||
96 | } | ||
97 | |||
98 | static inline int mpeg3video_getsp_bmb_type(mpeg3_slice_t *slice) | ||
99 | { | ||
100 | mpeg3_VLCtab_t *p; | ||
101 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
102 | int code = mpeg3slice_showbits9(slice_buffer); | ||
103 | |||
104 | if(code >= 64) | ||
105 | p = &mpeg3_spBMBtab0[(code >> 5) - 2]; | ||
106 | else | ||
107 | if(code >= 16) | ||
108 | p = &mpeg3_spBMBtab1[(code >> 2) - 4]; | ||
109 | else | ||
110 | if(code >= 8) | ||
111 | p = &mpeg3_spBMBtab2[code - 8]; | ||
112 | else | ||
113 | { | ||
114 | /* fprintf(stderr,"mpeg3video_getsp_bmb_type: invalid macroblock_type code\n"); */ | ||
115 | slice->fault = 1; | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | mpeg3slice_flushbits(slice_buffer, p->len); | ||
120 | return p->val; | ||
121 | } | ||
122 | |||
123 | static inline int mpeg3video_get_imb_type(mpeg3_slice_t *slice) | ||
124 | { | ||
125 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
126 | if(mpeg3slice_getbit(slice_buffer)) | ||
127 | { | ||
128 | return 1; | ||
129 | } | ||
130 | |||
131 | if(!mpeg3slice_getbit(slice_buffer)) | ||
132 | { | ||
133 | /* fprintf(stderr,"mpeg3video_get_imb_type: invalid macroblock_type code\n"); */ | ||
134 | slice->fault = 1; | ||
135 | } | ||
136 | |||
137 | return 17; | ||
138 | } | ||
139 | |||
140 | static inline int mpeg3video_get_pmb_type(mpeg3_slice_t *slice) | ||
141 | { | ||
142 | int code; | ||
143 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
144 | |||
145 | if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8) | ||
146 | { | ||
147 | code >>= 3; | ||
148 | mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab0[code].len); | ||
149 | return mpeg3_PMBtab0[code].val; | ||
150 | } | ||
151 | |||
152 | if(code == 0) | ||
153 | { | ||
154 | /* fprintf(stderr,"mpeg3video_get_pmb_type: invalid macroblock_type code\n"); */ | ||
155 | slice->fault = 1; | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab1[code].len); | ||
160 | return mpeg3_PMBtab1[code].val; | ||
161 | } | ||
162 | |||
163 | static inline int mpeg3video_get_bmb_type(mpeg3_slice_t *slice) | ||
164 | { | ||
165 | int code; | ||
166 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
167 | |||
168 | if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8) | ||
169 | { | ||
170 | code >>= 2; | ||
171 | mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab0[code].len); | ||
172 | return mpeg3_BMBtab0[code].val; | ||
173 | } | ||
174 | |||
175 | if(code == 0) | ||
176 | { | ||
177 | /* fprintf(stderr,"mpeg3video_get_bmb_type: invalid macroblock_type code\n"); */ | ||
178 | slice->fault = 1; | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab1[code].len); | ||
183 | |||
184 | return mpeg3_BMBtab1[code].val; | ||
185 | } | ||
186 | |||
187 | static inline int mpeg3video_get_dmb_type(mpeg3_slice_t *slice) | ||
188 | { | ||
189 | if(!mpeg3slice_getbit(slice->slice_buffer)) | ||
190 | { | ||
191 | /* fprintf(stderr,"mpeg3video_get_dmb_type: invalid macroblock_type code\n"); */ | ||
192 | slice->fault=1; | ||
193 | } | ||
194 | |||
195 | return 1; | ||
196 | } | ||
197 | |||
198 | |||
199 | static inline int mpeg3video_get_snrmb_type(mpeg3_slice_t *slice) | ||
200 | { | ||
201 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
202 | int code = mpeg3slice_showbits(slice_buffer, 3); | ||
203 | |||
204 | if(code == 0) | ||
205 | { | ||
206 | /* fprintf(stderr,"mpeg3video_get_snrmb_type: invalid macroblock_type code\n"); */ | ||
207 | slice->fault = 1; | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | mpeg3slice_flushbits(slice_buffer, mpeg3_SNRMBtab[code].len); | ||
212 | return mpeg3_SNRMBtab[code].val; | ||
213 | } | ||
214 | |||
215 | int mpeg3video_get_mb_type(mpeg3_slice_t *slice, mpeg3video_t *video) | ||
216 | { | ||
217 | if(video->scalable_mode == SC_SNR) | ||
218 | { | ||
219 | return mpeg3video_get_snrmb_type(slice); | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | switch(video->pict_type) | ||
224 | { | ||
225 | case I_TYPE: return video->pict_scal ? mpeg3video_getsp_imb_type(slice) : mpeg3video_get_imb_type(slice); | ||
226 | case P_TYPE: return video->pict_scal ? mpeg3video_getsp_pmb_type(slice) : mpeg3video_get_pmb_type(slice); | ||
227 | case B_TYPE: return video->pict_scal ? mpeg3video_getsp_bmb_type(slice) : mpeg3video_get_bmb_type(slice); | ||
228 | case D_TYPE: return mpeg3video_get_dmb_type(slice); | ||
229 | default: | ||
230 | /*fprintf(stderr, "mpeg3video_getmbtype: unknown coding type\n"); */ | ||
231 | break; | ||
232 | /* MPEG-1 only, not implemented */ | ||
233 | } | ||
234 | } | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | int mpeg3video_macroblock_modes(mpeg3_slice_t *slice, | ||
240 | mpeg3video_t *video, | ||
241 | int *pmb_type, | ||
242 | int *pstwtype, | ||
243 | int *pstwclass, | ||
244 | int *pmotion_type, | ||
245 | int *pmv_count, | ||
246 | int *pmv_format, | ||
247 | int *pdmv, | ||
248 | int *pmvscale, | ||
249 | int *pdct_type) | ||
250 | { | ||
251 | int mb_type; | ||
252 | int stwtype, stwcode, stwclass; | ||
253 | int motion_type = 0, mv_count, mv_format, dmv, mvscale; | ||
254 | int dct_type; | ||
255 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
256 | static unsigned char stwc_table[3][4] | ||
257 | = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} }; | ||
258 | static unsigned char stwclass_table[9] | ||
259 | = {0, 1, 2, 1, 1, 2, 3, 3, 4}; | ||
260 | |||
261 | /* get macroblock_type */ | ||
262 | mb_type = mpeg3video_get_mb_type(slice, video); | ||
263 | |||
264 | if(slice->fault) return 1; | ||
265 | |||
266 | /* get spatial_temporal_weight_code */ | ||
267 | if(mb_type & MB_WEIGHT) | ||
268 | { | ||
269 | if(video->stwc_table_index == 0) | ||
270 | stwtype = 4; | ||
271 | else | ||
272 | { | ||
273 | stwcode = mpeg3slice_getbits2(slice_buffer); | ||
274 | stwtype = stwc_table[video->stwc_table_index - 1][stwcode]; | ||
275 | } | ||
276 | } | ||
277 | else | ||
278 | stwtype = (mb_type & MB_CLASS4) ? 8 : 0; | ||
279 | |||
280 | /* derive spatial_temporal_weight_class (Table 7-18) */ | ||
281 | stwclass = stwclass_table[stwtype]; | ||
282 | |||
283 | /* get frame/field motion type */ | ||
284 | if(mb_type & (MB_FORWARD | MB_BACKWARD)) | ||
285 | { | ||
286 | if(video->pict_struct == FRAME_PICTURE) | ||
287 | { | ||
288 | /* frame_motion_type */ | ||
289 | motion_type = video->frame_pred_dct ? MC_FRAME : mpeg3slice_getbits2(slice_buffer); | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | /* field_motion_type */ | ||
294 | motion_type = mpeg3slice_getbits2(slice_buffer); | ||
295 | } | ||
296 | } | ||
297 | else | ||
298 | if((mb_type & MB_INTRA) && video->conceal_mv) | ||
299 | { | ||
300 | /* concealment motion vectors */ | ||
301 | motion_type = (video->pict_struct == FRAME_PICTURE) ? MC_FRAME : MC_FIELD; | ||
302 | } | ||
303 | |||
304 | /* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */ | ||
305 | if(video->pict_struct == FRAME_PICTURE) | ||
306 | { | ||
307 | mv_count = (motion_type == MC_FIELD && stwclass < 2) ? 2 : 1; | ||
308 | mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD; | ||
309 | } | ||
310 | else | ||
311 | { | ||
312 | mv_count = (motion_type == MC_16X8) ? 2 : 1; | ||
313 | mv_format = MV_FIELD; | ||
314 | } | ||
315 | |||
316 | dmv = (motion_type == MC_DMV); /* dual prime */ | ||
317 | |||
318 | /* field mv predictions in frame pictures have to be scaled */ | ||
319 | mvscale = ((mv_format == MV_FIELD) && (video->pict_struct == FRAME_PICTURE)); | ||
320 | |||
321 | /* get dct_type (frame DCT / field DCT) */ | ||
322 | dct_type = (video->pict_struct == FRAME_PICTURE) && | ||
323 | (!video->frame_pred_dct) && | ||
324 | (mb_type & (MB_PATTERN | MB_INTRA)) ? | ||
325 | mpeg3slice_getbit(slice_buffer) : 0; | ||
326 | |||
327 | /* return values */ | ||
328 | *pmb_type = mb_type; | ||
329 | *pstwtype = stwtype; | ||
330 | *pstwclass = stwclass; | ||
331 | *pmotion_type = motion_type; | ||
332 | *pmv_count = mv_count; | ||
333 | *pmv_format = mv_format; | ||
334 | *pdmv = dmv; | ||
335 | *pmvscale = mvscale; | ||
336 | *pdct_type = dct_type; | ||
337 | return 0; | ||
338 | } | ||