2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "cpudetect.h"
30 static int diff_y_mmx(unsigned char *a
, unsigned char *b
, int s
)
35 "pxor %%mm4, %%mm4 \n\t"
36 "pxor %%mm7, %%mm7 \n\t"
40 "movq (%%"REG_S
"), %%mm0 \n\t"
41 "movq (%%"REG_S
"), %%mm2 \n\t"
42 "add %%"REG_a
", %%"REG_S
" \n\t"
43 "movq (%%"REG_D
"), %%mm1 \n\t"
44 "add %%"REG_a
", %%"REG_D
" \n\t"
45 "psubusb %%mm1, %%mm2 \n\t"
46 "psubusb %%mm0, %%mm1 \n\t"
47 "movq %%mm2, %%mm0 \n\t"
48 "movq %%mm1, %%mm3 \n\t"
49 "punpcklbw %%mm7, %%mm0 \n\t"
50 "punpcklbw %%mm7, %%mm1 \n\t"
51 "punpckhbw %%mm7, %%mm2 \n\t"
52 "punpckhbw %%mm7, %%mm3 \n\t"
53 "paddw %%mm0, %%mm4 \n\t"
54 "paddw %%mm1, %%mm4 \n\t"
55 "paddw %%mm2, %%mm4 \n\t"
56 "paddw %%mm3, %%mm4 \n\t"
61 "movq %%mm4, %%mm3 \n\t"
62 "punpcklwd %%mm7, %%mm4 \n\t"
63 "punpckhwd %%mm7, %%mm3 \n\t"
64 "paddd %%mm4, %%mm3 \n\t"
65 "movd %%mm3, %%eax \n\t"
66 "psrlq $32, %%mm3 \n\t"
67 "movd %%mm3, %%edx \n\t"
68 "addl %%edx, %%eax \n\t"
71 : "S" (a
), "D" (b
), "a" (s
)
77 static int licomb_y_mmx(unsigned char *a
, unsigned char *b
, int s
)
82 "pxor %%mm6, %%mm6 \n\t"
83 "pxor %%mm7, %%mm7 \n\t"
84 "sub %%"REG_a
", %%"REG_D
" \n\t"
88 "movq (%%"REG_D
"), %%mm0 \n\t"
89 "movq (%%"REG_D
"), %%mm1 \n\t"
90 "punpcklbw %%mm7, %%mm0 \n\t"
91 "movq (%%"REG_D
",%%"REG_a
"), %%mm2 \n\t"
92 "punpcklbw %%mm7, %%mm1 \n\t"
93 "punpcklbw %%mm7, %%mm2 \n\t"
94 "paddw %%mm0, %%mm0 \n\t"
95 "paddw %%mm2, %%mm1 \n\t"
96 "movq %%mm0, %%mm2 \n\t"
97 "psubusw %%mm1, %%mm0 \n\t"
98 "psubusw %%mm2, %%mm1 \n\t"
99 "paddw %%mm0, %%mm6 \n\t"
100 "paddw %%mm1, %%mm6 \n\t"
102 "movq (%%"REG_S
"), %%mm0 \n\t"
103 "movq (%%"REG_D
"), %%mm1 \n\t"
104 "punpckhbw %%mm7, %%mm0 \n\t"
105 "movq (%%"REG_D
",%%"REG_a
"), %%mm2 \n\t"
106 "punpckhbw %%mm7, %%mm1 \n\t"
107 "punpckhbw %%mm7, %%mm2 \n\t"
108 "paddw %%mm0, %%mm0 \n\t"
109 "paddw %%mm2, %%mm1 \n\t"
110 "movq %%mm0, %%mm2 \n\t"
111 "psubusw %%mm1, %%mm0 \n\t"
112 "psubusw %%mm2, %%mm1 \n\t"
113 "paddw %%mm0, %%mm6 \n\t"
114 "paddw %%mm1, %%mm6 \n\t"
116 "movq (%%"REG_D
",%%"REG_a
"), %%mm0 \n\t"
117 "movq (%%"REG_S
"), %%mm1 \n\t"
118 "punpcklbw %%mm7, %%mm0 \n\t"
119 "movq (%%"REG_S
",%%"REG_a
"), %%mm2 \n\t"
120 "punpcklbw %%mm7, %%mm1 \n\t"
121 "punpcklbw %%mm7, %%mm2 \n\t"
122 "paddw %%mm0, %%mm0 \n\t"
123 "paddw %%mm2, %%mm1 \n\t"
124 "movq %%mm0, %%mm2 \n\t"
125 "psubusw %%mm1, %%mm0 \n\t"
126 "psubusw %%mm2, %%mm1 \n\t"
127 "paddw %%mm0, %%mm6 \n\t"
128 "paddw %%mm1, %%mm6 \n\t"
130 "movq (%%"REG_D
",%%"REG_a
"), %%mm0 \n\t"
131 "movq (%%"REG_S
"), %%mm1 \n\t"
132 "punpckhbw %%mm7, %%mm0 \n\t"
133 "movq (%%"REG_S
",%%"REG_a
"), %%mm2 \n\t"
134 "punpckhbw %%mm7, %%mm1 \n\t"
135 "punpckhbw %%mm7, %%mm2 \n\t"
136 "paddw %%mm0, %%mm0 \n\t"
137 "paddw %%mm2, %%mm1 \n\t"
138 "movq %%mm0, %%mm2 \n\t"
139 "psubusw %%mm1, %%mm0 \n\t"
140 "psubusw %%mm2, %%mm1 \n\t"
141 "paddw %%mm0, %%mm6 \n\t"
142 "paddw %%mm1, %%mm6 \n\t"
144 "add %%"REG_a
", %%"REG_S
" \n\t"
145 "add %%"REG_a
", %%"REG_D
" \n\t"
149 "movq %%mm6, %%mm5 \n\t"
150 "punpcklwd %%mm7, %%mm6 \n\t"
151 "punpckhwd %%mm7, %%mm5 \n\t"
152 "paddd %%mm6, %%mm5 \n\t"
153 "movd %%mm5, %%eax \n\t"
154 "psrlq $32, %%mm5 \n\t"
155 "movd %%mm5, %%edx \n\t"
156 "addl %%edx, %%eax \n\t"
160 : "S" (a
), "D" (b
), "a" (s
)
166 static int var_y_mmx(unsigned char *a
, unsigned char *b
, int s
)
170 "movl $3, %%ecx \n\t"
171 "pxor %%mm4, %%mm4 \n\t"
172 "pxor %%mm7, %%mm7 \n\t"
176 "movq (%%"REG_S
"), %%mm0 \n\t"
177 "movq (%%"REG_S
"), %%mm2 \n\t"
178 "movq (%%"REG_S
",%%"REG_a
"), %%mm1 \n\t"
179 "add %%"REG_a
", %%"REG_S
" \n\t"
180 "psubusb %%mm1, %%mm2 \n\t"
181 "psubusb %%mm0, %%mm1 \n\t"
182 "movq %%mm2, %%mm0 \n\t"
183 "movq %%mm1, %%mm3 \n\t"
184 "punpcklbw %%mm7, %%mm0 \n\t"
185 "punpcklbw %%mm7, %%mm1 \n\t"
186 "punpckhbw %%mm7, %%mm2 \n\t"
187 "punpckhbw %%mm7, %%mm3 \n\t"
188 "paddw %%mm0, %%mm4 \n\t"
189 "paddw %%mm1, %%mm4 \n\t"
190 "paddw %%mm2, %%mm4 \n\t"
191 "paddw %%mm3, %%mm4 \n\t"
196 "movq %%mm4, %%mm3 \n\t"
197 "punpcklwd %%mm7, %%mm4 \n\t"
198 "punpckhwd %%mm7, %%mm3 \n\t"
199 "paddd %%mm4, %%mm3 \n\t"
200 "movd %%mm3, %%eax \n\t"
201 "psrlq $32, %%mm3 \n\t"
202 "movd %%mm3, %%edx \n\t"
203 "addl %%edx, %%eax \n\t"
214 #define ABS(a) (((a)^((a)>>31))-((a)>>31))
216 static int diff_y(unsigned char *a
, unsigned char *b
, int s
)
220 for (j
=0; j
<8; j
++) diff
+= ABS(a
[j
]-b
[j
]);
226 static int licomb_y(unsigned char *a
, unsigned char *b
, int s
)
231 diff
+= ABS((a
[j
]<<1) - b
[j
-s
] - b
[j
])
232 + ABS((b
[j
]<<1) - a
[j
] - a
[j
+s
]);
239 static int qpcomb_y(unsigned char *a
, unsigned char *b
, int s
)
244 diff
+= ABS(a
[j
] - 3*b
[j
-s
] + 3*a
[j
+s
] - b
[j
]);
250 static int licomb_y_test(unsigned char *a
, unsigned char *b
, int s
)
252 int c
= licomb_y(a
,b
,s
);
253 int m
= licomb_y_mmx(a
,b
,s
);
254 if (c
!= m
) printf("%d != %d\n", c
, m
);
259 static int var_y(unsigned char *a
, unsigned char *b
, int s
)
263 for (j
=0; j
<8; j
++) {
264 var
+= ABS(a
[j
]-a
[j
+s
]);
268 return 4*var
; /* match comb scaling */
279 static void alloc_buffer(struct pullup_context
*c
, struct pullup_buffer
*b
)
282 if (b
->planes
) return;
283 b
->planes
= calloc(c
->nplanes
, sizeof(unsigned char *));
284 for (i
= 0; i
< c
->nplanes
; i
++) {
285 b
->planes
[i
] = malloc(c
->h
[i
]*c
->stride
[i
]);
286 /* Deal with idiotic 128=0 for chroma: */
287 memset(b
->planes
[i
], c
->background
[i
], c
->h
[i
]*c
->stride
[i
]);
291 struct pullup_buffer
*pullup_lock_buffer(struct pullup_buffer
*b
, int parity
)
294 if ((parity
+1) & 1) b
->lock
[0]++;
295 if ((parity
+1) & 2) b
->lock
[1]++;
299 void pullup_release_buffer(struct pullup_buffer
*b
, int parity
)
302 if ((parity
+1) & 1) b
->lock
[0]--;
303 if ((parity
+1) & 2) b
->lock
[1]--;
306 struct pullup_buffer
*pullup_get_buffer(struct pullup_context
*c
, int parity
)
310 /* Try first to get the sister buffer for the previous field */
311 if (parity
< 2 && c
->last
&& parity
!= c
->last
->parity
312 && !c
->last
->buffer
->lock
[parity
]) {
313 alloc_buffer(c
, c
->last
->buffer
);
314 return pullup_lock_buffer(c
->last
->buffer
, parity
);
317 /* Prefer a buffer with both fields open */
318 for (i
= 0; i
< c
->nbuffers
; i
++) {
319 if (c
->buffers
[i
].lock
[0]) continue;
320 if (c
->buffers
[i
].lock
[1]) continue;
321 alloc_buffer(c
, &c
->buffers
[i
]);
322 return pullup_lock_buffer(&c
->buffers
[i
], parity
);
325 if (parity
== 2) return 0;
327 /* Search for any half-free buffer */
328 for (i
= 0; i
< c
->nbuffers
; i
++) {
329 if (((parity
+1) & 1) && c
->buffers
[i
].lock
[0]) continue;
330 if (((parity
+1) & 2) && c
->buffers
[i
].lock
[1]) continue;
331 alloc_buffer(c
, &c
->buffers
[i
]);
332 return pullup_lock_buffer(&c
->buffers
[i
], parity
);
343 static void compute_metric(struct pullup_context
*c
,
344 struct pullup_field
*fa
, int pa
,
345 struct pullup_field
*fb
, int pb
,
346 int (*func
)(unsigned char *, unsigned char *, int), int *dest
)
348 unsigned char *a
, *b
;
350 int mp
= c
->metric_plane
;
351 int xstep
= c
->bpp
[mp
];
352 int ystep
= c
->stride
[mp
]<<3;
353 int s
= c
->stride
[mp
]<<1; /* field stride */
354 int w
= c
->metric_w
*xstep
;
356 if (!fa
->buffer
|| !fb
->buffer
) return;
358 /* Shortcut for duplicate fields (e.g. from RFF flag) */
359 if (fa
->buffer
== fb
->buffer
&& pa
== pb
) {
360 memset(dest
, 0, c
->metric_len
* sizeof(int));
364 a
= fa
->buffer
->planes
[mp
] + pa
* c
->stride
[mp
] + c
->metric_offset
;
365 b
= fb
->buffer
->planes
[mp
] + pb
* c
->stride
[mp
] + c
->metric_offset
;
367 for (y
= c
->metric_h
; y
; y
--) {
368 for (x
= 0; x
< w
; x
+= xstep
) {
369 *dest
++ = func(a
+ x
, b
+ x
, s
);
371 a
+= ystep
; b
+= ystep
;
379 static void alloc_metrics(struct pullup_context
*c
, struct pullup_field
*f
)
381 f
->diffs
= calloc(c
->metric_len
, sizeof(int));
382 f
->comb
= calloc(c
->metric_len
, sizeof(int));
383 f
->var
= calloc(c
->metric_len
, sizeof(int));
384 /* add more metrics here as needed */
387 static struct pullup_field
*make_field_queue(struct pullup_context
*c
, int len
)
389 struct pullup_field
*head
, *f
;
390 f
= head
= calloc(1, sizeof(struct pullup_field
));
392 for (; len
> 0; len
--) {
393 f
->next
= calloc(1, sizeof(struct pullup_field
));
403 static void check_field_queue(struct pullup_context
*c
)
405 if (c
->head
->next
== c
->first
) {
406 struct pullup_field
*f
= calloc(1, sizeof(struct pullup_field
));
415 void pullup_submit_field(struct pullup_context
*c
, struct pullup_buffer
*b
, int parity
)
417 struct pullup_field
*f
;
419 /* Grow the circular list if needed */
420 check_field_queue(c
);
422 /* Cannot have two fields of same parity in a row; drop the new one */
423 if (c
->last
&& c
->last
->parity
== parity
) return;
427 f
->buffer
= pullup_lock_buffer(b
, parity
);
432 compute_metric(c
, f
, parity
, f
->prev
->prev
, parity
, c
->diff
, f
->diffs
);
433 compute_metric(c
, parity
?f
->prev
:f
, 0, parity
?f
:f
->prev
, 1, c
->comb
, f
->comb
);
434 compute_metric(c
, f
, parity
, f
, -1, c
->var
, f
->var
);
436 /* Advance the circular list */
437 if (!c
->first
) c
->first
= c
->head
;
439 c
->head
= c
->head
->next
;
442 void pullup_flush_fields(struct pullup_context
*c
)
444 struct pullup_field
*f
;
446 for (f
= c
->first
; f
&& f
!= c
->head
; f
= f
->next
) {
447 pullup_release_buffer(f
->buffer
, f
->parity
);
450 c
->first
= c
->last
= 0;
460 #define F_HAVE_BREAKS 1
461 #define F_HAVE_AFFINITY 2
465 #define BREAK_RIGHT 2
470 static int queue_length(struct pullup_field
*begin
, struct pullup_field
*end
)
473 struct pullup_field
*f
;
475 if (!begin
|| !end
) return 0;
476 for (f
= begin
; f
!= end
; f
= f
->next
) count
++;
480 static int find_first_break(struct pullup_field
*f
, int max
)
483 for (i
= 0; i
< max
; i
++) {
484 if (f
->breaks
& BREAK_RIGHT
|| f
->next
->breaks
& BREAK_LEFT
)
491 static void compute_breaks(struct pullup_context
*c
, struct pullup_field
*f0
)
494 struct pullup_field
*f1
= f0
->next
;
495 struct pullup_field
*f2
= f1
->next
;
496 struct pullup_field
*f3
= f2
->next
;
497 int l
, max_l
=0, max_r
=0;
498 //struct pullup_field *ff;
499 //for (i=0, ff=c->first; ff != f0; i++, ff=ff->next);
501 if (f0
->flags
& F_HAVE_BREAKS
) return;
502 //printf("\n%d: ", i);
503 f0
->flags
|= F_HAVE_BREAKS
;
505 /* Special case when fields are 100% identical */
506 if (f0
->buffer
== f2
->buffer
&& f1
->buffer
!= f3
->buffer
) {
507 f2
->breaks
|= BREAK_RIGHT
;
510 if (f0
->buffer
!= f2
->buffer
&& f1
->buffer
== f3
->buffer
) {
511 f1
->breaks
|= BREAK_LEFT
;
515 for (i
= 0; i
< c
->metric_len
; i
++) {
516 l
= f2
->diffs
[i
] - f3
->diffs
[i
];
517 if (l
> max_l
) max_l
= l
;
518 if (-l
> max_r
) max_r
= -l
;
520 /* Don't get tripped up when differences are mostly quant error */
521 //printf("%d %d\n", max_l, max_r);
522 if (max_l
+ max_r
< 128) return;
523 if (max_l
> 4*max_r
) f1
->breaks
|= BREAK_LEFT
;
524 if (max_r
> 4*max_l
) f2
->breaks
|= BREAK_RIGHT
;
527 static void compute_affinity(struct pullup_context
*c
, struct pullup_field
*f
)
530 int max_l
=0, max_r
=0, l
;
531 if (f
->flags
& F_HAVE_AFFINITY
) return;
532 f
->flags
|= F_HAVE_AFFINITY
;
533 if (f
->buffer
== f
->next
->next
->buffer
) {
535 f
->next
->affinity
= 0;
536 f
->next
->next
->affinity
= -1;
537 f
->next
->flags
|= F_HAVE_AFFINITY
;
538 f
->next
->next
->flags
|= F_HAVE_AFFINITY
;
542 for (i
= 0; i
< c
->metric_len
; i
++) {
543 int lv
= f
->prev
->var
[i
];
544 int rv
= f
->next
->var
[i
];
546 int lc
= f
->comb
[i
] - (v
+lv
) + ABS(v
-lv
);
547 int rc
= f
->next
->comb
[i
] - (v
+rv
) + ABS(v
-rv
);
551 if (l
> max_l
) max_l
= l
;
552 if (-l
> max_r
) max_r
= -l
;
554 if (max_l
+ max_r
< 64) return;
555 if (max_r
> 6*max_l
) f
->affinity
= -1;
556 else if (max_l
> 6*max_r
) f
->affinity
= 1;
558 for (i
= 0; i
< c
->metric_len
; i
++) {
559 l
= f
->comb
[i
] - f
->next
->comb
[i
];
560 if (l
> max_l
) max_l
= l
;
561 if (-l
> max_r
) max_r
= -l
;
563 if (max_l
+ max_r
< 64) return;
564 if (max_r
> 2*max_l
) f
->affinity
= -1;
565 else if (max_l
> 2*max_r
) f
->affinity
= 1;
569 static void foo(struct pullup_context
*c
)
571 struct pullup_field
*f
= c
->first
;
572 int i
, n
= queue_length(f
, c
->last
);
573 for (i
= 0; i
< n
-1; i
++) {
574 if (i
< n
-3) compute_breaks(c
, f
);
575 compute_affinity(c
, f
);
580 static int decide_frame_length(struct pullup_context
*c
)
582 struct pullup_field
*f0
= c
->first
;
583 struct pullup_field
*f1
= f0
->next
;
584 struct pullup_field
*f2
= f1
->next
;
587 if (queue_length(c
->first
, c
->last
) < 4) return 0;
590 if (f0
->affinity
== -1) return 1;
592 l
= find_first_break(f0
, 3);
593 if (l
== 1 && c
->strict_breaks
< 0) l
= 0;
597 if (c
->strict_breaks
< 1 && f0
->affinity
== 1 && f1
->affinity
== -1)
601 /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
603 && (f0
->prev
->breaks
& BREAK_RIGHT
) && (f2
->breaks
& BREAK_LEFT
)
604 && (f0
->affinity
!= 1 || f1
->affinity
!= -1) )
606 if (f1
->affinity
== 1) return 1;
609 if (f2
->affinity
== 1) return 2;
612 /* 9 possibilities covered before switch */
613 if (f1
->affinity
== 1) return 1; /* covers 6 */
614 else if (f1
->affinity
== -1) return 2; /* covers 6 */
615 else if (f2
->affinity
== -1) { /* covers 2 */
616 if (f0
->affinity
== 1) return 3;
619 else return 2; /* the remaining 6 */
624 static void print_aff_and_breaks(struct pullup_context
*c
, struct pullup_field
*f
)
627 struct pullup_field
*f0
= f
;
628 const char aff_l
[] = "+..", aff_r
[] = "..+";
629 printf("\naffinity: ");
630 for (i
= 0; i
< 4; i
++) {
631 printf("%c%d%c", aff_l
[1+f
->affinity
], i
, aff_r
[1+f
->affinity
]);
635 printf("\nbreaks: ");
636 for (i
=0; i
<4; i
++) {
637 printf("%c%d%c", f
->breaks
& BREAK_LEFT
? '|' : '.', i
, f
->breaks
& BREAK_RIGHT
? '|' : '.');
647 struct pullup_frame
*pullup_get_frame(struct pullup_context
*c
)
650 struct pullup_frame
*fr
= c
->frame
;
651 int n
= decide_frame_length(c
);
652 int aff
= c
->first
->next
->affinity
;
655 if (fr
->lock
) return 0;
658 print_aff_and_breaks(c
, c
->first
);
659 printf("duration: %d \n", n
);
664 fr
->parity
= c
->first
->parity
;
666 for (i
= 0; i
< n
; i
++) {
667 /* We cheat and steal the buffer without release+relock */
668 fr
->ifields
[i
] = c
->first
->buffer
;
669 c
->first
->buffer
= 0;
670 c
->first
= c
->first
->next
;
674 fr
->ofields
[fr
->parity
] = fr
->ifields
[0];
675 fr
->ofields
[fr
->parity
^1] = 0;
677 fr
->ofields
[fr
->parity
] = fr
->ifields
[0];
678 fr
->ofields
[fr
->parity
^1] = fr
->ifields
[1];
681 aff
= (fr
->ifields
[0] == fr
->ifields
[1]) ? -1 : 1;
682 /* else if (c->verbose) printf("forced aff: %d \n", aff); */
683 fr
->ofields
[fr
->parity
] = fr
->ifields
[1+aff
];
684 fr
->ofields
[fr
->parity
^1] = fr
->ifields
[1];
686 pullup_lock_buffer(fr
->ofields
[0], 0);
687 pullup_lock_buffer(fr
->ofields
[1], 1);
689 if (fr
->ofields
[0] == fr
->ofields
[1]) {
690 fr
->buffer
= fr
->ofields
[0];
691 pullup_lock_buffer(fr
->buffer
, 2);
697 static void copy_field(struct pullup_context
*c
, struct pullup_buffer
*dest
,
698 struct pullup_buffer
*src
, int parity
)
701 unsigned char *d
, *s
;
702 for (i
= 0; i
< c
->nplanes
; i
++) {
703 s
= src
->planes
[i
] + parity
*c
->stride
[i
];
704 d
= dest
->planes
[i
] + parity
*c
->stride
[i
];
705 for (j
= c
->h
[i
]>>1; j
; j
--) {
706 memcpy(d
, s
, c
->stride
[i
]);
707 s
+= c
->stride
[i
]<<1;
708 d
+= c
->stride
[i
]<<1;
713 void pullup_pack_frame(struct pullup_context
*c
, struct pullup_frame
*fr
)
716 if (fr
->buffer
) return;
717 if (fr
->length
< 2) return; /* FIXME: deal with this */
718 for (i
= 0; i
< 2; i
++)
720 if (fr
->ofields
[i
]->lock
[i
^1]) continue;
721 fr
->buffer
= fr
->ofields
[i
];
722 pullup_lock_buffer(fr
->buffer
, 2);
723 copy_field(c
, fr
->buffer
, fr
->ofields
[i
^1], i
^1);
726 fr
->buffer
= pullup_get_buffer(c
, 2);
727 copy_field(c
, fr
->buffer
, fr
->ofields
[0], 0);
728 copy_field(c
, fr
->buffer
, fr
->ofields
[1], 1);
731 void pullup_release_frame(struct pullup_frame
*fr
)
734 for (i
= 0; i
< fr
->length
; i
++)
735 pullup_release_buffer(fr
->ifields
[i
], fr
->parity
^ (i
&1));
736 pullup_release_buffer(fr
->ofields
[0], 0);
737 pullup_release_buffer(fr
->ofields
[1], 1);
738 if (fr
->buffer
) pullup_release_buffer(fr
->buffer
, 2);
747 struct pullup_context
*pullup_alloc_context(void)
749 struct pullup_context
*c
;
751 c
= calloc(1, sizeof(struct pullup_context
));
756 void pullup_preinit_context(struct pullup_context
*c
)
758 c
->bpp
= calloc(c
->nplanes
, sizeof(int));
759 c
->w
= calloc(c
->nplanes
, sizeof(int));
760 c
->h
= calloc(c
->nplanes
, sizeof(int));
761 c
->stride
= calloc(c
->nplanes
, sizeof(int));
762 c
->background
= calloc(c
->nplanes
, sizeof(int));
765 void pullup_init_context(struct pullup_context
*c
)
767 int mp
= c
->metric_plane
;
768 if (c
->nbuffers
< 10) c
->nbuffers
= 10;
769 c
->buffers
= calloc(c
->nbuffers
, sizeof (struct pullup_buffer
));
771 c
->metric_w
= (c
->w
[mp
] - ((c
->junk_left
+ c
->junk_right
) << 3)) >> 3;
772 c
->metric_h
= (c
->h
[mp
] - ((c
->junk_top
+ c
->junk_bottom
) << 1)) >> 3;
773 c
->metric_offset
= c
->junk_left
*c
->bpp
[mp
] + (c
->junk_top
<<1)*c
->stride
[mp
];
774 c
->metric_len
= c
->metric_w
* c
->metric_h
;
776 c
->head
= make_field_queue(c
, 8);
778 c
->frame
= calloc(1, sizeof (struct pullup_frame
));
779 c
->frame
->ifields
= calloc(3, sizeof (struct pullup_buffer
*));
788 if (c
->cpu
& PULLUP_CPU_MMX
) {
789 c
->diff
= diff_y_mmx
;
790 c
->comb
= licomb_y_mmx
;
795 /* c->comb = qpcomb_y; */
798 case PULLUP_FMT_YUY2
:
801 case PULLUP_FMT_RGB32
:
802 c
->diff
= diff_rgb32
;
808 void pullup_free_context(struct pullup_context
*c
)
810 struct pullup_field
*f
;
819 } while (f
!= c
->head
);