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"
31 static int diff_y_mmx(unsigned char *a
, unsigned char *b
, int s
)
36 "pxor %%mm4, %%mm4 \n\t"
37 "pxor %%mm7, %%mm7 \n\t"
41 "movq (%%"REG_S
"), %%mm0 \n\t"
42 "movq (%%"REG_S
"), %%mm2 \n\t"
43 "add %%"REG_a
", %%"REG_S
" \n\t"
44 "movq (%%"REG_D
"), %%mm1 \n\t"
45 "add %%"REG_a
", %%"REG_D
" \n\t"
46 "psubusb %%mm1, %%mm2 \n\t"
47 "psubusb %%mm0, %%mm1 \n\t"
48 "movq %%mm2, %%mm0 \n\t"
49 "movq %%mm1, %%mm3 \n\t"
50 "punpcklbw %%mm7, %%mm0 \n\t"
51 "punpcklbw %%mm7, %%mm1 \n\t"
52 "punpckhbw %%mm7, %%mm2 \n\t"
53 "punpckhbw %%mm7, %%mm3 \n\t"
54 "paddw %%mm0, %%mm4 \n\t"
55 "paddw %%mm1, %%mm4 \n\t"
56 "paddw %%mm2, %%mm4 \n\t"
57 "paddw %%mm3, %%mm4 \n\t"
62 "movq %%mm4, %%mm3 \n\t"
63 "punpcklwd %%mm7, %%mm4 \n\t"
64 "punpckhwd %%mm7, %%mm3 \n\t"
65 "paddd %%mm4, %%mm3 \n\t"
66 "movd %%mm3, %%eax \n\t"
67 "psrlq $32, %%mm3 \n\t"
68 "movd %%mm3, %%edx \n\t"
69 "addl %%edx, %%eax \n\t"
72 : "S" (a
), "D" (b
), "a" (s
)
78 static int licomb_y_mmx(unsigned char *a
, unsigned char *b
, int s
)
83 "pxor %%mm6, %%mm6 \n\t"
84 "pxor %%mm7, %%mm7 \n\t"
85 "sub %%"REG_a
", %%"REG_D
" \n\t"
89 "movq (%%"REG_D
"), %%mm0 \n\t"
90 "movq (%%"REG_D
"), %%mm1 \n\t"
91 "punpcklbw %%mm7, %%mm0 \n\t"
92 "movq (%%"REG_D
",%%"REG_a
"), %%mm2 \n\t"
93 "punpcklbw %%mm7, %%mm1 \n\t"
94 "punpcklbw %%mm7, %%mm2 \n\t"
95 "paddw %%mm0, %%mm0 \n\t"
96 "paddw %%mm2, %%mm1 \n\t"
97 "movq %%mm0, %%mm2 \n\t"
98 "psubusw %%mm1, %%mm0 \n\t"
99 "psubusw %%mm2, %%mm1 \n\t"
100 "paddw %%mm0, %%mm6 \n\t"
101 "paddw %%mm1, %%mm6 \n\t"
103 "movq (%%"REG_S
"), %%mm0 \n\t"
104 "movq (%%"REG_D
"), %%mm1 \n\t"
105 "punpckhbw %%mm7, %%mm0 \n\t"
106 "movq (%%"REG_D
",%%"REG_a
"), %%mm2 \n\t"
107 "punpckhbw %%mm7, %%mm1 \n\t"
108 "punpckhbw %%mm7, %%mm2 \n\t"
109 "paddw %%mm0, %%mm0 \n\t"
110 "paddw %%mm2, %%mm1 \n\t"
111 "movq %%mm0, %%mm2 \n\t"
112 "psubusw %%mm1, %%mm0 \n\t"
113 "psubusw %%mm2, %%mm1 \n\t"
114 "paddw %%mm0, %%mm6 \n\t"
115 "paddw %%mm1, %%mm6 \n\t"
117 "movq (%%"REG_D
",%%"REG_a
"), %%mm0 \n\t"
118 "movq (%%"REG_S
"), %%mm1 \n\t"
119 "punpcklbw %%mm7, %%mm0 \n\t"
120 "movq (%%"REG_S
",%%"REG_a
"), %%mm2 \n\t"
121 "punpcklbw %%mm7, %%mm1 \n\t"
122 "punpcklbw %%mm7, %%mm2 \n\t"
123 "paddw %%mm0, %%mm0 \n\t"
124 "paddw %%mm2, %%mm1 \n\t"
125 "movq %%mm0, %%mm2 \n\t"
126 "psubusw %%mm1, %%mm0 \n\t"
127 "psubusw %%mm2, %%mm1 \n\t"
128 "paddw %%mm0, %%mm6 \n\t"
129 "paddw %%mm1, %%mm6 \n\t"
131 "movq (%%"REG_D
",%%"REG_a
"), %%mm0 \n\t"
132 "movq (%%"REG_S
"), %%mm1 \n\t"
133 "punpckhbw %%mm7, %%mm0 \n\t"
134 "movq (%%"REG_S
",%%"REG_a
"), %%mm2 \n\t"
135 "punpckhbw %%mm7, %%mm1 \n\t"
136 "punpckhbw %%mm7, %%mm2 \n\t"
137 "paddw %%mm0, %%mm0 \n\t"
138 "paddw %%mm2, %%mm1 \n\t"
139 "movq %%mm0, %%mm2 \n\t"
140 "psubusw %%mm1, %%mm0 \n\t"
141 "psubusw %%mm2, %%mm1 \n\t"
142 "paddw %%mm0, %%mm6 \n\t"
143 "paddw %%mm1, %%mm6 \n\t"
145 "add %%"REG_a
", %%"REG_S
" \n\t"
146 "add %%"REG_a
", %%"REG_D
" \n\t"
150 "movq %%mm6, %%mm5 \n\t"
151 "punpcklwd %%mm7, %%mm6 \n\t"
152 "punpckhwd %%mm7, %%mm5 \n\t"
153 "paddd %%mm6, %%mm5 \n\t"
154 "movd %%mm5, %%eax \n\t"
155 "psrlq $32, %%mm5 \n\t"
156 "movd %%mm5, %%edx \n\t"
157 "addl %%edx, %%eax \n\t"
161 : "S" (a
), "D" (b
), "a" (s
)
167 static int var_y_mmx(unsigned char *a
, unsigned char *b
, int s
)
171 "movl $3, %%ecx \n\t"
172 "pxor %%mm4, %%mm4 \n\t"
173 "pxor %%mm7, %%mm7 \n\t"
177 "movq (%%"REG_S
"), %%mm0 \n\t"
178 "movq (%%"REG_S
"), %%mm2 \n\t"
179 "movq (%%"REG_S
",%%"REG_a
"), %%mm1 \n\t"
180 "add %%"REG_a
", %%"REG_S
" \n\t"
181 "psubusb %%mm1, %%mm2 \n\t"
182 "psubusb %%mm0, %%mm1 \n\t"
183 "movq %%mm2, %%mm0 \n\t"
184 "movq %%mm1, %%mm3 \n\t"
185 "punpcklbw %%mm7, %%mm0 \n\t"
186 "punpcklbw %%mm7, %%mm1 \n\t"
187 "punpckhbw %%mm7, %%mm2 \n\t"
188 "punpckhbw %%mm7, %%mm3 \n\t"
189 "paddw %%mm0, %%mm4 \n\t"
190 "paddw %%mm1, %%mm4 \n\t"
191 "paddw %%mm2, %%mm4 \n\t"
192 "paddw %%mm3, %%mm4 \n\t"
197 "movq %%mm4, %%mm3 \n\t"
198 "punpcklwd %%mm7, %%mm4 \n\t"
199 "punpckhwd %%mm7, %%mm3 \n\t"
200 "paddd %%mm4, %%mm3 \n\t"
201 "movd %%mm3, %%eax \n\t"
202 "psrlq $32, %%mm3 \n\t"
203 "movd %%mm3, %%edx \n\t"
204 "addl %%edx, %%eax \n\t"
215 #define ABS(a) (((a)^((a)>>31))-((a)>>31))
217 static int diff_y(unsigned char *a
, unsigned char *b
, int s
)
221 for (j
=0; j
<8; j
++) diff
+= ABS(a
[j
]-b
[j
]);
227 static int licomb_y(unsigned char *a
, unsigned char *b
, int s
)
232 diff
+= ABS((a
[j
]<<1) - b
[j
-s
] - b
[j
])
233 + ABS((b
[j
]<<1) - a
[j
] - a
[j
+s
]);
240 static int qpcomb_y(unsigned char *a
, unsigned char *b
, int s
)
245 diff
+= ABS(a
[j
] - 3*b
[j
-s
] + 3*a
[j
+s
] - b
[j
]);
251 static int licomb_y_test(unsigned char *a
, unsigned char *b
, int s
)
253 int c
= licomb_y(a
,b
,s
);
254 int m
= licomb_y_mmx(a
,b
,s
);
255 if (c
!= m
) printf("%d != %d\n", c
, m
);
260 static int var_y(unsigned char *a
, unsigned char *b
, int s
)
264 for (j
=0; j
<8; j
++) {
265 var
+= ABS(a
[j
]-a
[j
+s
]);
269 return 4*var
; /* match comb scaling */
280 static void alloc_buffer(struct pullup_context
*c
, struct pullup_buffer
*b
)
283 if (b
->planes
) return;
284 b
->planes
= calloc(c
->nplanes
, sizeof(unsigned char *));
285 for (i
= 0; i
< c
->nplanes
; i
++) {
286 b
->planes
[i
] = malloc(c
->h
[i
]*c
->stride
[i
]);
287 /* Deal with idiotic 128=0 for chroma: */
288 memset(b
->planes
[i
], c
->background
[i
], c
->h
[i
]*c
->stride
[i
]);
292 struct pullup_buffer
*pullup_lock_buffer(struct pullup_buffer
*b
, int parity
)
295 if ((parity
+1) & 1) b
->lock
[0]++;
296 if ((parity
+1) & 2) b
->lock
[1]++;
300 void pullup_release_buffer(struct pullup_buffer
*b
, int parity
)
303 if ((parity
+1) & 1) b
->lock
[0]--;
304 if ((parity
+1) & 2) b
->lock
[1]--;
307 struct pullup_buffer
*pullup_get_buffer(struct pullup_context
*c
, int parity
)
311 /* Try first to get the sister buffer for the previous field */
312 if (parity
< 2 && c
->last
&& parity
!= c
->last
->parity
313 && !c
->last
->buffer
->lock
[parity
]) {
314 alloc_buffer(c
, c
->last
->buffer
);
315 return pullup_lock_buffer(c
->last
->buffer
, parity
);
318 /* Prefer a buffer with both fields open */
319 for (i
= 0; i
< c
->nbuffers
; i
++) {
320 if (c
->buffers
[i
].lock
[0]) continue;
321 if (c
->buffers
[i
].lock
[1]) continue;
322 alloc_buffer(c
, &c
->buffers
[i
]);
323 return pullup_lock_buffer(&c
->buffers
[i
], parity
);
326 if (parity
== 2) return 0;
328 /* Search for any half-free buffer */
329 for (i
= 0; i
< c
->nbuffers
; i
++) {
330 if (((parity
+1) & 1) && c
->buffers
[i
].lock
[0]) continue;
331 if (((parity
+1) & 2) && c
->buffers
[i
].lock
[1]) continue;
332 alloc_buffer(c
, &c
->buffers
[i
]);
333 return pullup_lock_buffer(&c
->buffers
[i
], parity
);
344 static void compute_metric(struct pullup_context
*c
,
345 struct pullup_field
*fa
, int pa
,
346 struct pullup_field
*fb
, int pb
,
347 int (*func
)(unsigned char *, unsigned char *, int), int *dest
)
349 unsigned char *a
, *b
;
351 int mp
= c
->metric_plane
;
352 int xstep
= c
->bpp
[mp
];
353 int ystep
= c
->stride
[mp
]<<3;
354 int s
= c
->stride
[mp
]<<1; /* field stride */
355 int w
= c
->metric_w
*xstep
;
357 if (!fa
->buffer
|| !fb
->buffer
) return;
359 /* Shortcut for duplicate fields (e.g. from RFF flag) */
360 if (fa
->buffer
== fb
->buffer
&& pa
== pb
) {
361 memset(dest
, 0, c
->metric_len
* sizeof(int));
365 a
= fa
->buffer
->planes
[mp
] + pa
* c
->stride
[mp
] + c
->metric_offset
;
366 b
= fb
->buffer
->planes
[mp
] + pb
* c
->stride
[mp
] + c
->metric_offset
;
368 for (y
= c
->metric_h
; y
; y
--) {
369 for (x
= 0; x
< w
; x
+= xstep
) {
370 *dest
++ = func(a
+ x
, b
+ x
, s
);
372 a
+= ystep
; b
+= ystep
;
380 static void alloc_metrics(struct pullup_context
*c
, struct pullup_field
*f
)
382 f
->diffs
= calloc(c
->metric_len
, sizeof(int));
383 f
->comb
= calloc(c
->metric_len
, sizeof(int));
384 f
->var
= calloc(c
->metric_len
, sizeof(int));
385 /* add more metrics here as needed */
388 static struct pullup_field
*make_field_queue(struct pullup_context
*c
, int len
)
390 struct pullup_field
*head
, *f
;
391 f
= head
= calloc(1, sizeof(struct pullup_field
));
393 for (; len
> 0; len
--) {
394 f
->next
= calloc(1, sizeof(struct pullup_field
));
404 static void check_field_queue(struct pullup_context
*c
)
406 if (c
->head
->next
== c
->first
) {
407 struct pullup_field
*f
= calloc(1, sizeof(struct pullup_field
));
416 void pullup_submit_field(struct pullup_context
*c
, struct pullup_buffer
*b
,
417 int parity
, double pts
)
419 struct pullup_field
*f
;
421 /* Grow the circular list if needed */
422 check_field_queue(c
);
424 /* Cannot have two fields of same parity in a row; drop the new one */
425 if (c
->last
&& c
->last
->parity
== parity
) return;
429 f
->buffer
= pullup_lock_buffer(b
, parity
);
435 compute_metric(c
, f
, parity
, f
->prev
->prev
, parity
, c
->diff
, f
->diffs
);
436 compute_metric(c
, parity
?f
->prev
:f
, 0, parity
?f
:f
->prev
, 1, c
->comb
, f
->comb
);
437 compute_metric(c
, f
, parity
, f
, -1, c
->var
, f
->var
);
439 /* Advance the circular list */
440 if (!c
->first
) c
->first
= c
->head
;
442 c
->head
= c
->head
->next
;
445 void pullup_flush_fields(struct pullup_context
*c
)
447 struct pullup_field
*f
;
449 for (f
= c
->first
; f
&& f
!= c
->head
; f
= f
->next
) {
450 pullup_release_buffer(f
->buffer
, f
->parity
);
453 c
->first
= c
->last
= 0;
463 #define F_HAVE_BREAKS 1
464 #define F_HAVE_AFFINITY 2
468 #define BREAK_RIGHT 2
473 static int queue_length(struct pullup_field
*begin
, struct pullup_field
*end
)
476 struct pullup_field
*f
;
478 if (!begin
|| !end
) return 0;
479 for (f
= begin
; f
!= end
; f
= f
->next
) count
++;
483 static int find_first_break(struct pullup_field
*f
, int max
)
486 for (i
= 0; i
< max
; i
++) {
487 if (f
->breaks
& BREAK_RIGHT
|| f
->next
->breaks
& BREAK_LEFT
)
494 static void compute_breaks(struct pullup_context
*c
, struct pullup_field
*f0
)
497 struct pullup_field
*f1
= f0
->next
;
498 struct pullup_field
*f2
= f1
->next
;
499 struct pullup_field
*f3
= f2
->next
;
500 int l
, max_l
=0, max_r
=0;
501 //struct pullup_field *ff;
502 //for (i=0, ff=c->first; ff != f0; i++, ff=ff->next);
504 if (f0
->flags
& F_HAVE_BREAKS
) return;
505 //printf("\n%d: ", i);
506 f0
->flags
|= F_HAVE_BREAKS
;
508 /* Special case when fields are 100% identical */
509 if (f0
->buffer
== f2
->buffer
&& f1
->buffer
!= f3
->buffer
) {
510 f2
->breaks
|= BREAK_RIGHT
;
513 if (f0
->buffer
!= f2
->buffer
&& f1
->buffer
== f3
->buffer
) {
514 f1
->breaks
|= BREAK_LEFT
;
518 for (i
= 0; i
< c
->metric_len
; i
++) {
519 l
= f2
->diffs
[i
] - f3
->diffs
[i
];
520 if (l
> max_l
) max_l
= l
;
521 if (-l
> max_r
) max_r
= -l
;
523 /* Don't get tripped up when differences are mostly quant error */
524 //printf("%d %d\n", max_l, max_r);
525 if (max_l
+ max_r
< 128) return;
526 if (max_l
> 4*max_r
) f1
->breaks
|= BREAK_LEFT
;
527 if (max_r
> 4*max_l
) f2
->breaks
|= BREAK_RIGHT
;
530 static void compute_affinity(struct pullup_context
*c
, struct pullup_field
*f
)
533 int max_l
=0, max_r
=0, l
;
534 if (f
->flags
& F_HAVE_AFFINITY
) return;
535 f
->flags
|= F_HAVE_AFFINITY
;
536 if (f
->buffer
== f
->next
->next
->buffer
) {
538 f
->next
->affinity
= 0;
539 f
->next
->next
->affinity
= -1;
540 f
->next
->flags
|= F_HAVE_AFFINITY
;
541 f
->next
->next
->flags
|= F_HAVE_AFFINITY
;
545 for (i
= 0; i
< c
->metric_len
; i
++) {
546 int lv
= f
->prev
->var
[i
];
547 int rv
= f
->next
->var
[i
];
549 int lc
= f
->comb
[i
] - (v
+lv
) + ABS(v
-lv
);
550 int rc
= f
->next
->comb
[i
] - (v
+rv
) + ABS(v
-rv
);
554 if (l
> max_l
) max_l
= l
;
555 if (-l
> max_r
) max_r
= -l
;
557 if (max_l
+ max_r
< 64) return;
558 if (max_r
> 6*max_l
) f
->affinity
= -1;
559 else if (max_l
> 6*max_r
) f
->affinity
= 1;
561 for (i
= 0; i
< c
->metric_len
; i
++) {
562 l
= f
->comb
[i
] - f
->next
->comb
[i
];
563 if (l
> max_l
) max_l
= l
;
564 if (-l
> max_r
) max_r
= -l
;
566 if (max_l
+ max_r
< 64) return;
567 if (max_r
> 2*max_l
) f
->affinity
= -1;
568 else if (max_l
> 2*max_r
) f
->affinity
= 1;
572 static void foo(struct pullup_context
*c
)
574 struct pullup_field
*f
= c
->first
;
575 int i
, n
= queue_length(f
, c
->last
);
576 for (i
= 0; i
< n
-1; i
++) {
577 if (i
< n
-3) compute_breaks(c
, f
);
578 compute_affinity(c
, f
);
583 static int decide_frame_length(struct pullup_context
*c
)
585 struct pullup_field
*f0
= c
->first
;
586 struct pullup_field
*f1
= f0
->next
;
587 struct pullup_field
*f2
= f1
->next
;
590 if (queue_length(c
->first
, c
->last
) < 4) return 0;
593 if (f0
->affinity
== -1) return 1;
595 l
= find_first_break(f0
, 3);
596 if (l
== 1 && c
->strict_breaks
< 0) l
= 0;
600 if (c
->strict_breaks
< 1 && f0
->affinity
== 1 && f1
->affinity
== -1)
604 /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
606 && (f0
->prev
->breaks
& BREAK_RIGHT
) && (f2
->breaks
& BREAK_LEFT
)
607 && (f0
->affinity
!= 1 || f1
->affinity
!= -1) )
609 if (f1
->affinity
== 1) return 1;
612 if (f2
->affinity
== 1) return 2;
615 /* 9 possibilities covered before switch */
616 if (f1
->affinity
== 1) return 1; /* covers 6 */
617 else if (f1
->affinity
== -1) return 2; /* covers 6 */
618 else if (f2
->affinity
== -1) { /* covers 2 */
619 if (f0
->affinity
== 1) return 3;
622 else return 2; /* the remaining 6 */
627 static void print_aff_and_breaks(struct pullup_context
*c
, struct pullup_field
*f
)
630 struct pullup_field
*f0
= f
;
631 const char aff_l
[] = "+..", aff_r
[] = "..+";
632 printf("\naffinity: ");
633 for (i
= 0; i
< 4; i
++) {
634 printf("%c%d%c", aff_l
[1+f
->affinity
], i
, aff_r
[1+f
->affinity
]);
638 printf("\nbreaks: ");
639 for (i
=0; i
<4; i
++) {
640 printf("%c%d%c", f
->breaks
& BREAK_LEFT
? '|' : '.', i
, f
->breaks
& BREAK_RIGHT
? '|' : '.');
650 struct pullup_frame
*pullup_get_frame(struct pullup_context
*c
)
653 struct pullup_frame
*fr
= c
->frame
;
654 int n
= decide_frame_length(c
);
655 int aff
= c
->first
->next
->affinity
;
658 if (fr
->lock
) return 0;
661 print_aff_and_breaks(c
, c
->first
);
662 printf("duration: %d \n", n
);
667 fr
->parity
= c
->first
->parity
;
670 for (i
= 0; i
< n
; i
++) {
671 /* We cheat and steal the buffer without release+relock */
672 fr
->ifields
[i
] = c
->first
->buffer
;
673 c
->first
->buffer
= 0;
674 if (c
->first
->pts
== MP_NOPTS_VALUE
|| fr
->pts
== MP_NOPTS_VALUE
)
675 fr
->pts
= MP_NOPTS_VALUE
;
677 fr
->pts
+= c
->first
->pts
;
678 c
->first
= c
->first
->next
;
680 if (fr
->pts
!= MP_NOPTS_VALUE
)
684 fr
->ofields
[fr
->parity
] = fr
->ifields
[0];
685 fr
->ofields
[fr
->parity
^1] = 0;
687 fr
->ofields
[fr
->parity
] = fr
->ifields
[0];
688 fr
->ofields
[fr
->parity
^1] = fr
->ifields
[1];
691 aff
= (fr
->ifields
[0] == fr
->ifields
[1]) ? -1 : 1;
692 /* else if (c->verbose) printf("forced aff: %d \n", aff); */
693 fr
->ofields
[fr
->parity
] = fr
->ifields
[1+aff
];
694 fr
->ofields
[fr
->parity
^1] = fr
->ifields
[1];
696 pullup_lock_buffer(fr
->ofields
[0], 0);
697 pullup_lock_buffer(fr
->ofields
[1], 1);
699 if (fr
->ofields
[0] == fr
->ofields
[1]) {
700 fr
->buffer
= fr
->ofields
[0];
701 pullup_lock_buffer(fr
->buffer
, 2);
707 static void copy_field(struct pullup_context
*c
, struct pullup_buffer
*dest
,
708 struct pullup_buffer
*src
, int parity
)
711 unsigned char *d
, *s
;
712 for (i
= 0; i
< c
->nplanes
; i
++) {
713 s
= src
->planes
[i
] + parity
*c
->stride
[i
];
714 d
= dest
->planes
[i
] + parity
*c
->stride
[i
];
715 for (j
= c
->h
[i
]>>1; j
; j
--) {
716 memcpy(d
, s
, c
->stride
[i
]);
717 s
+= c
->stride
[i
]<<1;
718 d
+= c
->stride
[i
]<<1;
723 void pullup_pack_frame(struct pullup_context
*c
, struct pullup_frame
*fr
)
726 if (fr
->buffer
) return;
727 if (fr
->length
< 2) return; /* FIXME: deal with this */
728 for (i
= 0; i
< 2; i
++)
730 if (fr
->ofields
[i
]->lock
[i
^1]) continue;
731 fr
->buffer
= fr
->ofields
[i
];
732 pullup_lock_buffer(fr
->buffer
, 2);
733 copy_field(c
, fr
->buffer
, fr
->ofields
[i
^1], i
^1);
736 fr
->buffer
= pullup_get_buffer(c
, 2);
737 copy_field(c
, fr
->buffer
, fr
->ofields
[0], 0);
738 copy_field(c
, fr
->buffer
, fr
->ofields
[1], 1);
741 void pullup_release_frame(struct pullup_frame
*fr
)
744 for (i
= 0; i
< fr
->length
; i
++)
745 pullup_release_buffer(fr
->ifields
[i
], fr
->parity
^ (i
&1));
746 pullup_release_buffer(fr
->ofields
[0], 0);
747 pullup_release_buffer(fr
->ofields
[1], 1);
748 if (fr
->buffer
) pullup_release_buffer(fr
->buffer
, 2);
757 struct pullup_context
*pullup_alloc_context(void)
759 struct pullup_context
*c
;
761 c
= calloc(1, sizeof(struct pullup_context
));
766 void pullup_preinit_context(struct pullup_context
*c
)
768 c
->bpp
= calloc(c
->nplanes
, sizeof(int));
769 c
->w
= calloc(c
->nplanes
, sizeof(int));
770 c
->h
= calloc(c
->nplanes
, sizeof(int));
771 c
->stride
= calloc(c
->nplanes
, sizeof(int));
772 c
->background
= calloc(c
->nplanes
, sizeof(int));
775 void pullup_init_context(struct pullup_context
*c
)
777 int mp
= c
->metric_plane
;
778 if (c
->nbuffers
< 10) c
->nbuffers
= 10;
779 c
->buffers
= calloc(c
->nbuffers
, sizeof (struct pullup_buffer
));
781 c
->metric_w
= (c
->w
[mp
] - ((c
->junk_left
+ c
->junk_right
) << 3)) >> 3;
782 c
->metric_h
= (c
->h
[mp
] - ((c
->junk_top
+ c
->junk_bottom
) << 1)) >> 3;
783 c
->metric_offset
= c
->junk_left
*c
->bpp
[mp
] + (c
->junk_top
<<1)*c
->stride
[mp
];
784 c
->metric_len
= c
->metric_w
* c
->metric_h
;
786 c
->head
= make_field_queue(c
, 8);
788 c
->frame
= calloc(1, sizeof (struct pullup_frame
));
789 c
->frame
->ifields
= calloc(3, sizeof (struct pullup_buffer
*));
798 if (c
->cpu
& PULLUP_CPU_MMX
) {
799 c
->diff
= diff_y_mmx
;
800 c
->comb
= licomb_y_mmx
;
805 /* c->comb = qpcomb_y; */
808 case PULLUP_FMT_YUY2
:
811 case PULLUP_FMT_RGB32
:
812 c
->diff
= diff_rgb32
;
818 void pullup_free_context(struct pullup_context
*c
)
820 struct pullup_field
*f
;
829 } while (f
!= c
->head
);