1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5
6 #define SCHRO_ENABLE_UNSTABLE_API 1
7
8 #include "schrovirtframe.h"
9 #include <schroedinger/schro.h>
10 #include <schroedinger/schroutils.h>
11 #include <string.h>
12 #include <math.h>
13 #include <orc/orc.h>
14
15 #include <schroedinger/schroorc.h>
16
17
18 SchroFrame *
schro_frame_new_virtual(SchroMemoryDomain * domain,SchroFrameFormat format,int width,int height)19 schro_frame_new_virtual (SchroMemoryDomain * domain, SchroFrameFormat format,
20 int width, int height)
21 {
22 SchroFrame *frame = schro_frame_new ();
23 int bytes_pp;
24 int h_shift, v_shift;
25 int chroma_width;
26 int chroma_height;
27 int i;
28
29 frame->format = format;
30 frame->width = width;
31 frame->height = height;
32 frame->domain = domain;
33
34 if (SCHRO_FRAME_IS_PACKED (format)) {
35 frame->components[0].format = format;
36 frame->components[0].width = width;
37 frame->components[0].height = height;
38 if (format == SCHRO_FRAME_FORMAT_AYUV) {
39 frame->components[0].stride = width * 4;
40 } else if (format == SCHRO_FRAME_FORMAT_v216) {
41 frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 4;
42 } else if (format == SCHRO_FRAME_FORMAT_v210) {
43 frame->components[0].stride = ((width + 47) / 48) * 128;
44 } else {
45 frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2;
46 }
47 frame->components[0].length = frame->components[0].stride * height;
48
49 frame->components[0].data = frame->regions[0];
50 frame->components[0].v_shift = 0;
51 frame->components[0].h_shift = 0;
52
53 frame->regions[0] =
54 malloc (frame->components[0].stride * SCHRO_FRAME_CACHE_SIZE);
55 for (i = 0; i < SCHRO_FRAME_CACHE_SIZE; i++) {
56 frame->cached_lines[0][i] = 0;
57 }
58 frame->is_virtual = TRUE;
59
60 return frame;
61 }
62
63 switch (SCHRO_FRAME_FORMAT_DEPTH (format)) {
64 case SCHRO_FRAME_FORMAT_DEPTH_U8:
65 bytes_pp = 1;
66 break;
67 case SCHRO_FRAME_FORMAT_DEPTH_S16:
68 bytes_pp = 2;
69 break;
70 case SCHRO_FRAME_FORMAT_DEPTH_S32:
71 bytes_pp = 4;
72 break;
73 default:
74 SCHRO_ASSERT (0);
75 bytes_pp = 0;
76 break;
77 }
78
79 h_shift = SCHRO_FRAME_FORMAT_H_SHIFT (format);
80 v_shift = SCHRO_FRAME_FORMAT_V_SHIFT (format);
81 chroma_width = ROUND_UP_SHIFT (width, h_shift);
82 chroma_height = ROUND_UP_SHIFT (height, v_shift);
83
84 frame->components[0].format = format;
85 frame->components[0].width = width;
86 frame->components[0].height = height;
87 frame->components[0].stride = ROUND_UP_4 (width * bytes_pp);
88 frame->components[0].length =
89 frame->components[0].stride * frame->components[0].height;
90 frame->components[0].v_shift = 0;
91 frame->components[0].h_shift = 0;
92
93 frame->components[1].format = format;
94 frame->components[1].width = chroma_width;
95 frame->components[1].height = chroma_height;
96 frame->components[1].stride = ROUND_UP_4 (chroma_width * bytes_pp);
97 frame->components[1].length =
98 frame->components[1].stride * frame->components[1].height;
99 frame->components[1].v_shift = v_shift;
100 frame->components[1].h_shift = h_shift;
101
102 frame->components[2].format = format;
103 frame->components[2].width = chroma_width;
104 frame->components[2].height = chroma_height;
105 frame->components[2].stride = ROUND_UP_4 (chroma_width * bytes_pp);
106 frame->components[2].length =
107 frame->components[2].stride * frame->components[2].height;
108 frame->components[2].v_shift = v_shift;
109 frame->components[2].h_shift = h_shift;
110
111 for (i = 0; i < 3; i++) {
112 SchroFrameData *comp = &frame->components[i];
113 int j;
114
115 frame->regions[i] = malloc (comp->stride * SCHRO_FRAME_CACHE_SIZE);
116 for (j = 0; j < SCHRO_FRAME_CACHE_SIZE; j++) {
117 frame->cached_lines[i][j] = 0;
118 }
119 }
120 frame->is_virtual = TRUE;
121
122 return frame;
123 }
124
125 static void
schro_virt_frame_prep_cache_line(SchroFrame * frame,int component,int i)126 schro_virt_frame_prep_cache_line (SchroFrame * frame, int component, int i)
127 {
128 int j;
129
130 if (i < frame->cache_offset[component]) {
131 SCHRO_ERROR ("cache failure: %d outside [%d,%d]", i,
132 frame->cache_offset[component],
133 frame->cache_offset[component] + SCHRO_FRAME_CACHE_SIZE - 1);
134
135 frame->cache_offset[component] = i;
136 for (j = 0; j < SCHRO_FRAME_CACHE_SIZE; j++) {
137 frame->cached_lines[component][j] = 0;
138 }
139 }
140
141 while (i >= frame->cache_offset[component] + SCHRO_FRAME_CACHE_SIZE) {
142 j = frame->cache_offset[component] & (SCHRO_FRAME_CACHE_SIZE - 1);
143 frame->cached_lines[component][j] = 0;
144
145 frame->cache_offset[component]++;
146 }
147 }
148
149 void *
schro_virt_frame_get_line_unrendered(SchroFrame * frame,int component,int i)150 schro_virt_frame_get_line_unrendered (SchroFrame * frame, int component, int i)
151 {
152 SchroFrameData *comp = &frame->components[component];
153 int j;
154
155 //SCHRO_ASSERT(i >= 0);
156 //SCHRO_ASSERT(i < comp->height);
157
158 if (!frame->is_virtual) {
159 return SCHRO_FRAME_DATA_GET_LINE (&frame->components[component], i);
160 }
161
162 schro_virt_frame_prep_cache_line (frame, component, i);
163 j = i & (SCHRO_FRAME_CACHE_SIZE - 1);
164
165 return SCHRO_OFFSET (frame->regions[component], comp->stride * j);
166 }
167
168 void *
schro_virt_frame_get_line(SchroFrame * frame,int component,int i)169 schro_virt_frame_get_line (SchroFrame * frame, int component, int i)
170 {
171 SchroFrameData *comp = &frame->components[component];
172 int j;
173
174 //SCHRO_ASSERT(i >= 0);
175 //SCHRO_ASSERT(i < comp->height);
176
177 if (!frame->is_virtual) {
178 return SCHRO_FRAME_DATA_GET_LINE (&frame->components[component], i);
179 }
180
181 schro_virt_frame_prep_cache_line (frame, component, i);
182 j = i & (SCHRO_FRAME_CACHE_SIZE - 1);
183
184 if (!frame->cached_lines[component][j]) {
185 schro_virt_frame_render_line (frame,
186 SCHRO_OFFSET (frame->regions[component], comp->stride * j), component,
187 i);
188 frame->cached_lines[component][j] = 1;
189 }
190
191 return SCHRO_OFFSET (frame->regions[component], comp->stride * j);
192 }
193
194 void
schro_virt_frame_set_line_rendered(SchroFrame * frame,int component,int i)195 schro_virt_frame_set_line_rendered (SchroFrame * frame, int component, int i)
196 {
197 int j;
198
199 //SCHRO_ASSERT(i >= 0);
200 //SCHRO_ASSERT(i < comp->height);
201 //SCHRO_ASSERT(frame->is_virtual);
202
203 j = i & (SCHRO_FRAME_CACHE_SIZE - 1);
204 frame->cached_lines[component][j] = 1;
205 }
206
207 void
schro_virt_frame_render_line(SchroFrame * frame,void * dest,int component,int i)208 schro_virt_frame_render_line (SchroFrame * frame, void *dest,
209 int component, int i)
210 {
211 frame->render_line (frame, dest, component, i);
212 }
213
214 static void
copy(SchroFrame * frame,void * _dest,int component,int i)215 copy (SchroFrame * frame, void *_dest, int component, int i)
216 {
217 uint8_t *dest = _dest;
218 uint8_t *src;
219
220 src = schro_virt_frame_get_line (frame, component, i);
221 switch (SCHRO_FRAME_FORMAT_DEPTH (frame->format)) {
222 case SCHRO_FRAME_FORMAT_DEPTH_U8:
223 orc_memcpy (dest, src, frame->components[component].width);
224 break;
225 case SCHRO_FRAME_FORMAT_DEPTH_S16:
226 orc_memcpy (dest, src, frame->components[component].width * sizeof(int16_t));
227 break;
228 case SCHRO_FRAME_FORMAT_DEPTH_S32:
229 orc_memcpy (dest, src, frame->components[component].width * sizeof(int32_t));
230 break;
231 default:
232 SCHRO_ASSERT (0);
233 break;
234 }
235 }
236
237 void
schro_virt_frame_render(SchroFrame * frame,SchroFrame * dest)238 schro_virt_frame_render (SchroFrame * frame, SchroFrame * dest)
239 {
240 int i, k;
241
242 SCHRO_ASSERT (frame->width == dest->width);
243 SCHRO_ASSERT (frame->height >= dest->height);
244
245 if (frame->is_virtual) {
246 for (k = 0; k < 3; k++) {
247 SchroFrameData *comp = dest->components + k;
248
249 for (i = 0; i < dest->components[k].height; i++) {
250 schro_virt_frame_render_line (frame,
251 SCHRO_FRAME_DATA_GET_LINE (comp, i), k, i);
252 }
253 }
254 } else {
255 for (k = 0; k < 3; k++) {
256 SchroFrameData *comp = dest->components + k;
257
258 for (i = 0; i < dest->components[k].height; i++) {
259 copy (frame, SCHRO_FRAME_DATA_GET_LINE (comp, i), k, i);
260 }
261 }
262 }
263 }
264
265 #ifdef unused
266 void
schro_virt_frame_render_downsample_horiz_cosite(SchroFrame * frame,void * _dest,int component,int i)267 schro_virt_frame_render_downsample_horiz_cosite (SchroFrame * frame,
268 void *_dest, int component, int i)
269 {
270 uint8_t *dest = _dest;
271 uint8_t *src;
272 int j;
273 int n_src;
274
275 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
276 n_src = frame->virt_frame1->components[component].width;
277
278 for (j = 0; j < frame->components[component].width; j++) {
279 int x = 0;
280 x += 1 * src[CLAMP (j * 2 - 1, 0, n_src - 1)];
281 x += 2 * src[CLAMP (j * 2 + 0, 0, n_src - 1)];
282 x += 1 * src[CLAMP (j * 2 + 1, 0, n_src - 1)];
283 dest[j] = CLAMP ((x + 2) >> 2, 0, 255);
284 }
285 }
286 #endif
287
288 #ifdef unused
289 void
schro_virt_frame_render_downsample_horiz_halfsite(SchroFrame * frame,void * _dest,int component,int i)290 schro_virt_frame_render_downsample_horiz_halfsite (SchroFrame * frame,
291 void *_dest, int component, int i)
292 {
293 uint8_t *dest = _dest;
294 uint8_t *src;
295 int j;
296 int n_src;
297 int taps = 4;
298 int k;
299
300 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
301 n_src = frame->virt_frame1->components[component].width;
302
303 switch (taps) {
304 case 4:
305 for (j = 0; j < frame->components[component].width; j++) {
306 int x = 0;
307 x += 6 * src[CLAMP (j * 2 - 1, 0, n_src - 1)];
308 x += 26 * src[CLAMP (j * 2 + 0, 0, n_src - 1)];
309 x += 26 * src[CLAMP (j * 2 + 1, 0, n_src - 1)];
310 x += 6 * src[CLAMP (j * 2 + 2, 0, n_src - 1)];
311 dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
312 }
313 break;
314 case 6:
315 for (j = 0; j < frame->components[component].width; j++) {
316 int x = 0;
317 x += -3 * src[CLAMP (j * 2 - 2, 0, n_src - 1)];
318 x += 8 * src[CLAMP (j * 2 - 1, 0, n_src - 1)];
319 x += 27 * src[CLAMP (j * 2 + 0, 0, n_src - 1)];
320 x += 27 * src[CLAMP (j * 2 + 1, 0, n_src - 1)];
321 x += 8 * src[CLAMP (j * 2 + 2, 0, n_src - 1)];
322 x += -3 * src[CLAMP (j * 2 + 3, 0, n_src - 1)];
323 dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
324 }
325 case 8:
326 for (j = 0; j < frame->components[component].width; j++) {
327 int x = 0;
328 const int taps8[8] = { -2, -4, 9, 29, 29, 9, -4, -2 };
329 for (k = 0; k < 8; k++) {
330 x += taps8[k] * src[CLAMP (j * 2 - 3 + k, 0, n_src - 1)];
331 }
332 dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
333 }
334 break;
335 case 10:
336 for (j = 0; j < frame->components[component].width; j++) {
337 int x = 0;
338 const int taps10[10] = { 1, -2, -5, 9, 29, 29, 9, -5, -2, 1 };
339 for (k = 0; k < 10; k++) {
340 x += taps10[k] * src[CLAMP (j * 2 - 4 + k, 0, n_src - 1)];
341 }
342 dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
343 }
344 break;
345 default:
346 break;
347 }
348 }
349 #endif
350
351 #ifdef unused
352 SchroFrame *
schro_virt_frame_new_horiz_downsample(SchroFrame * vf,int cosite)353 schro_virt_frame_new_horiz_downsample (SchroFrame * vf, int cosite)
354 {
355 SchroFrame *virt_frame;
356
357 virt_frame =
358 schro_frame_new_virtual (NULL, vf->format, vf->width / 2, vf->height);
359 virt_frame->virt_frame1 = vf;
360 if (cosite) {
361 virt_frame->render_line = schro_virt_frame_render_downsample_horiz_cosite;
362 } else {
363 virt_frame->render_line = schro_virt_frame_render_downsample_horiz_halfsite;
364 }
365
366 return virt_frame;
367 }
368 #endif
369
370 #ifdef unused
371 void
schro_virt_frame_render_downsample_vert_cosite(SchroFrame * frame,void * _dest,int component,int i)372 schro_virt_frame_render_downsample_vert_cosite (SchroFrame * frame,
373 void *_dest, int component, int i)
374 {
375 uint8_t *dest = _dest;
376 uint8_t *src1;
377 uint8_t *src2;
378 uint8_t *src3;
379 int j;
380 int n_src;
381
382 n_src = frame->virt_frame1->components[component].height;
383 src1 = schro_virt_frame_get_line (frame->virt_frame1, component,
384 CLAMP (i * 2 - 1, 0, n_src - 1));
385 src2 = schro_virt_frame_get_line (frame->virt_frame1, component,
386 CLAMP (i * 2 + 0, 0, n_src - 1));
387 src3 = schro_virt_frame_get_line (frame->virt_frame1, component,
388 CLAMP (i * 2 + 1, 0, n_src - 1));
389
390 for (j = 0; j < frame->components[component].width; j++) {
391 int x = 0;
392 x += 1 * src1[j];
393 x += 2 * src2[j];
394 x += 1 * src3[j];
395 dest[j] = CLAMP ((x + 2) >> 2, 0, 255);
396 }
397 }
398 #endif
399
400 #ifdef unused
401 void
schro_virt_frame_render_downsample_vert_halfsite(SchroFrame * frame,void * _dest,int component,int i)402 schro_virt_frame_render_downsample_vert_halfsite (SchroFrame * frame,
403 void *_dest, int component, int i)
404 {
405 uint8_t *dest = _dest;
406 uint8_t *src[10];
407 int j;
408 int n_src;
409 int taps = 4;
410 int k;
411
412 n_src = frame->virt_frame1->components[component].height;
413 for (j = 0; j < taps; j++) {
414 src[j] = schro_virt_frame_get_line (frame->virt_frame1, component,
415 CLAMP (i * 2 - (taps - 2) / 2 + j, 0, n_src - 1));
416 }
417
418 switch (taps) {
419 case 4:
420 for (j = 0; j < frame->components[component].width; j++) {
421 int x = 0;
422 x += 6 * src[0][j];
423 x += 26 * src[1][j];
424 x += 26 * src[2][j];
425 x += 6 * src[3][j];
426 dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
427 }
428 break;
429 case 6:
430 for (j = 0; j < frame->components[component].width; j++) {
431 int x = 0;
432 x += -3 * src[0][j];
433 x += 8 * src[1][j];
434 x += 27 * src[2][j];
435 x += 27 * src[3][j];
436 x += 8 * src[4][j];
437 x += -3 * src[5][j];
438 dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
439 }
440 break;
441 case 8:
442 for (j = 0; j < frame->components[component].width; j++) {
443 int x = 0;
444 const int taps8[8] = { -2, -4, 9, 29, 29, 9, -4, -2 };
445 for (k = 0; k < 8; k++) {
446 x += taps8[k] * src[k][j];
447 }
448 dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
449 }
450 break;
451 case 10:
452 for (j = 0; j < frame->components[component].width; j++) {
453 int x = 0;
454 const int taps10[10] = { 1, -2, -5, 9, 29, 29, 9, -5, -2, 1 };
455 //const int taps10[10] = { -1, 1, 6, 11, 15, 15, 11, 6, 1, -1 };
456 for (k = 0; k < 10; k++) {
457 x += taps10[k] * src[k][j];
458 }
459 dest[j] = CLAMP ((x + 32) >> 6, 0, 255);
460 }
461 break;
462 default:
463 SCHRO_ASSERT (0);
464 break;
465 }
466 }
467 #endif
468
469 #ifdef unused
470 SchroFrame *
schro_virt_frame_new_vert_downsample(SchroFrame * vf,int cosite)471 schro_virt_frame_new_vert_downsample (SchroFrame * vf, int cosite)
472 {
473 SchroFrame *virt_frame;
474
475 virt_frame =
476 schro_frame_new_virtual (NULL, vf->format, vf->width, vf->height / 2);
477 virt_frame->virt_frame1 = vf;
478 if (cosite) {
479 virt_frame->render_line = schro_virt_frame_render_downsample_vert_cosite;
480 } else {
481 virt_frame->render_line = schro_virt_frame_render_downsample_vert_halfsite;
482 }
483
484 return virt_frame;
485 }
486 #endif
487
488 #ifdef unused
489 void
get_taps(double * taps,double x)490 get_taps (double *taps, double x)
491 {
492 taps[3] = x * x * (x - 1);
493 taps[2] = x * (-x * x + x + 1);
494 x = 1 - x;
495 taps[1] = x * (-x * x + x + 1);
496 taps[0] = x * x * (x - 1);
497 }
498 #endif
499
500 #ifdef unused
501 void
schro_virt_frame_render_resample_vert(SchroFrame * frame,void * _dest,int component,int i)502 schro_virt_frame_render_resample_vert (SchroFrame * frame, void *_dest,
503 int component, int i)
504 {
505 uint8_t *dest = _dest;
506 uint8_t *src1;
507 uint8_t *src2;
508 uint8_t *src3;
509 uint8_t *src4;
510 int j;
511 int n_src;
512 double taps[4];
513 double *scale = (double *) frame->virt_priv;
514 double x;
515 int src_i;
516
517 x = (*scale) * i;
518 src_i = floor (x);
519 get_taps (taps, x - floor (x));
520
521 n_src = frame->virt_frame1->components[component].height;
522 src1 = schro_virt_frame_get_line (frame->virt_frame1, component,
523 CLAMP (src_i - 1, 0, n_src - 1));
524 src2 = schro_virt_frame_get_line (frame->virt_frame1, component,
525 CLAMP (src_i + 0, 0, n_src - 1));
526 src3 = schro_virt_frame_get_line (frame->virt_frame1, component,
527 CLAMP (src_i + 1, 0, n_src - 1));
528 src4 = schro_virt_frame_get_line (frame->virt_frame1, component,
529 CLAMP (src_i + 2, 0, n_src - 1));
530
531 for (j = 0; j < frame->components[component].width; j++) {
532 double x = 0;
533 x += taps[0] * src1[j];
534 x += taps[1] * src2[j];
535 x += taps[2] * src3[j];
536 x += taps[3] * src4[j];
537 dest[j] = CLAMP (rint (x), 0, 255);
538 }
539 }
540 #endif
541
542 #ifdef unused
543 SchroFrame *
schro_virt_frame_new_vert_resample(SchroFrame * vf,int height)544 schro_virt_frame_new_vert_resample (SchroFrame * vf, int height)
545 {
546 SchroFrame *virt_frame;
547 double *scale;
548
549 virt_frame = schro_frame_new_virtual (NULL, vf->format, vf->width, height);
550 virt_frame->virt_frame1 = vf;
551 virt_frame->render_line = schro_virt_frame_render_resample_vert;
552
553 scale = malloc (sizeof (double));
554 virt_frame->virt_priv = scale;
555
556 *scale = (double) vf->height / height;
557
558 return virt_frame;
559 }
560 #endif
561
562 #ifdef unused
563 void
schro_virt_frame_render_resample_horiz(SchroFrame * frame,void * _dest,int component,int i)564 schro_virt_frame_render_resample_horiz (SchroFrame * frame, void *_dest,
565 int component, int i)
566 {
567 uint8_t *dest = _dest;
568 uint8_t *src;
569 int j;
570 int n_src;
571 double taps[4];
572 double *scale = (double *) frame->virt_priv;
573 int src_i;
574
575 n_src = frame->virt_frame1->components[component].width;
576 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
577
578 for (j = 0; j < frame->components[component].width; j++) {
579 double x;
580 double y = 0;
581
582 x = (*scale) * j;
583 src_i = floor (x);
584 get_taps (taps, x - floor (x));
585
586 y = 0;
587 y += taps[0] * src[CLAMP (src_i - 1, 0, n_src - 1)];
588 y += taps[1] * src[CLAMP (src_i + 0, 0, n_src - 1)];
589 y += taps[2] * src[CLAMP (src_i + 1, 0, n_src - 1)];
590 y += taps[3] * src[CLAMP (src_i + 2, 0, n_src - 1)];
591 dest[j] = CLAMP (rint (y), 0, 255);
592 }
593 }
594 #endif
595
596 #ifdef unused
597 SchroFrame *
schro_virt_frame_new_horiz_resample(SchroFrame * vf,int width)598 schro_virt_frame_new_horiz_resample (SchroFrame * vf, int width)
599 {
600 SchroFrame *virt_frame;
601 double *scale;
602
603 virt_frame = schro_frame_new_virtual (NULL, vf->format, width, vf->height);
604 virt_frame->virt_frame1 = vf;
605 virt_frame->render_line = schro_virt_frame_render_resample_horiz;
606
607 scale = malloc (sizeof (double));
608 virt_frame->virt_priv = scale;
609
610 *scale = (double) vf->width / width;
611
612 return virt_frame;
613 }
614 #endif
615
616 static void
unpack_yuyv(SchroFrame * frame,void * _dest,int component,int i)617 unpack_yuyv (SchroFrame * frame, void *_dest, int component, int i)
618 {
619 uint8_t *dest = _dest;
620 uint8_t *src;
621
622 src = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
623
624 switch (component) {
625 case 0:
626 orc_unpack_yuyv_y (dest, (void *) src, frame->width);
627 break;
628 case 1:
629 orc_unpack_yuyv_u (dest, (void *) src, frame->width / 2);
630 break;
631 case 2:
632 orc_unpack_yuyv_v (dest, (void *) src, frame->width / 2);
633 break;
634 default:
635 SCHRO_ASSERT (0);
636 }
637 }
638
639 static void
unpack_uyvy(SchroFrame * frame,void * _dest,int component,int i)640 unpack_uyvy (SchroFrame * frame, void *_dest, int component, int i)
641 {
642 uint8_t *dest = _dest;
643 uint8_t *src;
644
645 src = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
646
647 switch (component) {
648 case 0:
649 orc_unpack_uyvy_y (dest, (void *) src, frame->width);
650 break;
651 case 1:
652 orc_unpack_uyvy_u (dest, (void *) src, frame->width / 2);
653 break;
654 case 2:
655 orc_unpack_uyvy_v (dest, (void *) src, frame->width / 2);
656 break;
657 default:
658 SCHRO_ASSERT (0);
659 }
660 }
661
662 static void
unpack_ayuv(SchroFrame * frame,void * _dest,int component,int i)663 unpack_ayuv (SchroFrame * frame, void *_dest, int component, int i)
664 {
665 uint8_t *dest = _dest;
666 uint8_t *src;
667 int j;
668
669 src = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
670
671 switch (component) {
672 case 0:
673 for (j = 0; j < frame->width; j++) {
674 dest[j] = src[j * 4 + 1];
675 }
676 break;
677 case 1:
678 for (j = 0; j < frame->width; j++) {
679 dest[j] = src[j * 4 + 2];
680 }
681 break;
682 case 2:
683 for (j = 0; j < frame->width; j++) {
684 dest[j] = src[j * 4 + 3];
685 }
686 break;
687 default:
688 SCHRO_ASSERT (0);
689 }
690 }
691
692 static void
unpack_AY64(SchroFrame * frame,void * _dest,int component,int i)693 unpack_AY64 (SchroFrame * frame, void *_dest, int component, int i)
694 {
695 int32_t *dest = _dest;
696 uint16_t *src;
697 int j;
698
699 src = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
700
701 switch (component) {
702 case 0:
703 for (j = 0; j < frame->width; j++) {
704 dest[j] = src[j * 4 + 1] - 32768;
705 }
706 break;
707 case 1:
708 for (j = 0; j < frame->width; j++) {
709 dest[j] = src[j * 4 + 2] - 32768;
710 }
711 break;
712 case 2:
713 for (j = 0; j < frame->width; j++) {
714 dest[j] = src[j * 4 + 3] - 32768;
715 }
716 break;
717 default:
718 SCHRO_ASSERT (0);
719 }
720 }
721
722 static void
unpack_v210(SchroFrame * frame,void * _dest,int component,int i)723 unpack_v210 (SchroFrame * frame, void *_dest, int component, int i)
724 {
725 int16_t *dest = _dest;
726 uint8_t *src;
727 int j;
728
729 src = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
730
731 #define READ_UINT32_LE(a) (((uint8_t *)(a))[0] | (((uint8_t *)(a))[1]<<8) | \
732 (((uint8_t *)(a))[2]<<16) | (((uint8_t *)(a))[3]<<24))
733 switch (component) {
734 case 0:
735 for (j = 0; j < frame->width / 6; j++) {
736 dest[j * 6 + 0] =
737 ((READ_UINT32_LE (src + j * 16 + 0) >> 10) & 0x3ff) - 512;
738 dest[j * 6 + 1] =
739 ((READ_UINT32_LE (src + j * 16 + 4) >> 0) & 0x3ff) - 512;
740 dest[j * 6 + 2] =
741 ((READ_UINT32_LE (src + j * 16 + 4) >> 20) & 0x3ff) - 512;
742 dest[j * 6 + 3] =
743 ((READ_UINT32_LE (src + j * 16 + 8) >> 10) & 0x3ff) - 512;
744 dest[j * 6 + 4] =
745 ((READ_UINT32_LE (src + j * 16 + 12) >> 0) & 0x3ff) - 512;
746 dest[j * 6 + 5] =
747 ((READ_UINT32_LE (src + j * 16 + 12) >> 20) & 0x3ff) - 512;
748 }
749 if (j * 6 + 0 < frame->width) {
750 dest[j * 6 + 0] =
751 ((READ_UINT32_LE (src + j * 16 + 0) >> 10) & 0x3ff) - 512;
752 }
753 if (j * 6 + 1 < frame->width) {
754 dest[j * 6 + 1] =
755 ((READ_UINT32_LE (src + j * 16 + 4) >> 0) & 0x3ff) - 512;
756 }
757 if (j * 6 + 2 < frame->width) {
758 dest[j * 6 + 2] =
759 ((READ_UINT32_LE (src + j * 16 + 4) >> 20) & 0x3ff) - 512;
760 }
761 if (j * 6 + 3 < frame->width) {
762 dest[j * 6 + 3] =
763 ((READ_UINT32_LE (src + j * 16 + 8) >> 10) & 0x3ff) - 512;
764 }
765 if (j * 6 + 4 < frame->width) {
766 dest[j * 6 + 4] =
767 ((READ_UINT32_LE (src + j * 16 + 12) >> 0) & 0x3ff) - 512;
768 }
769 if (j * 6 + 5 < frame->width) {
770 dest[j * 6 + 5] =
771 ((READ_UINT32_LE (src + j * 16 + 12) >> 20) & 0x3ff) - 512;
772 }
773 break;
774 case 1:
775 for (j = 0; j < frame->width / 6; j++) {
776 dest[j * 3 + 0] =
777 ((READ_UINT32_LE (src + j * 16 + 0) >> 0) & 0x3ff) - 512;
778 dest[j * 3 + 1] =
779 ((READ_UINT32_LE (src + j * 16 + 4) >> 10) & 0x3ff) - 512;
780 dest[j * 3 + 2] =
781 ((READ_UINT32_LE (src + j * 16 + 8) >> 20) & 0x3ff) - 512;
782 }
783 if (j * 6 + 0 < frame->width) {
784 dest[j * 3 + 0] =
785 ((READ_UINT32_LE (src + j * 16 + 0) >> 0) & 0x3ff) - 512;
786 }
787 if (j * 6 + 2 < frame->width) {
788 dest[j * 3 + 1] =
789 ((READ_UINT32_LE (src + j * 16 + 4) >> 10) & 0x3ff) - 512;
790 }
791 if (j * 6 + 4 < frame->width) {
792 dest[j * 3 + 2] =
793 ((READ_UINT32_LE (src + j * 16 + 8) >> 20) & 0x3ff) - 512;
794 }
795 break;
796 case 2:
797 for (j = 0; j < frame->width / 6; j++) {
798 dest[j * 3 + 0] =
799 ((READ_UINT32_LE (src + j * 16 + 0) >> 20) & 0x3ff) - 512;
800 dest[j * 3 + 1] =
801 ((READ_UINT32_LE (src + j * 16 + 8) >> 0) & 0x3ff) - 512;
802 dest[j * 3 + 2] =
803 ((READ_UINT32_LE (src + j * 16 + 12) >> 10) & 0x3ff) - 512;
804 }
805 if (j * 6 + 0 < frame->width) {
806 dest[j * 3 + 0] =
807 ((READ_UINT32_LE (src + j * 16 + 0) >> 20) & 0x3ff) - 512;
808 }
809 if (j * 6 + 2 < frame->width) {
810 dest[j * 3 + 1] =
811 ((READ_UINT32_LE (src + j * 16 + 8) >> 0) & 0x3ff) - 512;
812 }
813 if (j * 6 + 4 < frame->width) {
814 dest[j * 3 + 2] =
815 ((READ_UINT32_LE (src + j * 16 + 12) >> 10) & 0x3ff) - 512;
816 }
817 break;
818 default:
819 SCHRO_ASSERT (0);
820 }
821 }
822
823 static void
unpack_v216(SchroFrame * frame,void * _dest,int component,int i)824 unpack_v216 (SchroFrame * frame, void *_dest, int component, int i)
825 {
826 int16_t *dest = _dest;
827 uint8_t *src;
828 int j;
829
830 src = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
831
832 switch (component) {
833 case 0:
834 for (j = 0; j < frame->width; j++) {
835 dest[j] = src[j * 4 + 2 + 1];
836 }
837 break;
838 case 1:
839 for (j = 0; j < frame->width / 2; j++) {
840 dest[j] = src[j * 8 + 0 + 1];
841 }
842 break;
843 case 2:
844 for (j = 0; j < frame->width / 2; j++) {
845 dest[j] = src[j * 8 + 4 + 1];
846 }
847 break;
848 default:
849 SCHRO_ASSERT (0);
850 }
851 }
852
853 SchroFrame *
schro_virt_frame_new_unpack(SchroFrame * vf)854 schro_virt_frame_new_unpack (SchroFrame * vf)
855 {
856 SchroFrame *virt_frame;
857 SchroFrameFormat format;
858 SchroFrameRenderFunc render_line;
859
860 switch (vf->format) {
861 case SCHRO_FRAME_FORMAT_YUYV:
862 format = SCHRO_FRAME_FORMAT_U8_422;
863 render_line = unpack_yuyv;
864 break;
865 case SCHRO_FRAME_FORMAT_UYVY:
866 format = SCHRO_FRAME_FORMAT_U8_422;
867 render_line = unpack_uyvy;
868 break;
869 case SCHRO_FRAME_FORMAT_AYUV:
870 format = SCHRO_FRAME_FORMAT_U8_444;
871 render_line = unpack_ayuv;
872 break;
873 case SCHRO_FRAME_FORMAT_v210:
874 format = SCHRO_FRAME_FORMAT_S16_422;
875 render_line = unpack_v210;
876 break;
877 case SCHRO_FRAME_FORMAT_v216:
878 format = SCHRO_FRAME_FORMAT_S16_422;
879 render_line = unpack_v216;
880 break;
881 case SCHRO_FRAME_FORMAT_AY64:
882 format = SCHRO_FRAME_FORMAT_S32_444;
883 render_line = unpack_AY64;
884 break;
885 default:
886 return vf;
887 }
888
889 virt_frame = schro_frame_new_virtual (NULL, format, vf->width, vf->height);
890 virt_frame->virt_frame1 = vf;
891 virt_frame->render_line = render_line;
892
893 return virt_frame;
894 }
895
896
897 static void
pack_yuyv(SchroFrame * frame,void * _dest,int component,int i)898 pack_yuyv (SchroFrame * frame, void *_dest, int component, int i)
899 {
900 uint32_t *dest = _dest;
901 uint8_t *src_y;
902 uint8_t *src_u;
903 uint8_t *src_v;
904
905 src_y = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
906 src_u = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
907 src_v = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
908
909 orc_packyuyv (dest, src_y, src_u, src_v, frame->width / 2);
910 }
911
912
913 SchroFrame *
schro_virt_frame_new_pack_YUY2(SchroFrame * vf)914 schro_virt_frame_new_pack_YUY2 (SchroFrame * vf)
915 {
916 SchroFrame *virt_frame;
917
918 virt_frame = schro_frame_new_virtual (NULL, SCHRO_FRAME_FORMAT_YUYV,
919 vf->width, vf->height);
920 virt_frame->virt_frame1 = vf;
921 virt_frame->render_line = pack_yuyv;
922
923 return virt_frame;
924 }
925
926 static void
pack_uyvy(SchroFrame * frame,void * _dest,int component,int i)927 pack_uyvy (SchroFrame * frame, void *_dest, int component, int i)
928 {
929 uint8_t *dest = _dest;
930 uint8_t *src_y;
931 uint8_t *src_u;
932 uint8_t *src_v;
933 int j;
934
935 src_y = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
936 src_u = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
937 src_v = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
938
939 for (j = 0; j < frame->width / 2; j++) {
940 dest[j * 4 + 1] = src_y[j * 2 + 0];
941 dest[j * 4 + 3] = src_y[j * 2 + 1];
942 dest[j * 4 + 0] = src_u[j];
943 dest[j * 4 + 2] = src_v[j];
944 }
945 }
946
947 SchroFrame *
schro_virt_frame_new_pack_UYVY(SchroFrame * vf)948 schro_virt_frame_new_pack_UYVY (SchroFrame * vf)
949 {
950 SchroFrame *virt_frame;
951
952 virt_frame = schro_frame_new_virtual (NULL, SCHRO_FRAME_FORMAT_YUYV,
953 vf->width, vf->height);
954 virt_frame->virt_frame1 = vf;
955 virt_frame->render_line = pack_uyvy;
956
957 return virt_frame;
958 }
959
960 static void
pack_v216(SchroFrame * frame,void * _dest,int component,int i)961 pack_v216 (SchroFrame * frame, void *_dest, int component, int i)
962 {
963 uint8_t *dest = _dest;
964 uint8_t *src_y;
965 uint8_t *src_u;
966 uint8_t *src_v;
967 int j;
968
969 src_y = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
970 src_u = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
971 src_v = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
972
973 for (j = 0; j < frame->width / 2; j++) {
974 dest[j * 8 + 0] = src_u[j];
975 dest[j * 8 + 1] = src_u[j];
976 dest[j * 8 + 2] = src_y[j * 2 + 0];
977 dest[j * 8 + 3] = src_y[j * 2 + 0];
978 dest[j * 8 + 4] = src_v[j];
979 dest[j * 8 + 5] = src_v[j];
980 dest[j * 8 + 6] = src_y[j * 2 + 1];
981 dest[j * 8 + 7] = src_y[j * 2 + 1];
982 }
983 }
984
985 SchroFrame *
schro_virt_frame_new_pack_v216(SchroFrame * vf)986 schro_virt_frame_new_pack_v216 (SchroFrame * vf)
987 {
988 SchroFrame *virt_frame;
989
990 virt_frame = schro_frame_new_virtual (NULL, SCHRO_FRAME_FORMAT_v216,
991 vf->width, vf->height);
992 virt_frame->virt_frame1 = vf;
993 virt_frame->render_line = pack_v216;
994
995 return virt_frame;
996 }
997
998 static void
pack_v210_s16(SchroFrame * frame,void * _dest,int component,int i)999 pack_v210_s16 (SchroFrame * frame, void *_dest, int component, int i)
1000 {
1001 uint8_t *dest = _dest;
1002 int16_t *src_y;
1003 int16_t *src_u;
1004 int16_t *src_v;
1005 int j;
1006 uint32_t val;
1007
1008 src_y = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
1009 src_u = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
1010 src_v = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
1011
1012 #define TO_10(x) (CLAMP(((x) + 512), 0, 1023))
1013 #define WRITE_UINT32_LE(a,b) do { \
1014 ((uint8_t *)(a))[0] = (b)&0xff; \
1015 ((uint8_t *)(a))[1] = ((b)>>8)&0xff; \
1016 ((uint8_t *)(a))[2] = ((b)>>16)&0xff; \
1017 ((uint8_t *)(a))[3] = ((b)>>24)&0xff; \
1018 } while(0)
1019 for (j = 0; j < frame->width / 6; j++) {
1020 int y0, y1, y2, y3, y4, y5;
1021 int cr0, cr1, cr2;
1022 int cb0, cb1, cb2;
1023
1024 y0 = TO_10 (src_y[j * 6 + 0]);
1025 y1 = TO_10 (src_y[j * 6 + 1]);
1026 y2 = TO_10 (src_y[j * 6 + 2]);
1027 y3 = TO_10 (src_y[j * 6 + 3]);
1028 y4 = TO_10 (src_y[j * 6 + 4]);
1029 y5 = TO_10 (src_y[j * 6 + 5]);
1030 cb0 = TO_10 (src_u[j * 3 + 0]);
1031 cb1 = TO_10 (src_u[j * 3 + 1]);
1032 cb2 = TO_10 (src_u[j * 3 + 2]);
1033 cr0 = TO_10 (src_v[j * 3 + 0]);
1034 cr1 = TO_10 (src_v[j * 3 + 1]);
1035 cr2 = TO_10 (src_v[j * 3 + 2]);
1036
1037 val = (cr0 << 20) | (y0 << 10) | (cb0);
1038 WRITE_UINT32_LE (dest + j * 16 + 0, val);
1039
1040 val = (y2 << 20) | (cb1 << 10) | (y1);
1041 WRITE_UINT32_LE (dest + j * 16 + 4, val);
1042
1043 val = (cb2 << 20) | (y3 << 10) | (cr1);
1044 WRITE_UINT32_LE (dest + j * 16 + 8, val);
1045
1046 val = (y5 << 20) | (cr2 << 10) | (y4);
1047 WRITE_UINT32_LE (dest + j * 16 + 12, val);
1048 }
1049 if (j * 6 < frame->width) {
1050 int y0, y1, y2, y3, y4, y5;
1051 int cr0, cr1, cr2;
1052 int cb0, cb1, cb2;
1053
1054 y0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_y[j * 6 + 0]) : 0;
1055 y1 = ((j * 6 + 1) < frame->width) ? TO_10 (src_y[j * 6 + 1]) : 0;
1056 y2 = ((j * 6 + 2) < frame->width) ? TO_10 (src_y[j * 6 + 2]) : 0;
1057 y3 = ((j * 6 + 3) < frame->width) ? TO_10 (src_y[j * 6 + 3]) : 0;
1058 y4 = ((j * 6 + 4) < frame->width) ? TO_10 (src_y[j * 6 + 4]) : 0;
1059 y5 = ((j * 6 + 5) < frame->width) ? TO_10 (src_y[j * 6 + 5]) : 0;
1060 cb0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_u[j * 3 + 0]) : 0;
1061 cb1 = ((j * 6 + 2) < frame->width) ? TO_10 (src_u[j * 3 + 1]) : 0;
1062 cb2 = ((j * 6 + 4) < frame->width) ? TO_10 (src_u[j * 3 + 2]) : 0;
1063 cr0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_v[j * 3 + 0]) : 0;
1064 cr1 = ((j * 6 + 2) < frame->width) ? TO_10 (src_v[j * 3 + 1]) : 0;
1065 cr2 = ((j * 6 + 4) < frame->width) ? TO_10 (src_v[j * 3 + 2]) : 0;
1066
1067 val = (cr0 << 20) | (y0 << 10) | (cb0);
1068 WRITE_UINT32_LE (dest + j * 16 + 0, val);
1069
1070 val = (y2 << 20) | (cb1 << 10) | (y1);
1071 WRITE_UINT32_LE (dest + j * 16 + 4, val);
1072
1073 val = (cb2 << 20) | (y3 << 10) | (cr1);
1074 WRITE_UINT32_LE (dest + j * 16 + 8, val);
1075
1076 val = (y5 << 20) | (cr2 << 10) | (y4);
1077 WRITE_UINT32_LE (dest + j * 16 + 12, val);
1078 }
1079 #undef TO_10
1080
1081 }
1082
1083 static void
pack_v210(SchroFrame * frame,void * _dest,int component,int i)1084 pack_v210 (SchroFrame * frame, void *_dest, int component, int i)
1085 {
1086 uint8_t *dest = _dest;
1087 uint8_t *src_y;
1088 uint8_t *src_u;
1089 uint8_t *src_v;
1090 int j;
1091 uint32_t val;
1092
1093 src_y = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
1094 src_u = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
1095 src_v = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
1096
1097 #define TO_10(x) (((x)<<2) | ((x)>>6))
1098 #define WRITE_UINT32_LE(a,b) do { \
1099 ((uint8_t *)(a))[0] = (b)&0xff; \
1100 ((uint8_t *)(a))[1] = ((b)>>8)&0xff; \
1101 ((uint8_t *)(a))[2] = ((b)>>16)&0xff; \
1102 ((uint8_t *)(a))[3] = ((b)>>24)&0xff; \
1103 } while(0)
1104 for (j = 0; j < frame->width / 6; j++) {
1105 int y0, y1, y2, y3, y4, y5;
1106 int cr0, cr1, cr2;
1107 int cb0, cb1, cb2;
1108
1109 y0 = TO_10 (src_y[j * 6 + 0]);
1110 y1 = TO_10 (src_y[j * 6 + 1]);
1111 y2 = TO_10 (src_y[j * 6 + 2]);
1112 y3 = TO_10 (src_y[j * 6 + 3]);
1113 y4 = TO_10 (src_y[j * 6 + 4]);
1114 y5 = TO_10 (src_y[j * 6 + 5]);
1115 cb0 = TO_10 (src_u[j * 3 + 0]);
1116 cb1 = TO_10 (src_u[j * 3 + 1]);
1117 cb2 = TO_10 (src_u[j * 3 + 2]);
1118 cr0 = TO_10 (src_v[j * 3 + 0]);
1119 cr1 = TO_10 (src_v[j * 3 + 1]);
1120 cr2 = TO_10 (src_v[j * 3 + 2]);
1121
1122 val = (cr0 << 20) | (y0 << 10) | (cb0);
1123 WRITE_UINT32_LE (dest + j * 16 + 0, val);
1124
1125 val = (y2 << 20) | (cb1 << 10) | (y1);
1126 WRITE_UINT32_LE (dest + j * 16 + 4, val);
1127
1128 val = (cb2 << 20) | (y3 << 10) | (cr1);
1129 WRITE_UINT32_LE (dest + j * 16 + 8, val);
1130
1131 val = (y5 << 20) | (cr2 << 10) | (y4);
1132 WRITE_UINT32_LE (dest + j * 16 + 12, val);
1133 }
1134 if (j * 6 < frame->width) {
1135 int y0, y1, y2, y3, y4, y5;
1136 int cr0, cr1, cr2;
1137 int cb0, cb1, cb2;
1138
1139 y0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_y[j * 6 + 0]) : 0;
1140 y1 = ((j * 6 + 1) < frame->width) ? TO_10 (src_y[j * 6 + 1]) : 0;
1141 y2 = ((j * 6 + 2) < frame->width) ? TO_10 (src_y[j * 6 + 2]) : 0;
1142 y3 = ((j * 6 + 3) < frame->width) ? TO_10 (src_y[j * 6 + 3]) : 0;
1143 y4 = ((j * 6 + 4) < frame->width) ? TO_10 (src_y[j * 6 + 4]) : 0;
1144 y5 = ((j * 6 + 5) < frame->width) ? TO_10 (src_y[j * 6 + 5]) : 0;
1145 cb0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_u[j * 3 + 0]) : 0;
1146 cb1 = ((j * 6 + 2) < frame->width) ? TO_10 (src_u[j * 3 + 1]) : 0;
1147 cb2 = ((j * 6 + 4) < frame->width) ? TO_10 (src_u[j * 3 + 2]) : 0;
1148 cr0 = ((j * 6 + 0) < frame->width) ? TO_10 (src_v[j * 3 + 0]) : 0;
1149 cr1 = ((j * 6 + 2) < frame->width) ? TO_10 (src_v[j * 3 + 1]) : 0;
1150 cr2 = ((j * 6 + 4) < frame->width) ? TO_10 (src_v[j * 3 + 2]) : 0;
1151
1152 val = (cr0 << 20) | (y0 << 10) | (cb0);
1153 WRITE_UINT32_LE (dest + j * 16 + 0, val);
1154
1155 val = (y2 << 20) | (cb1 << 10) | (y1);
1156 WRITE_UINT32_LE (dest + j * 16 + 4, val);
1157
1158 val = (cb2 << 20) | (y3 << 10) | (cr1);
1159 WRITE_UINT32_LE (dest + j * 16 + 8, val);
1160
1161 val = (y5 << 20) | (cr2 << 10) | (y4);
1162 WRITE_UINT32_LE (dest + j * 16 + 12, val);
1163 }
1164
1165 }
1166
1167 SchroFrame *
schro_virt_frame_new_pack_v210(SchroFrame * vf)1168 schro_virt_frame_new_pack_v210 (SchroFrame * vf)
1169 {
1170 SchroFrame *virt_frame;
1171
1172 virt_frame = schro_frame_new_virtual (NULL, SCHRO_FRAME_FORMAT_v210,
1173 vf->width, vf->height);
1174 virt_frame->virt_frame1 = vf;
1175 if (vf->format == SCHRO_FRAME_FORMAT_S16_422) {
1176 virt_frame->render_line = pack_v210_s16;
1177 } else {
1178 virt_frame->render_line = pack_v210;
1179 }
1180
1181 return virt_frame;
1182 }
1183
1184 static void
pack_ayuv(SchroFrame * frame,void * _dest,int component,int i)1185 pack_ayuv (SchroFrame * frame, void *_dest, int component, int i)
1186 {
1187 uint8_t *dest = _dest;
1188 uint8_t *src_y;
1189 uint8_t *src_u;
1190 uint8_t *src_v;
1191 int j;
1192
1193 src_y = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
1194 src_u = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
1195 src_v = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
1196
1197 for (j = 0; j < frame->width; j++) {
1198 dest[j * 4 + 0] = 0xff;
1199 dest[j * 4 + 1] = src_y[j];
1200 dest[j * 4 + 2] = src_u[j];
1201 dest[j * 4 + 3] = src_v[j];
1202 }
1203 }
1204
1205 SchroFrame *
schro_virt_frame_new_pack_AYUV(SchroFrame * vf)1206 schro_virt_frame_new_pack_AYUV (SchroFrame * vf)
1207 {
1208 SchroFrame *virt_frame;
1209
1210 virt_frame = schro_frame_new_virtual (NULL, SCHRO_FRAME_FORMAT_AYUV,
1211 vf->width, vf->height);
1212 virt_frame->virt_frame1 = vf;
1213 virt_frame->render_line = pack_ayuv;
1214
1215 return virt_frame;
1216 }
1217
1218 static void
pack_ayuv64(SchroFrame * frame,void * _dest,int component,int i)1219 pack_ayuv64 (SchroFrame * frame, void *_dest, int component, int i)
1220 {
1221 uint16_t *dest = _dest;
1222 int32_t *src_y;
1223 int32_t *src_u;
1224 int32_t *src_v;
1225 int j;
1226
1227 src_y = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
1228 src_u = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
1229 src_v = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
1230
1231 for (j = 0; j < frame->width; j++) {
1232 dest[j * 4 + 0] = 0xffff;
1233 dest[j * 4 + 1] = CLAMP(src_y[j] + 0x8000, 0, 0xffff);
1234 dest[j * 4 + 2] = CLAMP(src_u[j] + 0x8000, 0, 0xffff);
1235 dest[j * 4 + 3] = CLAMP(src_v[j] + 0x8000, 0, 0xffff);
1236 }
1237 }
1238
1239 SchroFrame *
schro_virt_frame_new_pack_AY64(SchroFrame * vf)1240 schro_virt_frame_new_pack_AY64 (SchroFrame * vf)
1241 {
1242 SchroFrame *virt_frame;
1243
1244 virt_frame = schro_frame_new_virtual (NULL, SCHRO_FRAME_FORMAT_AY64,
1245 vf->width, vf->height);
1246 virt_frame->virt_frame1 = vf;
1247 virt_frame->render_line = pack_ayuv64;
1248
1249 return virt_frame;
1250 }
1251
1252 #ifdef unused
1253 static void
pack_rgb(SchroFrame * frame,void * _dest,int component,int i)1254 pack_rgb (SchroFrame * frame, void *_dest, int component, int i)
1255 {
1256 uint8_t *dest = _dest;
1257 uint8_t *src_y;
1258 uint8_t *src_u;
1259 uint8_t *src_v;
1260 int j;
1261
1262 src_y = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
1263 src_u = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
1264 src_v = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
1265
1266 for (j = 0; j < frame->width; j++) {
1267 dest[j * 3 + 0] = src_y[j];
1268 dest[j * 3 + 1] = src_u[j];
1269 dest[j * 3 + 2] = src_v[j];
1270 }
1271 }
1272 #endif
1273
1274 #ifdef unused
1275 SchroFrame *
schro_virt_frame_new_pack_RGB(SchroFrame * vf)1276 schro_virt_frame_new_pack_RGB (SchroFrame * vf)
1277 {
1278 SchroFrame *virt_frame;
1279
1280 virt_frame = schro_frame_new_virtual (NULL, SCHRO_FRAME_FORMAT_RGB,
1281 vf->width, vf->height);
1282 virt_frame->virt_frame1 = vf;
1283 virt_frame->render_line = pack_rgb;
1284
1285 return virt_frame;
1286 }
1287 #endif
1288
1289 #ifdef unused
1290 static void
color_matrix(SchroFrame * frame,void * _dest,int component,int i)1291 color_matrix (SchroFrame * frame, void *_dest, int component, int i)
1292 {
1293 uint8_t *dest = _dest;
1294 uint8_t *src1;
1295 uint8_t *src2;
1296 uint8_t *src3;
1297 double m1, m2, m3;
1298 double offset;
1299 int j;
1300
1301 src1 = schro_virt_frame_get_line (frame->virt_frame1, 0, i);
1302 src2 = schro_virt_frame_get_line (frame->virt_frame1, 1, i);
1303 src3 = schro_virt_frame_get_line (frame->virt_frame1, 2, i);
1304
1305 switch (component) {
1306 case 0:
1307 m1 = 0.25679;
1308 m2 = 0.50413;
1309 m3 = 0.097906;
1310 offset = 16;
1311 break;
1312 case 1:
1313 m1 = -0.14822;
1314 m2 = -0.29099;
1315 m3 = 0.43922;
1316 offset = 128;
1317 break;
1318 case 2:
1319 m1 = 0.43922;
1320 m2 = -0.36779;
1321 m3 = -0.071427;
1322 offset = 128;
1323 break;
1324 default:
1325 m1 = 0.0;
1326 m2 = 0.0;
1327 m3 = 0.0;
1328 offset = 0;
1329 break;
1330 }
1331
1332 for (j = 0; j < frame->width; j++) {
1333 dest[j] = floor (src1[j] * m1 + src2[j] * m2 + src3[j] * m3 + offset + 0.5);
1334 }
1335
1336 }
1337 #endif
1338
1339 #ifdef unused
1340 SchroFrame *
schro_virt_frame_new_color_matrix(SchroFrame * vf)1341 schro_virt_frame_new_color_matrix (SchroFrame * vf)
1342 {
1343 SchroFrame *virt_frame;
1344
1345 virt_frame = schro_frame_new_virtual (NULL, SCHRO_FRAME_FORMAT_U8_444,
1346 vf->width, vf->height);
1347 virt_frame->virt_frame1 = vf;
1348 virt_frame->render_line = color_matrix;
1349
1350 return virt_frame;
1351 }
1352 #endif
1353
1354 static void
convert_444_422(SchroFrame * frame,void * _dest,int component,int i)1355 convert_444_422 (SchroFrame * frame, void *_dest, int component, int i)
1356 {
1357 uint8_t *dest = _dest;
1358 uint8_t *src;
1359 int j;
1360
1361 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1362
1363 if (component == 0) {
1364 orc_memcpy (dest, src, frame->width);
1365 } else {
1366 for (j = 0; j < frame->components[component].width; j++) {
1367 dest[j] = src[j * 2];
1368 }
1369 }
1370 }
1371
1372 static void
convert_444_420(SchroFrame * frame,void * _dest,int component,int i)1373 convert_444_420 (SchroFrame * frame, void *_dest, int component, int i)
1374 {
1375 uint8_t *dest = _dest;
1376 uint8_t *src;
1377 int j;
1378
1379 if (component == 0) {
1380 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1381 orc_memcpy (dest, src, frame->components[component].width);
1382 } else {
1383 src = schro_virt_frame_get_line (frame->virt_frame1, component, i * 2);
1384 for (j = 0; j < frame->components[component].width; j++) {
1385 dest[j] = src[j * 2];
1386 }
1387 }
1388 }
1389
1390 static void
convert_422_420(SchroFrame * frame,void * _dest,int component,int i)1391 convert_422_420 (SchroFrame * frame, void *_dest, int component, int i)
1392 {
1393 uint8_t *dest = _dest;
1394 uint8_t *src;
1395
1396 if (component == 0) {
1397 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1398 } else {
1399 src = schro_virt_frame_get_line (frame->virt_frame1, component, i * 2);
1400 }
1401 orc_memcpy (dest, src, frame->components[component].width);
1402 }
1403
1404 /* up */
1405
1406 static void
convert_422_444(SchroFrame * frame,void * _dest,int component,int i)1407 convert_422_444 (SchroFrame * frame, void *_dest, int component, int i)
1408 {
1409 uint8_t *dest = _dest;
1410 uint8_t *src;
1411 int j;
1412
1413 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1414
1415 if (component == 0) {
1416 orc_memcpy (dest, src, frame->width);
1417 } else {
1418 for (j = 0; j < frame->components[component].width; j++) {
1419 dest[j] = src[j >> 1];
1420 }
1421 }
1422 }
1423
1424 static void
convert_420_444(SchroFrame * frame,void * _dest,int component,int i)1425 convert_420_444 (SchroFrame * frame, void *_dest, int component, int i)
1426 {
1427 uint8_t *dest = _dest;
1428 uint8_t *src;
1429 int j;
1430
1431 if (component == 0) {
1432 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1433 orc_memcpy (dest, src, frame->components[component].width);
1434 } else {
1435 src = schro_virt_frame_get_line (frame->virt_frame1, component, i >> 1);
1436 for (j = 0; j < frame->components[component].width; j++) {
1437 dest[j] = src[j >> 1];
1438 }
1439 }
1440 }
1441
1442 static void
convert_420_422(SchroFrame * frame,void * _dest,int component,int i)1443 convert_420_422 (SchroFrame * frame, void *_dest, int component, int i)
1444 {
1445 uint8_t *dest = _dest;
1446 uint8_t *src;
1447
1448 if (component == 0) {
1449 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1450 } else {
1451 src = schro_virt_frame_get_line (frame->virt_frame1, component, i >> 1);
1452 }
1453 orc_memcpy (dest, src, frame->components[component].width);
1454 }
1455
1456 SchroFrame *
schro_virt_frame_new_subsample(SchroFrame * vf,SchroFrameFormat format)1457 schro_virt_frame_new_subsample (SchroFrame * vf, SchroFrameFormat format)
1458 {
1459 SchroFrame *virt_frame;
1460 SchroFrameRenderFunc render_line;
1461
1462 if (vf->format == format) {
1463 return vf;
1464 }
1465 if (vf->format == SCHRO_FRAME_FORMAT_U8_422 &&
1466 format == SCHRO_FRAME_FORMAT_U8_420) {
1467 render_line = convert_422_420;
1468 } else if (vf->format == SCHRO_FRAME_FORMAT_U8_444 &&
1469 format == SCHRO_FRAME_FORMAT_U8_420) {
1470 render_line = convert_444_420;
1471 } else if (vf->format == SCHRO_FRAME_FORMAT_U8_444 &&
1472 format == SCHRO_FRAME_FORMAT_U8_422) {
1473 render_line = convert_444_422;
1474 } else if (vf->format == SCHRO_FRAME_FORMAT_U8_420 &&
1475 format == SCHRO_FRAME_FORMAT_U8_422) {
1476 render_line = convert_420_422;
1477 } else if (vf->format == SCHRO_FRAME_FORMAT_U8_420 &&
1478 format == SCHRO_FRAME_FORMAT_U8_444) {
1479 render_line = convert_420_444;
1480 } else if (vf->format == SCHRO_FRAME_FORMAT_U8_422 &&
1481 format == SCHRO_FRAME_FORMAT_U8_444) {
1482 render_line = convert_422_444;
1483 } else {
1484 SCHRO_ASSERT (0);
1485 return NULL;
1486 }
1487 virt_frame = schro_frame_new_virtual (NULL, format, vf->width, vf->height);
1488 virt_frame->virt_frame1 = vf;
1489 virt_frame->render_line = render_line;
1490
1491 return virt_frame;
1492 }
1493
1494
1495 #if 0
1496 SchroFrame *
1497 schro_virt_frame_new_horiz_downsample_take (SchroFrame * vf, int cosite)
1498 {
1499 SchroFrame *virt_frame;
1500 virt_frame = schro_virt_frame_new_horiz_downsample (vf, cosite);
1501 schro_frame_unref (vf);
1502 return virt_frame;
1503 }
1504
1505 SchroFrame *
1506 schro_virt_frame_new_vert_downsample_take (SchroFrame * vf, int cosite)
1507 {
1508 SchroFrame *virt_frame;
1509 virt_frame = schro_virt_frame_new_vert_downsample (vf, cosite);
1510 schro_frame_unref (vf);
1511 return virt_frame;
1512 }
1513
1514 SchroFrame *
1515 schro_virt_frame_new_vert_resample_take (SchroFrame * vf, int height)
1516 {
1517 SchroFrame *virt_frame;
1518 virt_frame = schro_virt_frame_new_vert_resample (vf, height);
1519 schro_frame_unref (vf);
1520 return virt_frame;
1521 }
1522
1523 SchroFrame *
1524 schro_virt_frame_new_horiz_resample_take (SchroFrame * vf, int width)
1525 {
1526 SchroFrame *virt_frame;
1527 virt_frame = schro_virt_frame_new_horiz_resample (vf, width);
1528 schro_frame_unref (vf);
1529 return virt_frame;
1530 }
1531
1532 SchroFrame *
1533 schro_virt_frame_new_unpack_take (SchroFrame * vf)
1534 {
1535 SchroFrame *virt_frame;
1536 virt_frame = schro_virt_frame_new_unpack (vf);
1537 schro_frame_unref (vf);
1538 return virt_frame;
1539 }
1540
1541 SchroFrame *
1542 schro_virt_frame_new_pack_YUY2_take (SchroFrame * vf)
1543 {
1544 SchroFrame *virt_frame;
1545 virt_frame = schro_virt_frame_new_pack_YUY2 (vf);
1546 schro_frame_unref (vf);
1547 return virt_frame;
1548 }
1549
1550 SchroFrame *
1551 schro_virt_frame_new_pack_UYVY_take (SchroFrame * vf)
1552 {
1553 SchroFrame *virt_frame;
1554 virt_frame = schro_virt_frame_new_pack_UYVY (vf);
1555 schro_frame_unref (vf);
1556 return virt_frame;
1557 }
1558
1559 SchroFrame *
1560 schro_virt_frame_new_pack_v216_take (SchroFrame * vf)
1561 {
1562 SchroFrame *virt_frame;
1563 virt_frame = schro_virt_frame_new_pack_v216 (vf);
1564 schro_frame_unref (vf);
1565 return virt_frame;
1566 }
1567
1568 SchroFrame *
1569 schro_virt_frame_new_pack_v210_take (SchroFrame * vf)
1570 {
1571 SchroFrame *virt_frame;
1572 virt_frame = schro_virt_frame_new_pack_v210 (vf);
1573 schro_frame_unref (vf);
1574 return virt_frame;
1575 }
1576
1577 SchroFrame *
1578 schro_virt_frame_new_pack_AYUV_take (SchroFrame * vf)
1579 {
1580 SchroFrame *virt_frame;
1581 virt_frame = schro_virt_frame_new_pack_AYUV (vf);
1582 schro_frame_unref (vf);
1583 return virt_frame;
1584 }
1585
1586 SchroFrame *
1587 schro_virt_frame_new_pack_RGB_take (SchroFrame * vf)
1588 {
1589 SchroFrame *virt_frame;
1590 virt_frame = schro_virt_frame_new_pack_RGB (vf);
1591 schro_frame_unref (vf);
1592 return virt_frame;
1593 }
1594
1595 SchroFrame *
1596 schro_virt_frame_new_subsample_take (SchroFrame * vf, SchroFrameFormat format)
1597 {
1598 SchroFrame *virt_frame;
1599 virt_frame = schro_virt_frame_new_subsample (vf, format);
1600 schro_frame_unref (vf);
1601 return virt_frame;
1602 }
1603 #endif
1604
1605 static void
convert_u8_s16(SchroFrame * frame,void * _dest,int component,int i)1606 convert_u8_s16 (SchroFrame * frame, void *_dest, int component, int i)
1607 {
1608 uint8_t *dest = _dest;
1609 int16_t *src;
1610
1611 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1612 orc_offsetconvert_u8_s16 (dest, src, frame->components[component].width);
1613 }
1614
1615 SchroFrame *
schro_virt_frame_new_convert_u8(SchroFrame * vf)1616 schro_virt_frame_new_convert_u8 (SchroFrame * vf)
1617 {
1618 SchroFrame *virt_frame;
1619 SchroFrameFormat format;
1620
1621 format = (vf->format & 3) | SCHRO_FRAME_FORMAT_U8_444;
1622
1623 virt_frame = schro_frame_new_virtual (NULL, format, vf->width, vf->height);
1624 virt_frame->virt_frame1 = vf;
1625 virt_frame->render_line = convert_u8_s16;
1626 virt_frame->virt_priv = schro_malloc (sizeof (int16_t) * vf->width);
1627
1628 return virt_frame;
1629 }
1630
1631 static void
convert_u8_s32(SchroFrame * frame,void * _dest,int component,int i)1632 convert_u8_s32 (SchroFrame * frame, void *_dest, int component, int i)
1633 {
1634 uint8_t *dest = _dest;
1635 int32_t *src;
1636
1637 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1638 orc_offsetconvert_u8_s32 (dest, src, frame->components[component].width);
1639 }
1640
1641 SchroFrame *
schro_virt_frame_new_convert_u8_s32(SchroFrame * vf)1642 schro_virt_frame_new_convert_u8_s32 (SchroFrame * vf)
1643 {
1644 SchroFrame *virt_frame;
1645 SchroFrameFormat format;
1646
1647 format = (vf->format & 3) | SCHRO_FRAME_FORMAT_U8_444;
1648
1649 virt_frame = schro_frame_new_virtual (NULL, format, vf->width, vf->height);
1650 virt_frame->virt_frame1 = vf;
1651 virt_frame->render_line = convert_u8_s32;
1652 virt_frame->virt_priv = schro_malloc (sizeof (int32_t) * vf->width);
1653
1654 return virt_frame;
1655 }
1656
1657 static void
convert_s16_u8(SchroFrame * frame,void * _dest,int component,int i)1658 convert_s16_u8 (SchroFrame * frame, void *_dest, int component, int i)
1659 {
1660 int16_t *dest = _dest;
1661 uint8_t *src;
1662
1663 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1664
1665 orc_offsetconvert_s16_u8 (dest, src, frame->components[component].width);
1666 }
1667
1668 static void
convert_s16_s32(SchroFrame * frame,void * _dest,int component,int i)1669 convert_s16_s32 (SchroFrame * frame, void *_dest, int component, int i)
1670 {
1671 int16_t *dest = _dest;
1672 int32_t *src;
1673
1674 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1675
1676 orc_convert_s16_s32 (dest, src, frame->components[component].width);
1677 }
1678
1679 SchroFrame *
schro_virt_frame_new_convert_s16(SchroFrame * vf)1680 schro_virt_frame_new_convert_s16 (SchroFrame * vf)
1681 {
1682 SchroFrame *virt_frame;
1683 SchroFrameFormat format;
1684
1685 format = (vf->format & 3) | SCHRO_FRAME_FORMAT_S16_444;
1686
1687 virt_frame = schro_frame_new_virtual (NULL, format, vf->width, vf->height);
1688 virt_frame->virt_frame1 = vf;
1689 if (SCHRO_FRAME_FORMAT_DEPTH (vf->format) == SCHRO_FRAME_FORMAT_DEPTH_S32) {
1690 virt_frame->render_line = convert_s16_s32;
1691 } else {
1692 virt_frame->render_line = convert_s16_u8;
1693 }
1694
1695 return virt_frame;
1696 }
1697
1698 static void
convert_s32_u8(SchroFrame * frame,void * _dest,int component,int i)1699 convert_s32_u8 (SchroFrame * frame, void *_dest, int component, int i)
1700 {
1701 int32_t *dest = _dest;
1702 uint8_t *src;
1703
1704 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1705
1706 orc_offsetconvert_s32_u8 (dest, src, frame->components[component].width);
1707 }
1708
1709 static void
convert_s32_s16(SchroFrame * frame,void * _dest,int component,int i)1710 convert_s32_s16 (SchroFrame * frame, void *_dest, int component, int i)
1711 {
1712 int32_t *dest = _dest;
1713 int16_t *src;
1714
1715 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1716
1717 orc_convert_s32_s16 (dest, src, frame->components[component].width);
1718 }
1719
1720 SchroFrame *
schro_virt_frame_new_convert_s32(SchroFrame * vf)1721 schro_virt_frame_new_convert_s32 (SchroFrame * vf)
1722 {
1723 SchroFrame *virt_frame;
1724 SchroFrameFormat format;
1725
1726 format = (vf->format & 3) | SCHRO_FRAME_FORMAT_S32_444;
1727
1728 virt_frame = schro_frame_new_virtual (NULL, format, vf->width, vf->height);
1729 virt_frame->virt_frame1 = vf;
1730 if (SCHRO_FRAME_FORMAT_DEPTH (vf->format) == SCHRO_FRAME_FORMAT_DEPTH_S16) {
1731 virt_frame->render_line = convert_s32_s16;
1732 } else {
1733 virt_frame->render_line = convert_s32_u8;
1734 }
1735
1736 return virt_frame;
1737 }
1738
1739 static void
crop_u8(SchroFrame * frame,void * _dest,int component,int i)1740 crop_u8 (SchroFrame * frame, void *_dest, int component, int i)
1741 {
1742 uint8_t *dest = _dest;
1743 uint8_t *src;
1744
1745 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1746 orc_memcpy (dest, src, frame->components[component].width);
1747 }
1748
1749 static void
crop_s16(SchroFrame * frame,void * _dest,int component,int i)1750 crop_s16 (SchroFrame * frame, void *_dest, int component, int i)
1751 {
1752 int16_t *dest = _dest;
1753 int16_t *src;
1754
1755 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1756 orc_memcpy (dest, src, frame->components[component].width * sizeof (int16_t));
1757 }
1758
1759 static void
crop_s32(SchroFrame * frame,void * _dest,int component,int i)1760 crop_s32 (SchroFrame * frame, void *_dest, int component, int i)
1761 {
1762 int16_t *dest = _dest;
1763 int16_t *src;
1764
1765 src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
1766 orc_memcpy (dest, src, frame->components[component].width * sizeof (int32_t));
1767 }
1768
1769 SchroFrame *
schro_virt_frame_new_crop(SchroFrame * vf,int width,int height)1770 schro_virt_frame_new_crop (SchroFrame * vf, int width, int height)
1771 {
1772 SchroFrame *virt_frame;
1773
1774 if (width == vf->width && height == vf->height)
1775 return vf;
1776
1777 SCHRO_ASSERT (width <= vf->width);
1778 SCHRO_ASSERT (height <= vf->height);
1779
1780 virt_frame = schro_frame_new_virtual (NULL, vf->format, width, height);
1781 virt_frame->virt_frame1 = vf;
1782 switch (SCHRO_FRAME_FORMAT_DEPTH (vf->format)) {
1783 case SCHRO_FRAME_FORMAT_DEPTH_U8:
1784 virt_frame->render_line = crop_u8;
1785 break;
1786 case SCHRO_FRAME_FORMAT_DEPTH_S16:
1787 virt_frame->render_line = crop_s16;
1788 break;
1789 default:
1790 virt_frame->render_line = crop_s32;
1791 break;
1792 }
1793
1794 return virt_frame;
1795 }
1796
1797 static void
edge_extend_u8(SchroFrame * frame,void * _dest,int component,int i)1798 edge_extend_u8 (SchroFrame * frame, void *_dest, int component, int i)
1799 {
1800 uint8_t *dest = _dest;
1801 uint8_t *src;
1802 SchroFrame *srcframe = frame->virt_frame1;
1803
1804 src = schro_virt_frame_get_line (frame->virt_frame1, component,
1805 MIN (i, srcframe->components[component].height - 1));
1806 orc_memcpy (dest, src, srcframe->components[component].width);
1807 orc_splat_u8_ns (dest + srcframe->components[component].width,
1808 dest[srcframe->components[component].width - 1],
1809 frame->components[component].width -
1810 srcframe->components[component].width);
1811 }
1812
1813 static void
edge_extend_s16(SchroFrame * frame,void * _dest,int component,int i)1814 edge_extend_s16 (SchroFrame * frame, void *_dest, int component, int i)
1815 {
1816 int16_t *dest = _dest;
1817 int16_t *src;
1818 SchroFrame *srcframe = frame->virt_frame1;
1819
1820 src = schro_virt_frame_get_line (frame->virt_frame1, component,
1821 MIN (i, srcframe->components[component].height - 1));
1822 orc_memcpy (dest, src,
1823 srcframe->components[component].width * sizeof (int16_t));
1824 orc_splat_s16_ns (dest + srcframe->components[component].width,
1825 dest[srcframe->components[component].width - 1],
1826 frame->components[component].width -
1827 srcframe->components[component].width);
1828 }
1829
1830 static void
edge_extend_s32(SchroFrame * frame,void * _dest,int component,int i)1831 edge_extend_s32 (SchroFrame * frame, void *_dest, int component, int i)
1832 {
1833 int32_t *dest = _dest;
1834 int32_t *src;
1835 SchroFrame *srcframe = frame->virt_frame1;
1836
1837 src = schro_virt_frame_get_line (frame->virt_frame1, component,
1838 MIN (i, srcframe->components[component].height - 1));
1839 orc_memcpy (dest, src,
1840 srcframe->components[component].width * sizeof (int32_t));
1841 orc_splat_s32_ns (dest + srcframe->components[component].width,
1842 dest[srcframe->components[component].width - 1],
1843 frame->components[component].width -
1844 srcframe->components[component].width);
1845 }
1846
1847 SchroFrame *
schro_virt_frame_new_edgeextend(SchroFrame * vf,int width,int height)1848 schro_virt_frame_new_edgeextend (SchroFrame * vf, int width, int height)
1849 {
1850 SchroFrame *virt_frame;
1851
1852 if (width == vf->width && height == vf->height)
1853 return vf;
1854
1855 SCHRO_ASSERT (width >= vf->width);
1856 SCHRO_ASSERT (height >= vf->height);
1857
1858 virt_frame = schro_frame_new_virtual (NULL, vf->format, width, height);
1859 virt_frame->virt_frame1 = vf;
1860 switch (SCHRO_FRAME_FORMAT_DEPTH (vf->format)) {
1861 case SCHRO_FRAME_FORMAT_DEPTH_U8:
1862 virt_frame->render_line = edge_extend_u8;
1863 break;
1864 case SCHRO_FRAME_FORMAT_DEPTH_S16:
1865 virt_frame->render_line = edge_extend_s16;
1866 break;
1867 case SCHRO_FRAME_FORMAT_DEPTH_S32:
1868 virt_frame->render_line = edge_extend_s32;
1869 break;
1870 default:
1871 SCHRO_ASSERT (0);
1872 break;
1873 }
1874
1875 return virt_frame;
1876 }
1877