sna/video: Add NV12 video copy funcs
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
This commit is contained in:
parent
27d58e4b37
commit
8906d8b0e2
|
|
@ -233,7 +233,29 @@ sna_video_frame_set_rotation(struct sna_video *video,
|
|||
/* Determine the desired destination pitch (representing the
|
||||
* chroma's pitch in the planar case).
|
||||
*/
|
||||
if (is_planar_fourcc(frame->id)) {
|
||||
if (is_nv12_fourcc(frame->id)) {
|
||||
assert((width & 1) == 0);
|
||||
assert((height & 1) == 0);
|
||||
if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
|
||||
frame->pitch[0] = ALIGN(height, align);
|
||||
frame->pitch[1] = ALIGN(height, align);
|
||||
frame->size = width * frame->pitch[1] +
|
||||
width / 2 * frame->pitch[0];
|
||||
} else {
|
||||
frame->pitch[0] = ALIGN(width, align);
|
||||
frame->pitch[1] = ALIGN(width, align);
|
||||
frame->size = height * frame->pitch[1] +
|
||||
height / 2 * frame->pitch[0];
|
||||
}
|
||||
|
||||
if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
|
||||
frame->UBufOffset = (int)frame->pitch[1] * width;
|
||||
frame->VBufOffset = frame->UBufOffset;
|
||||
} else {
|
||||
frame->UBufOffset = (int)frame->pitch[1] * height;
|
||||
frame->VBufOffset = frame->UBufOffset;
|
||||
}
|
||||
} else if (is_planar_fourcc(frame->id)) {
|
||||
assert((width & 1) == 0);
|
||||
assert((height & 1) == 0);
|
||||
if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
|
||||
|
|
@ -297,6 +319,78 @@ sna_video_frame_set_rotation(struct sna_video *video,
|
|||
assert(frame->size);
|
||||
}
|
||||
|
||||
static void plane_dims(const struct sna_video_frame *frame, int sub,
|
||||
int *x, int *y, int *w, int *h)
|
||||
{
|
||||
*x = frame->image.x1;
|
||||
*y = frame->image.y1;
|
||||
*w = frame->image.x2 - frame->image.x1;
|
||||
*h = frame->image.y2 - frame->image.y1;
|
||||
|
||||
if (sub) {
|
||||
*x >>= 1; *w >>= 1;
|
||||
*y >>= 1; *h >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sna_memcpy_cbcr_plane(struct sna_video *video,
|
||||
uint16_t *dst, const uint16_t *src,
|
||||
const struct sna_video_frame *frame)
|
||||
{
|
||||
int dstPitch = frame->pitch[0] >> 1, srcPitch;
|
||||
const uint16_t *s;
|
||||
int i, j = 0;
|
||||
int x, y, w, h;
|
||||
|
||||
plane_dims(frame, 1, &x, &y, &w, &h);
|
||||
|
||||
srcPitch = ALIGN((frame->width >> 1), 2);
|
||||
|
||||
src += y * srcPitch + x;
|
||||
if (!video->textured)
|
||||
x = y = 0;
|
||||
|
||||
switch (frame->rotation) {
|
||||
case RR_Rotate_0:
|
||||
dst += y * dstPitch + x;
|
||||
if (srcPitch == dstPitch && srcPitch == w)
|
||||
memcpy(dst, src, (srcPitch * h) << 1);
|
||||
else while (h--) {
|
||||
memcpy(dst, src, w << 1);
|
||||
src += srcPitch;
|
||||
dst += dstPitch;
|
||||
}
|
||||
break;
|
||||
case RR_Rotate_90:
|
||||
for (i = 0; i < h; i++) {
|
||||
s = src;
|
||||
for (j = 0; j < w; j++)
|
||||
dst[i + ((x + w - j - 1) * dstPitch)] = *s++;
|
||||
src += srcPitch;
|
||||
}
|
||||
break;
|
||||
case RR_Rotate_180:
|
||||
for (i = 0; i < h; i++) {
|
||||
s = src;
|
||||
for (j = 0; j < w; j++) {
|
||||
dst[(x + w - j - 1) +
|
||||
((h - i - 1) * dstPitch)] = *s++;
|
||||
}
|
||||
src += srcPitch;
|
||||
}
|
||||
break;
|
||||
case RR_Rotate_270:
|
||||
for (i = 0; i < h; i++) {
|
||||
s = src;
|
||||
for (j = 0; j < w; j++) {
|
||||
dst[(h - i - 1) + (x + j * dstPitch)] = *s++;
|
||||
}
|
||||
src += srcPitch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sna_memcpy_plane(struct sna_video *video,
|
||||
uint8_t *dst, const uint8_t *src,
|
||||
const struct sna_video_frame *frame, int sub)
|
||||
|
|
@ -306,15 +400,11 @@ static void sna_memcpy_plane(struct sna_video *video,
|
|||
int i, j = 0;
|
||||
int x, y, w, h;
|
||||
|
||||
x = frame->image.x1;
|
||||
y = frame->image.y1;
|
||||
w = frame->image.x2 - frame->image.x1;
|
||||
h = frame->image.y2 - frame->image.y1;
|
||||
if (sub) {
|
||||
x >>= 1; w >>= 1;
|
||||
y >>= 1; h >>= 1;
|
||||
plane_dims(frame, sub, &x, &y, &w, &h);
|
||||
|
||||
if (sub)
|
||||
srcPitch = ALIGN((frame->width >> 1), 4);
|
||||
} else
|
||||
else
|
||||
srcPitch = ALIGN(frame->width, 4);
|
||||
|
||||
src += y * srcPitch + x;
|
||||
|
|
@ -362,6 +452,17 @@ static void sna_memcpy_plane(struct sna_video *video,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sna_copy_nv12_data(struct sna_video *video,
|
||||
const struct sna_video_frame *frame,
|
||||
const uint8_t *src, uint8_t *dst)
|
||||
{
|
||||
sna_memcpy_plane(video, dst, src, frame, 0);
|
||||
src += frame->height * ALIGN(frame->width, 4);
|
||||
dst += frame->UBufOffset;
|
||||
sna_memcpy_cbcr_plane(video, (void*)dst, (void*)src, frame);
|
||||
}
|
||||
|
||||
static void
|
||||
sna_copy_planar_data(struct sna_video *video,
|
||||
const struct sna_video_frame *frame,
|
||||
|
|
@ -506,7 +607,28 @@ sna_video_copy_data(struct sna_video *video,
|
|||
if (frame->rotation == RR_Rotate_0 && !video->tiled) {
|
||||
DBG(("%s: unrotated, untiled fast paths: is-planar?=%d\n",
|
||||
__FUNCTION__, is_planar_fourcc(frame->id)));
|
||||
if (is_planar_fourcc(frame->id)) {
|
||||
if (is_nv12_fourcc(frame->id)) {
|
||||
int w = frame->image.x2 - frame->image.x1;
|
||||
int h = frame->image.y2 - frame->image.y1;
|
||||
if (ALIGN(h, 2) == frame->height &&
|
||||
ALIGN(w, 4) == frame->pitch[0] &&
|
||||
ALIGN(w, 4) == frame->pitch[1]) {
|
||||
if (frame->bo) {
|
||||
if (!kgem_bo_write(&video->sna->kgem, frame->bo,
|
||||
buf, frame->size))
|
||||
goto use_gtt;
|
||||
} else {
|
||||
frame->bo = kgem_create_buffer(&video->sna->kgem, frame->size,
|
||||
KGEM_BUFFER_WRITE | KGEM_BUFFER_WRITE_INPLACE,
|
||||
(void **)&dst);
|
||||
if (frame->bo == NULL)
|
||||
return false;
|
||||
|
||||
memcpy(dst, buf, frame->size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else if (is_planar_fourcc(frame->id)) {
|
||||
int w = frame->image.x2 - frame->image.x1;
|
||||
int h = frame->image.y2 - frame->image.y1;
|
||||
if (ALIGN(h, 2) == frame->height &&
|
||||
|
|
@ -583,7 +705,9 @@ use_gtt: /* copy data, must use GTT so that we keep the overlay uncached */
|
|||
return false;
|
||||
}
|
||||
|
||||
if (is_planar_fourcc(frame->id))
|
||||
if (is_nv12_fourcc(frame->id))
|
||||
sna_copy_nv12_data(video, frame, buf, dst);
|
||||
else if (is_planar_fourcc(frame->id))
|
||||
sna_copy_planar_data(video, frame, buf, dst);
|
||||
else
|
||||
sna_copy_packed_data(video, frame, buf, dst);
|
||||
|
|
|
|||
Loading…
Reference in New Issue