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/slice.c | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video/slice.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libmpeg3/video/slice.c | 702 |
1 files changed, 702 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libmpeg3/video/slice.c b/core/multimedia/opieplayer/libmpeg3/video/slice.c new file mode 100644 index 0000000..90891b0 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/slice.c | |||
@@ -0,0 +1,702 @@ | |||
1 | #include "../libmpeg3.h" | ||
2 | #include "../mpeg3protos.h" | ||
3 | #include "mpeg3video.h" | ||
4 | #include "mpeg3videoprotos.h" | ||
5 | #include "slice.h" | ||
6 | |||
7 | #include <stdlib.h> | ||
8 | |||
9 | static ULONGLONG MMX_128 = 0x80008000800080LL; | ||
10 | |||
11 | int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) | ||
12 | { | ||
13 | pthread_mutexattr_t mutex_attr; | ||
14 | slice_buffer->data = (unsigned char*)malloc(1024); | ||
15 | slice_buffer->buffer_size = 0; | ||
16 | slice_buffer->buffer_allocation = 1024; | ||
17 | slice_buffer->current_position = 0; | ||
18 | slice_buffer->bits_size = 0; | ||
19 | slice_buffer->bits = 0; | ||
20 | slice_buffer->done = 0; | ||
21 | pthread_mutexattr_init(&mutex_attr); | ||
22 | pthread_mutex_init(&(slice_buffer->completion_lock), &mutex_attr); | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) | ||
27 | { | ||
28 | free(slice_buffer->data); | ||
29 | pthread_mutex_destroy(&(slice_buffer->completion_lock)); | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer) | ||
34 | { | ||
35 | int i; | ||
36 | unsigned char *new_buffer = | ||
37 | (unsigned char*)malloc(slice_buffer->buffer_allocation * 2); | ||
38 | for(i = 0; i < slice_buffer->buffer_size; i++) | ||
39 | new_buffer[i] = slice_buffer->data[i]; | ||
40 | free(slice_buffer->data); | ||
41 | slice_buffer->data = new_buffer; | ||
42 | slice_buffer->buffer_allocation *= 2; | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | /* limit coefficients to -2048..2047 */ | ||
47 | |||
48 | /* move/add 8x8-Block from block[comp] to refframe */ | ||
49 | |||
50 | static inline int mpeg3video_addblock(mpeg3_slice_t *slice, | ||
51 | mpeg3video_t *video, | ||
52 | int comp, | ||
53 | int bx, | ||
54 | int by, | ||
55 | int dct_type, | ||
56 | int addflag) | ||
57 | { | ||
58 | int cc, i, iincr; | ||
59 | unsigned char *rfp; | ||
60 | short *bp; | ||
61 | int spar = slice->sparse[comp]; | ||
62 | /* color component index */ | ||
63 | cc = (comp < 4) ? 0 : (comp & 1) + 1; | ||
64 | |||
65 | if(cc == 0) | ||
66 | { | ||
67 | /* luminance */ | ||
68 | if(video->pict_struct == FRAME_PICTURE) | ||
69 | { | ||
70 | if(dct_type) | ||
71 | { | ||
72 | /* field DCT coding */ | ||
73 | rfp = video->newframe[0] + | ||
74 | video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3); | ||
75 | iincr = (video->coded_picture_width << 1); | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | /* frame DCT coding */ | ||
80 | rfp = video->newframe[0] + | ||
81 | video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3); | ||
82 | iincr = video->coded_picture_width; | ||
83 | } | ||
84 | } | ||
85 | else | ||
86 | { | ||
87 | /* field picture */ | ||
88 | rfp = video->newframe[0] + | ||
89 | (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3); | ||
90 | iincr = (video->coded_picture_width << 1); | ||
91 | } | ||
92 | } | ||
93 | else | ||
94 | { | ||
95 | /* chrominance */ | ||
96 | |||
97 | /* scale coordinates */ | ||
98 | if(video->chroma_format != CHROMA444) bx >>= 1; | ||
99 | if(video->chroma_format == CHROMA420) by >>= 1; | ||
100 | if(video->pict_struct == FRAME_PICTURE) | ||
101 | { | ||
102 | if(dct_type && (video->chroma_format != CHROMA420)) | ||
103 | { | ||
104 | /* field DCT coding */ | ||
105 | rfp = video->newframe[cc] | ||
106 | + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8); | ||
107 | iincr = (video->chrom_width << 1); | ||
108 | } | ||
109 | else | ||
110 | { | ||
111 | /* frame DCT coding */ | ||
112 | rfp = video->newframe[cc] | ||
113 | + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8); | ||
114 | iincr = video->chrom_width; | ||
115 | } | ||
116 | } | ||
117 | else | ||
118 | { | ||
119 | /* field picture */ | ||
120 | rfp = video->newframe[cc] | ||
121 | + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8); | ||
122 | iincr = (video->chrom_width << 1); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | bp = slice->block[comp]; | ||
127 | |||
128 | if(addflag) | ||
129 | { | ||
130 | #ifdef HAVE_MMX | ||
131 | if(video->have_mmx) | ||
132 | { | ||
133 | if(spar) | ||
134 | { | ||
135 | __asm__ __volatile__( | ||
136 | "movq (%2), %%mm6\n" /* 4 blockvals */ | ||
137 | "pxor %%mm4, %%mm4\n" | ||
138 | "punpcklwd %%mm6, %%mm6\n" | ||
139 | "punpcklwd %%mm6, %%mm6\n" | ||
140 | ".align 8\n" | ||
141 | "1:" | ||
142 | "movq (%1), %%mm0\n" /* 8 rindex1 */ | ||
143 | "movq %%mm0, %%mm2\n" | ||
144 | "punpcklbw %%mm4, %%mm0\n" | ||
145 | "punpckhbw %%mm4, %%mm2\n" | ||
146 | "paddw %%mm6, %%mm0\n" | ||
147 | "paddw %%mm6, %%mm2\n" | ||
148 | |||
149 | "packuswb %%mm2, %%mm0\n" | ||
150 | "movq %%mm0, (%1)\n" | ||
151 | |||
152 | "leal (%1, %3), %1\n" | ||
153 | "loop 1b\n" | ||
154 | : /* scr dest */ | ||
155 | : "c" (8),"r" (rfp), "r" (bp), "r" (iincr) | ||
156 | ); | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | __asm__ __volatile__( | ||
161 | "pxor %%mm4, %%mm4\n" | ||
162 | |||
163 | ".align 8\n" | ||
164 | "1:" | ||
165 | "movq (%2), %%mm0\n" /* 8 rfp 0 1 2 3 4 5 6 7*/ | ||
166 | "movq (%1), %%mm6\n" /* 4 blockvals 0 1 2 3 */ | ||
167 | |||
168 | "movq %%mm0, %%mm2\n" | ||
169 | "movq 8(%1), %%mm5\n" /* 4 blockvals 0 1 2 3 */ | ||
170 | "punpcklbw %%mm4, %%mm0\n" /* 0 2 4 6 */ | ||
171 | "punpckhbw %%mm4, %%mm2\n" /* 1 3 5 7 */ | ||
172 | |||
173 | "paddw %%mm6, %%mm0\n" | ||
174 | "paddw %%mm5, %%mm2\n" | ||
175 | "packuswb %%mm2, %%mm0\n" | ||
176 | |||
177 | "addl $16, %1\n" | ||
178 | "movq %%mm0, (%2)\n" | ||
179 | |||
180 | "leal (%2,%3), %2\n" | ||
181 | "loop 1b\n" | ||
182 | : /* scr dest */ | ||
183 | : "c" (8),"r" (bp), "r" (rfp), "r" (iincr) | ||
184 | ); | ||
185 | } | ||
186 | } | ||
187 | else | ||
188 | #endif | ||
189 | for(i = 0; i < 8; i++) | ||
190 | { | ||
191 | rfp[0] = CLIP(bp[0] + rfp[0]); | ||
192 | rfp[1] = CLIP(bp[1] + rfp[1]); | ||
193 | rfp[2] = CLIP(bp[2] + rfp[2]); | ||
194 | rfp[3] = CLIP(bp[3] + rfp[3]); | ||
195 | rfp[4] = CLIP(bp[4] + rfp[4]); | ||
196 | rfp[5] = CLIP(bp[5] + rfp[5]); | ||
197 | rfp[6] = CLIP(bp[6] + rfp[6]); | ||
198 | rfp[7] = CLIP(bp[7] + rfp[7]); | ||
199 | rfp += iincr; | ||
200 | bp += 8; | ||
201 | } | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | #ifdef HAVE_MMX | ||
206 | if(video->have_mmx) | ||
207 | { | ||
208 | if(spar) | ||
209 | { | ||
210 | __asm__ __volatile__( | ||
211 | "movd (%2), %%mm0\n" /* " 0 0 0 v1" */ | ||
212 | "punpcklwd %%mm0, %%mm0\n" /* " 0 0 v1 v1" */ | ||
213 | "punpcklwd %%mm0, %%mm0\n" | ||
214 | "paddw MMX_128, %%mm0\n" | ||
215 | "packuswb %%mm0, %%mm0\n" | ||
216 | "leal (%0,%1,2), %%eax\n" | ||
217 | |||
218 | "movq %%mm0, (%0, %1)\n" | ||
219 | "movq %%mm0, (%%eax)\n" | ||
220 | "leal (%%eax,%1,2), %0\n" | ||
221 | "movq %%mm0, (%%eax, %1)\n" | ||
222 | |||
223 | "movq %%mm0, (%0)\n" | ||
224 | "leal (%0,%1,2), %%eax\n" | ||
225 | "movq %%mm0, (%0, %1)\n" | ||
226 | |||
227 | "movq %%mm0, (%%eax)\n" | ||
228 | "movq %%mm0, (%%eax, %1)\n" | ||
229 | : | ||
230 | : "D" (rfp), "c" (iincr), "b" (bp) | ||
231 | : "eax"); | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | __asm__ __volatile__( | ||
236 | "movq MMX_128,%%mm4\n" | ||
237 | ".align 8\n" | ||
238 | "1:" | ||
239 | "movq (%1), %%mm0\n" | ||
240 | "movq 8(%1), %%mm1\n" | ||
241 | "paddw %%mm4, %%mm0\n" | ||
242 | |||
243 | "movq 16(%1), %%mm2\n" | ||
244 | "paddw %%mm4, %%mm1\n" | ||
245 | |||
246 | "movq 24(%1), %%mm3\n" | ||
247 | "paddw %%mm4, %%mm2\n" | ||
248 | |||
249 | "packuswb %%mm1, %%mm0\n" | ||
250 | "paddw %%mm4, %%mm3\n" | ||
251 | |||
252 | "addl $32, %1\n" | ||
253 | "packuswb %%mm3, %%mm2\n" | ||
254 | |||
255 | "movq %%mm0, (%2)\n" | ||
256 | |||
257 | "movq %%mm2, (%2,%3)\n" | ||
258 | |||
259 | "leal (%2,%3,2), %2\n" | ||
260 | "loop 1b\n" | ||
261 | : | ||
262 | : "c" (4), "r" (bp), "r" (rfp), "r" (iincr) | ||
263 | ); | ||
264 | } | ||
265 | } | ||
266 | else | ||
267 | #endif | ||
268 | for(i = 0; i < 8; i++) | ||
269 | { | ||
270 | rfp[0] = CLIP(bp[0] + 128); | ||
271 | rfp[1] = CLIP(bp[1] + 128); | ||
272 | rfp[2] = CLIP(bp[2] + 128); | ||
273 | rfp[3] = CLIP(bp[3] + 128); | ||
274 | rfp[4] = CLIP(bp[4] + 128); | ||
275 | rfp[5] = CLIP(bp[5] + 128); | ||
276 | rfp[6] = CLIP(bp[6] + 128); | ||
277 | rfp[7] = CLIP(bp[7] + 128); | ||
278 | rfp+= iincr; | ||
279 | bp += 8; | ||
280 | } | ||
281 | } | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | int mpeg3_decode_slice(mpeg3_slice_t *slice) | ||
286 | { | ||
287 | mpeg3video_t *video = slice->video; | ||
288 | int comp; | ||
289 | int mb_type, cbp, motion_type = 0, dct_type; | ||
290 | int macroblock_address, mba_inc, mba_max; | ||
291 | int slice_vert_pos_ext; | ||
292 | unsigned int code; | ||
293 | int bx, by; | ||
294 | int dc_dct_pred[3]; | ||
295 | int mv_count, mv_format, mvscale; | ||
296 | int pmv[2][2][2], mv_field_sel[2][2]; | ||
297 | int dmv, dmvector[2]; | ||
298 | int qs; | ||
299 | int stwtype, stwclass; | ||
300 | int snr_cbp; | ||
301 | int i; | ||
302 | mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; | ||
303 | |||
304 | /* number of macroblocks per picture */ | ||
305 | mba_max = video->mb_width * video->mb_height; | ||
306 | |||
307 | /* field picture has half as many macroblocks as frame */ | ||
308 | if(video->pict_struct != FRAME_PICTURE) | ||
309 | mba_max >>= 1; | ||
310 | |||
311 | /* macroblock address */ | ||
312 | macroblock_address = 0; | ||
313 | /* first macroblock in slice is not skipped */ | ||
314 | mba_inc = 0; | ||
315 | slice->fault = 0; | ||
316 | |||
317 | code = mpeg3slice_getbits(slice_buffer, 32); | ||
318 | /* decode slice header (may change quant_scale) */ | ||
319 | slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video); | ||
320 | |||
321 | /* reset all DC coefficient and motion vector predictors */ | ||
322 | dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; | ||
323 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
324 | pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; | ||
325 | |||
326 | for(i = 0; | ||
327 | slice_buffer->current_position < slice_buffer->buffer_size; | ||
328 | i++) | ||
329 | { | ||
330 | if(mba_inc == 0) | ||
331 | { | ||
332 | /* Done */ | ||
333 | if(!mpeg3slice_showbits(slice_buffer, 23)) return 0; | ||
334 | /* decode macroblock address increment */ | ||
335 | mba_inc = mpeg3video_get_macroblock_address(slice); | ||
336 | |||
337 | if(slice->fault) return 1; | ||
338 | |||
339 | if(i == 0) | ||
340 | { | ||
341 | /* Get the macroblock_address */ | ||
342 | macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1; | ||
343 | /* first macroblock in slice: not skipped */ | ||
344 | mba_inc = 1; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | if(slice->fault) return 1; | ||
349 | |||
350 | if(macroblock_address >= mba_max) | ||
351 | { | ||
352 | /* mba_inc points beyond picture dimensions */ | ||
353 | /*fprintf(stderr, "mpeg3_decode_slice: too many macroblocks in picture\n"); */ | ||
354 | return 1; | ||
355 | } | ||
356 | |||
357 | /* not skipped */ | ||
358 | if(mba_inc == 1) | ||
359 | { | ||
360 | mpeg3video_macroblock_modes(slice, | ||
361 | video, | ||
362 | &mb_type, | ||
363 | &stwtype, | ||
364 | &stwclass, | ||
365 | &motion_type, | ||
366 | &mv_count, | ||
367 | &mv_format, | ||
368 | &dmv, | ||
369 | &mvscale, | ||
370 | &dct_type); | ||
371 | |||
372 | if(slice->fault) return 1; | ||
373 | |||
374 | if(mb_type & MB_QUANT) | ||
375 | { | ||
376 | qs = mpeg3slice_getbits(slice_buffer, 5); | ||
377 | |||
378 | if(video->mpeg2) | ||
379 | slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1); | ||
380 | else | ||
381 | slice->quant_scale = qs; | ||
382 | |||
383 | if(video->scalable_mode == SC_DP) | ||
384 | /* make sure quant_scale is valid */ | ||
385 | slice->quant_scale = slice->quant_scale; | ||
386 | } | ||
387 | |||
388 | /* motion vectors */ | ||
389 | |||
390 | |||
391 | /* decode forward motion vectors */ | ||
392 | if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv)) | ||
393 | { | ||
394 | if(video->mpeg2) | ||
395 | mpeg3video_motion_vectors(slice, | ||
396 | video, | ||
397 | pmv, | ||
398 | dmvector, | ||
399 | mv_field_sel, | ||
400 | 0, | ||
401 | mv_count, | ||
402 | mv_format, | ||
403 | video->h_forw_r_size, | ||
404 | video->v_forw_r_size, | ||
405 | dmv, | ||
406 | mvscale); | ||
407 | else | ||
408 | mpeg3video_motion_vector(slice, | ||
409 | video, | ||
410 | pmv[0][0], | ||
411 | dmvector, | ||
412 | video->forw_r_size, | ||
413 | video->forw_r_size, | ||
414 | 0, | ||
415 | 0, | ||
416 | video->full_forw); | ||
417 | } | ||
418 | if(slice->fault) return 1; | ||
419 | |||
420 | /* decode backward motion vectors */ | ||
421 | if(mb_type & MB_BACKWARD) | ||
422 | { | ||
423 | if(video->mpeg2) | ||
424 | mpeg3video_motion_vectors(slice, | ||
425 | video, | ||
426 | pmv, | ||
427 | dmvector, | ||
428 | mv_field_sel, | ||
429 | 1, | ||
430 | mv_count, | ||
431 | mv_format, | ||
432 | video->h_back_r_size, | ||
433 | video->v_back_r_size, | ||
434 | 0, | ||
435 | mvscale); | ||
436 | else | ||
437 | mpeg3video_motion_vector(slice, | ||
438 | video, | ||
439 | pmv[0][1], | ||
440 | dmvector, | ||
441 | video->back_r_size, | ||
442 | video->back_r_size, | ||
443 | 0, | ||
444 | 0, | ||
445 | video->full_back); | ||
446 | } | ||
447 | |||
448 | if(slice->fault) return 1; | ||
449 | |||
450 | /* remove marker_bit */ | ||
451 | if((mb_type & MB_INTRA) && video->conceal_mv) | ||
452 | mpeg3slice_flushbit(slice_buffer); | ||
453 | |||
454 | /* macroblock_pattern */ | ||
455 | if(mb_type & MB_PATTERN) | ||
456 | { | ||
457 | cbp = mpeg3video_get_cbp(slice); | ||
458 | if(video->chroma_format == CHROMA422) | ||
459 | { | ||
460 | /* coded_block_pattern_1 */ | ||
461 | cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer); | ||
462 | } | ||
463 | else | ||
464 | if(video->chroma_format == CHROMA444) | ||
465 | { | ||
466 | /* coded_block_pattern_2 */ | ||
467 | cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6); | ||
468 | } | ||
469 | } | ||
470 | else | ||
471 | cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0; | ||
472 | |||
473 | if(slice->fault) return 1; | ||
474 | /* decode blocks */ | ||
475 | mpeg3video_clearblock(slice, 0, video->blk_cnt); | ||
476 | for(comp = 0; comp < video->blk_cnt; comp++) | ||
477 | { | ||
478 | if(cbp & (1 << (video->blk_cnt - comp - 1))) | ||
479 | { | ||
480 | if(mb_type & MB_INTRA) | ||
481 | { | ||
482 | if(video->mpeg2) | ||
483 | mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred); | ||
484 | else | ||
485 | mpeg3video_getintrablock(slice, video, comp, dc_dct_pred); | ||
486 | } | ||
487 | else | ||
488 | { | ||
489 | if(video->mpeg2) | ||
490 | mpeg3video_getmpg2interblock(slice, video, comp); | ||
491 | else | ||
492 | mpeg3video_getinterblock(slice, video, comp); | ||
493 | } | ||
494 | if(slice->fault) return 1; | ||
495 | } | ||
496 | } | ||
497 | |||
498 | /* reset intra_dc predictors */ | ||
499 | if(!(mb_type & MB_INTRA)) | ||
500 | dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; | ||
501 | |||
502 | /* reset motion vector predictors */ | ||
503 | if((mb_type & MB_INTRA) && !video->conceal_mv) | ||
504 | { | ||
505 | /* intra mb without concealment motion vectors */ | ||
506 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
507 | pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; | ||
508 | } | ||
509 | |||
510 | if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA))) | ||
511 | { | ||
512 | /* non-intra mb without forward mv in a P picture */ | ||
513 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
514 | |||
515 | /* derive motion_type */ | ||
516 | if(video->pict_struct == FRAME_PICTURE) | ||
517 | motion_type = MC_FRAME; | ||
518 | else | ||
519 | { | ||
520 | motion_type = MC_FIELD; | ||
521 | /* predict from field of same parity */ | ||
522 | mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD); | ||
523 | } | ||
524 | } | ||
525 | |||
526 | if(stwclass == 4) | ||
527 | { | ||
528 | /* purely spatially predicted macroblock */ | ||
529 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
530 | pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; | ||
531 | } | ||
532 | } | ||
533 | else | ||
534 | { | ||
535 | /* mba_inc!=1: skipped macroblock */ | ||
536 | mpeg3video_clearblock(slice, 0, video->blk_cnt); | ||
537 | |||
538 | /* reset intra_dc predictors */ | ||
539 | dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; | ||
540 | |||
541 | /* reset motion vector predictors */ | ||
542 | if(video->pict_type == P_TYPE) | ||
543 | pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; | ||
544 | |||
545 | /* derive motion_type */ | ||
546 | if(video->pict_struct == FRAME_PICTURE) | ||
547 | motion_type = MC_FRAME; | ||
548 | else | ||
549 | { | ||
550 | motion_type = MC_FIELD; | ||
551 | /* predict from field of same parity */ | ||
552 | mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD); | ||
553 | } | ||
554 | |||
555 | /* skipped I are spatial-only predicted, */ | ||
556 | /* skipped P and B are temporal-only predicted */ | ||
557 | stwtype = (video->pict_type == I_TYPE) ? 8 : 0; | ||
558 | |||
559 | /* clear MB_INTRA */ | ||
560 | mb_type &= ~MB_INTRA; | ||
561 | |||
562 | /* no block data */ | ||
563 | cbp = 0; | ||
564 | } | ||
565 | |||
566 | snr_cbp = 0; | ||
567 | |||
568 | /* pixel coordinates of top left corner of current macroblock */ | ||
569 | bx = 16 * (macroblock_address % video->mb_width); | ||
570 | by = 16 * (macroblock_address / video->mb_width); | ||
571 | |||
572 | /* motion compensation */ | ||
573 | if(!(mb_type & MB_INTRA)) | ||
574 | mpeg3video_reconstruct(video, | ||
575 | bx, | ||
576 | by, | ||
577 | mb_type, | ||
578 | motion_type, | ||
579 | pmv, | ||
580 | mv_field_sel, | ||
581 | dmvector, | ||
582 | stwtype); | ||
583 | |||
584 | /* copy or add block data into picture */ | ||
585 | for(comp = 0; comp < video->blk_cnt; comp++) | ||
586 | { | ||
587 | if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp))) | ||
588 | { | ||
589 | #ifdef HAVE_MMX | ||
590 | if(video->have_mmx) | ||
591 | IDCT_mmx(slice->block[comp]); | ||
592 | else | ||
593 | #endif | ||
594 | mpeg3video_idct_conversion(slice->block[comp]); | ||
595 | |||
596 | mpeg3video_addblock(slice, | ||
597 | video, | ||
598 | comp, | ||
599 | bx, | ||
600 | by, | ||
601 | dct_type, | ||
602 | (mb_type & MB_INTRA) == 0); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /* advance to next macroblock */ | ||
607 | macroblock_address++; | ||
608 | mba_inc--; | ||
609 | } | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | void mpeg3_slice_loop(mpeg3_slice_t *slice) | ||
615 | { | ||
616 | mpeg3video_t *video = slice->video; | ||
617 | int result = 1; | ||
618 | |||
619 | while(!slice->done) | ||
620 | { | ||
621 | pthread_mutex_lock(&(slice->input_lock)); | ||
622 | |||
623 | if(!slice->done) | ||
624 | { | ||
625 | /* Get a buffer to decode */ | ||
626 | result = 1; | ||
627 | pthread_mutex_lock(&(video->slice_lock)); | ||
628 | if(slice->buffer_step > 0) | ||
629 | { | ||
630 | while(slice->current_buffer <= slice->last_buffer) | ||
631 | { | ||
632 | if(!video->slice_buffers[slice->current_buffer].done && | ||
633 | slice->current_buffer <= slice->last_buffer) | ||
634 | { | ||
635 | result = 0; | ||
636 | break; | ||
637 | } | ||
638 | slice->current_buffer += slice->buffer_step; | ||
639 | } | ||
640 | } | ||
641 | else | ||
642 | { | ||
643 | while(slice->current_buffer >= slice->last_buffer) | ||
644 | { | ||
645 | if(!video->slice_buffers[slice->current_buffer].done && | ||
646 | slice->current_buffer >= slice->last_buffer) | ||
647 | { | ||
648 | result = 0; | ||
649 | break; | ||
650 | } | ||
651 | slice->current_buffer += slice->buffer_step; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | /* Got one */ | ||
656 | if(!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers) | ||
657 | { | ||
658 | slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]); | ||
659 | slice->slice_buffer->done = 1; | ||
660 | pthread_mutex_unlock(&(video->slice_lock)); | ||
661 | pthread_mutex_unlock(&(slice->input_lock)); | ||
662 | mpeg3_decode_slice(slice); | ||
663 | pthread_mutex_unlock(&(slice->slice_buffer->completion_lock)); | ||
664 | } | ||
665 | else | ||
666 | pthread_mutex_unlock(&(video->slice_lock)); | ||
667 | } | ||
668 | |||
669 | pthread_mutex_unlock(&(slice->output_lock)); | ||
670 | } | ||
671 | } | ||
672 | |||
673 | int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice) | ||
674 | { | ||
675 | pthread_attr_t attr; | ||
676 | //struct sched_param param; | ||
677 | pthread_mutexattr_t mutex_attr; | ||
678 | |||
679 | slice->video = video; | ||
680 | slice->done = 0; | ||
681 | pthread_mutexattr_init(&mutex_attr); | ||
682 | pthread_mutex_init(&(slice->input_lock), &mutex_attr); | ||
683 | pthread_mutex_lock(&(slice->input_lock)); | ||
684 | pthread_mutex_init(&(slice->output_lock), &mutex_attr); | ||
685 | pthread_mutex_lock(&(slice->output_lock)); | ||
686 | |||
687 | pthread_attr_init(&attr); | ||
688 | pthread_create(&(slice->tid), &attr, | ||
689 | (void * (*)(void *))mpeg3_slice_loop, slice); | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice) | ||
695 | { | ||
696 | slice->done = 1; | ||
697 | pthread_mutex_unlock(&(slice->input_lock)); | ||
698 | pthread_join(slice->tid, 0); | ||
699 | pthread_mutex_destroy(&(slice->input_lock)); | ||
700 | pthread_mutex_destroy(&(slice->output_lock)); | ||
701 | return 0; | ||
702 | } | ||