~ubuntu-branches/ubuntu/lucid/gst-plugins-bad0.10/lucid-proposed

« back to all changes in this revision

Viewing changes to ext/cog/cogvirtframe.c

  • Committer: Bazaar Package Importer
  • Author(s): Tony Espy
  • Date: 2009-12-04 13:17:51 UTC
  • mfrom: (18.4.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091204131751-hpo02yltrcsmy1xh
Tags: 0.10.17-1ubuntu1
* Merge from Debian testing (LP: #481645), remaining changes:
  - Removed plugins that are now provided -good
    - libgstdtmf.so
    - libgstvalve.so
    - libgstautoconvert.so
    - libgstrtpmux.so
    - libgstliveadder.so

Show diffs side-by-side

added added

removed removed

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