summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libmpeg3/video/slice.c
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/video/slice.c') (more/less context) (show whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/slice.c702
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
9static ULONGLONG MMX_128 = 0x80008000800080LL;
10
11int 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
26int 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
33int 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
50static 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
285int 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
614void 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
673int 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
694int 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}