summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video/macroblocks.c') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/macroblocks.c338
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
9int 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
56static 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
75static 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
98static 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
123static 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
140static 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
163static 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
187static 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
199static 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
215int 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
239int 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}