1161 lines
40 KiB
C
1161 lines
40 KiB
C
|
|
||
|
/*
|
||
|
* Copyright (c) 2008-2016 Allwinner Technology Co. Ltd.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* File : pixelformat.c
|
||
|
* Description :display engine 2.0 rotation processing base functions implement
|
||
|
* History :
|
||
|
* Author : xyliu <xyliu@allwinnertech.com>
|
||
|
* Date : 2016/04/13
|
||
|
* Comment :
|
||
|
*
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <unistd.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include "vdecoder.h"
|
||
|
#include "log.h"
|
||
|
|
||
|
/*******************************************************************************
|
||
|
Function name: map32x32_to_yuv_Y
|
||
|
Description:
|
||
|
1. we should know : vdecbuf_uv is 32*32 align too
|
||
|
2. must match gpuBuf_uv size.
|
||
|
3. gpuBuf_uv size is half of gpuBuf_y size
|
||
|
4. we guarantee: vdecbufSize>=gpuBufSize
|
||
|
5. uv's macroblock is also 16*16. Vdec_macroblock is also twomb(32*32).
|
||
|
6. if coded_width is stride/2, we can support gpu_buf_width 16byte align and 8byte align!
|
||
|
But need outer set right value of coded_width, must meet gpu_uv_buf_width align's request!
|
||
|
Parameters:
|
||
|
1. mode = 0:yv12, 1:thumb yuv420p
|
||
|
2. coded_width and coded_height is uv size, already half of y_size
|
||
|
Return:
|
||
|
|
||
|
*******************************************************************************/
|
||
|
#ifdef CEDARX_DECODER_ARM32
|
||
|
void ConvertMb32420ToNv21Y(char* pSrc,char* pDst,int nWidth, int nHeight)
|
||
|
{
|
||
|
int nMbWidth = 0;
|
||
|
int nMbHeight = 0;
|
||
|
int i = 0;
|
||
|
int j = 0;
|
||
|
int m = 0;
|
||
|
int n = 0;
|
||
|
int k = 0;
|
||
|
int nLineStride=0;
|
||
|
int lineNum = 0;
|
||
|
int offset = 0;
|
||
|
int maxNum = 0;
|
||
|
char* ptr = NULL;
|
||
|
char bufferU[32];
|
||
|
int nWidthMatchFlag = 0;
|
||
|
int nCopyMbWidth = 0;
|
||
|
|
||
|
nLineStride = (nWidth + 15) &~15;
|
||
|
nMbWidth = (nWidth+31)&~31;
|
||
|
nMbWidth /= 32;
|
||
|
|
||
|
nMbHeight = (nHeight+31)&~31;
|
||
|
nMbHeight /= 32;
|
||
|
ptr = pSrc;
|
||
|
|
||
|
nWidthMatchFlag = 0;
|
||
|
nCopyMbWidth = nMbWidth-1;
|
||
|
|
||
|
if(nMbWidth*32 == nLineStride)
|
||
|
{
|
||
|
nWidthMatchFlag = 1;
|
||
|
nCopyMbWidth = nMbWidth;
|
||
|
|
||
|
}
|
||
|
for(i=0; i<nMbHeight; i++)
|
||
|
{
|
||
|
char *dstAsm = NULL;
|
||
|
char *srcAsm = NULL;
|
||
|
CEDARC_UNUSE(dstAsm);
|
||
|
CEDARC_UNUSE(srcAsm);
|
||
|
for(j=0; j<nCopyMbWidth; j++)
|
||
|
{
|
||
|
for(m=0; m<32; m++)
|
||
|
{
|
||
|
if((i*32 + m) >= nHeight)
|
||
|
{
|
||
|
ptr += 32;
|
||
|
continue;
|
||
|
}
|
||
|
srcAsm = ptr;
|
||
|
lineNum = i*32 + m; //line num
|
||
|
offset = lineNum*nLineStride + j*32;
|
||
|
dstAsm = pDst+ offset;
|
||
|
|
||
|
asm volatile (
|
||
|
"vld1.8 {d0 - d3}, [%[srcAsm]] \n\t"
|
||
|
"vst1.8 {d0 - d3}, [%[dstAsm]] \n\t"
|
||
|
: [dstAsm] "+r" (dstAsm), [srcAsm] "+r" (srcAsm)
|
||
|
: //[srcY] "r" (srcY)
|
||
|
: "cc", "memory", "d0", "d1", "d2", "d3", \
|
||
|
"d4", "d5", "d6", "d16", "d17", "d18", \
|
||
|
"d19", "d20", "d21", "d22", "d23", \
|
||
|
"d24", "d28", "d29", "d30", "d31");
|
||
|
ptr += 32;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(nWidthMatchFlag == 1)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
for(m=0; m<32; m++)
|
||
|
{
|
||
|
if((i*32 + m) >= nHeight)
|
||
|
{
|
||
|
ptr += 32;
|
||
|
continue;
|
||
|
}
|
||
|
dstAsm = bufferU;
|
||
|
srcAsm = ptr;
|
||
|
lineNum = i*32 + m; //line num
|
||
|
offset = lineNum*nLineStride + j*32;
|
||
|
|
||
|
asm volatile (
|
||
|
"vld1.8 {d0 - d3}, [%[srcAsm]] \n\t"
|
||
|
"vst1.8 {d0 - d3}, [%[dstAsm]] \n\t"
|
||
|
: [dstAsm] "+r" (dstAsm), [srcAsm] "+r" (srcAsm)
|
||
|
: //[srcY] "r" (srcY)
|
||
|
: "cc", "memory", "d0", "d1", "d2", "d3", \
|
||
|
"d4", "d5", "d6", "d16", "d17", "d18", \
|
||
|
"d19", "d20", "d21", "d22", "d23", \
|
||
|
"d24", "d28", "d29", "d30", "d31");
|
||
|
ptr += 32;
|
||
|
for(k=0; k<32; k++)
|
||
|
{
|
||
|
if((j*32+ k) >= nLineStride)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
pDst[offset+k] = bufferU[k];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ConvertMb32420ToNv21C(char* pSrc,char* pDst,int nPicWidth, int nPicHeight)
|
||
|
{
|
||
|
int nMbWidth = 0;
|
||
|
int nMbHeight = 0;
|
||
|
int i = 0;
|
||
|
int j = 0;
|
||
|
int m = 0;
|
||
|
int n = 0;
|
||
|
int k = 0;
|
||
|
int nLineStride=0;
|
||
|
int lineNum = 0;
|
||
|
int offset = 0;
|
||
|
int maxNum = 0;
|
||
|
char* ptr = NULL;
|
||
|
char bufferV[16], bufferU[16];
|
||
|
int nWidth = 0;
|
||
|
int nHeight = 0;
|
||
|
|
||
|
nWidth = (nPicWidth+1)/2;
|
||
|
nHeight = (nPicHeight+1)/2;
|
||
|
|
||
|
nLineStride = (nWidth*2 + 15) &~15;
|
||
|
nMbWidth = (nWidth*2+31)&~31;
|
||
|
nMbWidth /= 32;
|
||
|
|
||
|
nMbHeight = (nHeight+31)&~31;
|
||
|
nMbHeight /= 32;
|
||
|
|
||
|
ptr = pSrc;
|
||
|
|
||
|
for(i=0; i<nMbHeight; i++)
|
||
|
{
|
||
|
char *dst0Asm = NULL;
|
||
|
char *dst1Asm = NULL;
|
||
|
char *srcAsm = NULL;
|
||
|
CEDARC_UNUSE(dst0Asm);
|
||
|
CEDARC_UNUSE(dst1Asm);
|
||
|
CEDARC_UNUSE(srcAsm);
|
||
|
for(j=0; j<nMbWidth; j++)
|
||
|
{
|
||
|
for(m=0; m<32; m++)
|
||
|
{
|
||
|
if((i*32 + m) >= nHeight)
|
||
|
{
|
||
|
ptr += 32;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
dst0Asm = bufferU;
|
||
|
dst1Asm = bufferV;
|
||
|
srcAsm = ptr;
|
||
|
lineNum = i*32 + m; //line num
|
||
|
offset = lineNum*nLineStride + j*32;
|
||
|
|
||
|
asm volatile(
|
||
|
"vld2.8 {d0-d3}, [%[srcAsm]] \n\t"
|
||
|
"vst1.8 {d0,d1}, [%[dst0Asm]] \n\t"
|
||
|
"vst1.8 {d2,d3}, [%[dst1Asm]] \n\t"
|
||
|
: [dst0Asm] "+r" (dst0Asm), [dst1Asm] "+r" (dst1Asm), [srcAsm] "+r" (srcAsm)
|
||
|
: //[srcY] "r" (srcY)
|
||
|
: "cc", "memory", "d0", "d1", "d2", "d3", \
|
||
|
"d4", "d5", "d6", "d16", "d17", "d18", \
|
||
|
"d19", "d20", "d21", "d22", "d23", "d24", \
|
||
|
"d28", "d29", "d30", "d31"
|
||
|
);
|
||
|
ptr += 32;
|
||
|
|
||
|
for(k=0; k<16; k++)
|
||
|
{
|
||
|
if((j*32+ 2*k) >= nLineStride)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
pDst[offset+2*k] = bufferV[k];
|
||
|
pDst[offset+2*k+1] = bufferU[k];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ConvertMb32422ToNv21C(char* pSrc,char* pDst,int nPicWidth, int nPicHeight)
|
||
|
{
|
||
|
int nMbWidth = 0;
|
||
|
int nMbHeight = 0;
|
||
|
int i = 0;
|
||
|
int j = 0;
|
||
|
int m = 0;
|
||
|
int n = 0;
|
||
|
int k = 0;
|
||
|
int nLineStride=0;
|
||
|
int lineNum = 0;
|
||
|
int offset = 0;
|
||
|
int maxNum = 0;
|
||
|
char* ptr = NULL;
|
||
|
char bufferV[16], bufferU[16];
|
||
|
int nWidth = 0;
|
||
|
int nHeight = 0;
|
||
|
|
||
|
nWidth = (nPicWidth+1)/2;
|
||
|
nHeight = (nPicHeight+1)/2;
|
||
|
|
||
|
nLineStride = (nWidth*2 + 15) &~15;
|
||
|
nMbWidth = (nWidth*2+31)&~31;
|
||
|
nMbWidth /= 32;
|
||
|
|
||
|
nMbHeight = (nHeight*2+31)&~31;
|
||
|
nMbHeight /= 32;
|
||
|
|
||
|
ptr = pSrc;
|
||
|
|
||
|
for(i=0; i<nMbHeight; i++)
|
||
|
{
|
||
|
char *dst0Asm = NULL;
|
||
|
char *dst1Asm = NULL;
|
||
|
char *srcAsm = NULL;
|
||
|
CEDARC_UNUSE(dst0Asm);
|
||
|
CEDARC_UNUSE(dst1Asm);
|
||
|
CEDARC_UNUSE(srcAsm);
|
||
|
for(j=0; j<nMbWidth; j++)
|
||
|
{
|
||
|
for(m=0; m<16; m++)
|
||
|
{
|
||
|
if((i*16 + m) >= nHeight)
|
||
|
{
|
||
|
ptr += 64;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
dst0Asm = bufferU;
|
||
|
dst1Asm = bufferV;
|
||
|
srcAsm = ptr;
|
||
|
lineNum = i*16 + m; //line num
|
||
|
offset = lineNum*nLineStride + j*32;
|
||
|
|
||
|
asm volatile(
|
||
|
"vld2.8 {d0-d3}, [%[srcAsm]] \n\t"
|
||
|
"vst1.8 {d0,d1}, [%[dst0Asm]] \n\t"
|
||
|
"vst1.8 {d2,d3}, [%[dst1Asm]] \n\t"
|
||
|
: [dst0Asm] "+r" (dst0Asm), [dst1Asm] "+r" (dst1Asm), [srcAsm] "+r" (srcAsm)
|
||
|
: //[srcY] "r" (srcY)
|
||
|
: "cc", "memory", "d0", "d1", "d2", "d3", "d4", \
|
||
|
"d5", "d6", "d16", "d17", "d18", "d19", "d20", \
|
||
|
"d21", "d22", "d23", "d24", "d28", "d29", "d30", "d31"
|
||
|
);
|
||
|
ptr += 64;
|
||
|
|
||
|
for(k=0; k<16; k++)
|
||
|
{
|
||
|
if((j*32+ 2*k) >= nLineStride)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
pDst[offset+2*k] = bufferV[k];
|
||
|
pDst[offset+2*k+1] = bufferU[k];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void ConvertMb32420ToYv12C(char* pSrc,char* pDstU, char*pDstV,int nPicWidth, int nPicHeight)
|
||
|
{
|
||
|
int nMbWidth = 0;
|
||
|
int nMbHeight = 0;
|
||
|
int i = 0;
|
||
|
int j = 0;
|
||
|
int m = 0;
|
||
|
int n = 0;
|
||
|
int k = 0;
|
||
|
int nLineStride=0;
|
||
|
int lineNum = 0;
|
||
|
int offset = 0;
|
||
|
int maxNum = 0;
|
||
|
char* ptr = NULL;
|
||
|
int nWidth = 0;
|
||
|
int nHeight = 0;
|
||
|
char bufferV[16], bufferU[16];
|
||
|
int nWidthMatchFlag = 0;
|
||
|
int nCopyMbWidth = 0;
|
||
|
|
||
|
nWidth = (nPicWidth+1)/2;
|
||
|
nHeight = (nPicHeight+1)/2;
|
||
|
|
||
|
//nLineStride = ((nPicWidth+ 15) &~15)/2;
|
||
|
nLineStride = (nWidth+7)&~7;
|
||
|
|
||
|
nMbWidth = (nWidth*2+31)&~31;
|
||
|
nMbWidth /= 32;
|
||
|
|
||
|
nMbHeight = (nHeight+31)&~31;
|
||
|
nMbHeight /= 32;
|
||
|
|
||
|
ptr = pSrc;
|
||
|
|
||
|
nWidthMatchFlag = 0;
|
||
|
nCopyMbWidth = nMbWidth-1;
|
||
|
|
||
|
if(nMbWidth*16 == nLineStride)
|
||
|
{
|
||
|
nWidthMatchFlag = 1;
|
||
|
nCopyMbWidth = nMbWidth;
|
||
|
}
|
||
|
|
||
|
for(i=0; i<nMbHeight; i++)
|
||
|
{
|
||
|
char *dst0Asm = NULL;
|
||
|
char *dst1Asm = NULL;
|
||
|
char *srcAsm = NULL;
|
||
|
CEDARC_UNUSE(dst0Asm);
|
||
|
CEDARC_UNUSE(dst1Asm);
|
||
|
CEDARC_UNUSE(srcAsm);
|
||
|
for(j=0; j<nCopyMbWidth; j++)
|
||
|
{
|
||
|
for(m=0; m<32; m++)
|
||
|
{
|
||
|
if((i*32 + m) >= nHeight)
|
||
|
{
|
||
|
ptr += 32;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
srcAsm = ptr;
|
||
|
lineNum = i*32 + m; //line num
|
||
|
offset = lineNum*nLineStride + j*16;
|
||
|
dst0Asm = pDstU+offset;
|
||
|
dst1Asm = pDstV+offset;
|
||
|
asm volatile(
|
||
|
"vld2.8 {d0-d3}, [%[srcAsm]] \n\t"
|
||
|
"vst1.8 {d0,d1}, [%[dst0Asm]] \n\t"
|
||
|
"vst1.8 {d2,d3}, [%[dst1Asm]] \n\t"
|
||
|
: [dst0Asm] "+r" (dst0Asm), [dst1Asm] "+r" (dst1Asm), [srcAsm] "+r" (srcAsm)
|
||
|
: //[srcY] "r" (srcY)
|
||
|
: "cc", "memory", "d0", "d1", "d2", "d3", \
|
||
|
"d4", "d5", "d6", "d16", "d17", "d18", \
|
||
|
"d19", "d20", "d21", "d22", "d23", "d24", \
|
||
|
"d28", "d29", "d30", "d31"
|
||
|
);
|
||
|
ptr += 32;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(nWidthMatchFlag == 1)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
for(m=0; m<32; m++)
|
||
|
{
|
||
|
if((i*32 + m) >= nHeight)
|
||
|
{
|
||
|
ptr += 32;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
srcAsm = ptr;
|
||
|
lineNum = i*32 + m; //line num
|
||
|
offset = lineNum*nLineStride + j*16;
|
||
|
dst0Asm = bufferU;
|
||
|
dst1Asm = bufferV;
|
||
|
asm volatile(
|
||
|
"vld2.8 {d0-d3}, [%[srcAsm]] \n\t"
|
||
|
"vst1.8 {d0,d1}, [%[dst0Asm]] \n\t"
|
||
|
"vst1.8 {d2,d3}, [%[dst1Asm]] \n\t"
|
||
|
: [dst0Asm] "+r" (dst0Asm), [dst1Asm] "+r" (dst1Asm), [srcAsm] "+r" (srcAsm)
|
||
|
: //[srcY] "r" (srcY)
|
||
|
: "cc", "memory", "d0", "d1", "d2", "d3", "d4", \
|
||
|
"d5", "d6", "d16", "d17", "d18", "d19", \
|
||
|
"d20", "d21", "d22", "d23", "d24", "d28", \
|
||
|
"d29", "d30", "d31"
|
||
|
);
|
||
|
ptr += 32;
|
||
|
|
||
|
for(k=0; k<16; k++)
|
||
|
{
|
||
|
if((j*16+ k) >= nLineStride)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
pDstV[offset+k] = bufferV[k];
|
||
|
pDstU[offset+k] = bufferU[k];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ConvertMb32422ToYv12C(char* pSrc,char* pDstU, char*pDstV,int nPicWidth, int nPicHeight)
|
||
|
{
|
||
|
int nMbWidth = 0;
|
||
|
int nMbHeight = 0;
|
||
|
int i = 0;
|
||
|
int j = 0;
|
||
|
int m = 0;
|
||
|
int n = 0;
|
||
|
int k = 0;
|
||
|
int nLineStride=0;
|
||
|
int lineNum = 0;
|
||
|
int offset = 0;
|
||
|
int maxNum = 0;
|
||
|
char* ptr = NULL;
|
||
|
|
||
|
int nWidth = 0;
|
||
|
int nHeight = 0;
|
||
|
char bufferV[16], bufferU[16];
|
||
|
int nWidthMatchFlag = 0;
|
||
|
int nCopyMbWidth = 0;
|
||
|
|
||
|
nWidth = (nPicWidth+1)/2;
|
||
|
nHeight = (nPicHeight+1)/2;
|
||
|
|
||
|
nLineStride = (nWidth+7)&~7;
|
||
|
|
||
|
nMbWidth = (nWidth*2+31)&~31;
|
||
|
nMbWidth /= 32;
|
||
|
|
||
|
nMbHeight = (nHeight*2+31)&~31;
|
||
|
nMbHeight /= 32;
|
||
|
|
||
|
ptr = pSrc;
|
||
|
|
||
|
nWidthMatchFlag = 0;
|
||
|
nCopyMbWidth = nMbWidth-1;
|
||
|
|
||
|
if(nMbWidth*16 == nLineStride)
|
||
|
{
|
||
|
nWidthMatchFlag = 1;
|
||
|
nCopyMbWidth = nMbWidth;
|
||
|
}
|
||
|
|
||
|
for(i=0; i<nMbHeight; i++)
|
||
|
{
|
||
|
char *dst0Asm = NULL;
|
||
|
char *dst1Asm = NULL;
|
||
|
char *srcAsm = NULL;
|
||
|
CEDARC_UNUSE(dst0Asm);
|
||
|
CEDARC_UNUSE(dst1Asm);
|
||
|
CEDARC_UNUSE(srcAsm);
|
||
|
for(j=0; j<nCopyMbWidth; j++)
|
||
|
{
|
||
|
for(m=0; m<16; m++)
|
||
|
{
|
||
|
if((i*16 + m) >= nHeight)
|
||
|
{
|
||
|
ptr += 64;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
srcAsm = ptr;
|
||
|
lineNum = i*16 + m; //line num
|
||
|
offset = lineNum*nLineStride + j*16;
|
||
|
dst0Asm = pDstU+offset;
|
||
|
dst1Asm = pDstV+offset;
|
||
|
|
||
|
asm volatile(
|
||
|
"vld2.8 {d0-d3}, [%[srcAsm]] \n\t"
|
||
|
"vst1.8 {d0,d1}, [%[dst0Asm]] \n\t"
|
||
|
"vst1.8 {d2,d3}, [%[dst1Asm]] \n\t"
|
||
|
: [dst0Asm] "+r" (dst0Asm), [dst1Asm] "+r" (dst1Asm), [srcAsm] "+r" (srcAsm)
|
||
|
: //[srcY] "r" (srcY)
|
||
|
: "cc", "memory", "d0", "d1", "d2", "d3", "d4", \
|
||
|
"d5", "d6", "d16", "d17", "d18", "d19", "d20", \
|
||
|
"d21", "d22", "d23", "d24", "d28", "d29", "d30", "d31"
|
||
|
);
|
||
|
ptr += 64;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(nWidthMatchFlag==1)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
for(m=0; m<16; m++)
|
||
|
{
|
||
|
if((i*16 + m) >= nHeight)
|
||
|
{
|
||
|
ptr += 64;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
dst0Asm = bufferU;
|
||
|
dst1Asm = bufferV;
|
||
|
srcAsm = ptr;
|
||
|
lineNum = i*16 + m; //line num
|
||
|
offset = lineNum*nLineStride + j*16;
|
||
|
|
||
|
asm volatile(
|
||
|
"vld2.8 {d0-d3}, [%[srcAsm]] \n\t"
|
||
|
"vst1.8 {d0,d1}, [%[dst0Asm]] \n\t"
|
||
|
"vst1.8 {d2,d3}, [%[dst1Asm]] \n\t"
|
||
|
: [dst0Asm] "+r" (dst0Asm), [dst1Asm] "+r" (dst1Asm), [srcAsm] "+r" (srcAsm)
|
||
|
: //[srcY] "r" (srcY)
|
||
|
: "cc", "memory", "d0", "d1", "d2", "d3", "d4", \
|
||
|
"d5", "d6", "d16", "d17", "d18", "d19", "d20", \
|
||
|
"d21", "d22", "d23", "d24", "d28", "d29", "d30", "d31"
|
||
|
);
|
||
|
ptr += 64;
|
||
|
|
||
|
for(k=0; k<16; k++)
|
||
|
{
|
||
|
if((j*16+ k) >= nLineStride)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
pDstV[offset+k] = bufferV[k];
|
||
|
pDstU[offset+k] = bufferU[k];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
//****************************************************************//
|
||
|
//****************************************************************//
|
||
|
|
||
|
void ConvertPixelFormat(VideoPicture* pPictureIn, VideoPicture* pPictureOut)
|
||
|
{
|
||
|
int nMemSizeY = 0;
|
||
|
int nMemSizeC = 0;
|
||
|
int nLineStride = 0;
|
||
|
int nHeight16Align = 0;
|
||
|
//int nHeight32Align = 0;
|
||
|
//int nHeight64Align = 0;
|
||
|
int nHeight = 0;
|
||
|
int i = 0;
|
||
|
int j = 0;
|
||
|
|
||
|
nHeight = pPictureIn->nHeight;
|
||
|
nLineStride = (pPictureIn->nWidth+15) &~15;
|
||
|
nHeight16Align = (nHeight+15) & ~15;
|
||
|
//nHeight32Align = (nHeight+31) & ~31;
|
||
|
//nHeight64Align = (nHeight+63) & ~63;
|
||
|
|
||
|
pPictureOut->nLineStride = (pPictureIn->nWidth+15) & ~15;
|
||
|
pPictureOut->nHeight = pPictureIn->nHeight;
|
||
|
pPictureOut->nWidth = pPictureIn->nWidth;
|
||
|
pPictureOut->nTopOffset = pPictureIn->nTopOffset;
|
||
|
pPictureOut->nBottomOffset = pPictureIn->nBottomOffset;
|
||
|
pPictureOut->nLeftOffset = pPictureIn->nLeftOffset;
|
||
|
pPictureOut->nRightOffset = pPictureIn->nRightOffset;
|
||
|
|
||
|
if(pPictureOut->ePixelFormat==PIXEL_FORMAT_YV12)
|
||
|
{
|
||
|
#ifdef CEDARX_DECODER_ARM32
|
||
|
if(pPictureIn->ePixelFormat == PIXEL_FORMAT_YUV_MB32_420)
|
||
|
{
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
|
||
|
ConvertMb32420ToNv21Y(pPictureIn->pData0,pPictureOut->pData0, \
|
||
|
pPictureIn->nWidth, pPictureIn->nHeight);
|
||
|
ConvertMb32420ToYv12C(pPictureIn->pData1, \
|
||
|
(char*)(pPictureOut->pData0+nMemSizeY+nMemSizeC), \
|
||
|
(char*)(pPictureOut->pData0+nMemSizeY), \
|
||
|
pPictureIn->nWidth, pPictureIn->nHeight);
|
||
|
|
||
|
}
|
||
|
else if(pPictureIn->ePixelFormat == PIXEL_FORMAT_YUV_MB32_422)
|
||
|
{
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
ConvertMb32420ToNv21Y(pPictureIn->pData0,pPictureOut->pData0, \
|
||
|
pPictureIn->nWidth, pPictureIn->nHeight);
|
||
|
ConvertMb32422ToYv12C(pPictureIn->pData1, \
|
||
|
(char*)(pPictureOut->pData0+nMemSizeY+nMemSizeC), \
|
||
|
(char*)(pPictureOut->pData0+nMemSizeY), \
|
||
|
pPictureIn->nWidth, pPictureIn->nHeight);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if(pPictureIn->ePixelFormat == PIXEL_FORMAT_NV21)
|
||
|
{
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
memcpy(pPictureOut->pData0, pPictureIn->pData0, nMemSizeY);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
pPictureOut->pData1 = pPictureOut->pData0 + nMemSizeY;
|
||
|
pPictureOut->pData2 = pPictureOut->pData1 + nMemSizeC;
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
|
||
|
for(i=0; i<(pPictureIn->nHeight+1)/2; i++)
|
||
|
{
|
||
|
for(j=0; j<(pPictureIn->nWidth+1)/2; j++)
|
||
|
{
|
||
|
pPictureOut->pData1[i*nLineStride/2+j] = \
|
||
|
pPictureIn->pData1[i*nLineStride+2*j];
|
||
|
pPictureOut->pData2[i*nLineStride/2+j] = \
|
||
|
pPictureIn->pData1[i*nLineStride+2*j+1];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if(pPictureIn->ePixelFormat == PIXEL_FORMAT_YUV_PLANER_420)
|
||
|
{
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
memcpy(pPictureOut->pData0, pPictureIn->pData0, nMemSizeY);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
memcpy(pPictureOut->pData0+nMemSizeY, \
|
||
|
pPictureIn->pData0+nMemSizeY+nMemSizeC, nMemSizeC);
|
||
|
memcpy(pPictureOut->pData0+nMemSizeY+nMemSizeC, \
|
||
|
pPictureIn->pData0+nMemSizeY, nMemSizeC);
|
||
|
}
|
||
|
}
|
||
|
else if(pPictureOut->ePixelFormat==PIXEL_FORMAT_NV21)
|
||
|
{
|
||
|
#ifdef CEDARX_DECODER_ARM32
|
||
|
if(pPictureIn->ePixelFormat == PIXEL_FORMAT_YUV_MB32_420)
|
||
|
{
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
//nMemSizeY = nLineStride*nHeight;
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
ConvertMb32420ToNv21Y(pPictureIn->pData0,pPictureOut->pData0, \
|
||
|
pPictureIn->nWidth, pPictureIn->nHeight);
|
||
|
ConvertMb32420ToNv21C(pPictureIn->pData1, \
|
||
|
pPictureOut->pData0+nMemSizeY, \
|
||
|
pPictureIn->nWidth, pPictureIn->nHeight);
|
||
|
}
|
||
|
else if(pPictureIn->ePixelFormat == PIXEL_FORMAT_YUV_MB32_422)
|
||
|
{
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
ConvertMb32420ToNv21Y(pPictureIn->pData0,pPictureOut->pData0, \
|
||
|
pPictureIn->nWidth, pPictureIn->nHeight);
|
||
|
ConvertMb32422ToNv21C(pPictureIn->pData1, \
|
||
|
(char*)(pPictureOut->pData0+nMemSizeY), \
|
||
|
pPictureIn->nWidth, pPictureIn->nHeight);
|
||
|
}
|
||
|
#endif
|
||
|
if(pPictureIn->ePixelFormat == PIXEL_FORMAT_YV12)
|
||
|
{
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
memcpy(pPictureOut->pData0, pPictureIn->pData0, nMemSizeY);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
pPictureIn->pData2 = pPictureIn->pData1 + nMemSizeC;
|
||
|
pPictureOut->pData1 = pPictureOut->pData0 + nMemSizeY;
|
||
|
|
||
|
for(i=0; i<(pPictureIn->nHeight+1)/2; i++)
|
||
|
{
|
||
|
for(j=0; j<(pPictureIn->nWidth+1)/2; j++)
|
||
|
{
|
||
|
pPictureOut->pData1[i*nLineStride+2*j] = \
|
||
|
pPictureIn->pData1[i*nLineStride/2+j];
|
||
|
pPictureOut->pData1[i*nLineStride+2*j+1] = \
|
||
|
pPictureIn->pData2[i*nLineStride/2+j];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if(pPictureIn->ePixelFormat == PIXEL_FORMAT_YUV_PLANER_420)
|
||
|
{
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
memcpy(pPictureOut->pData0, pPictureIn->pData0, nMemSizeY);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
pPictureIn->pData2 = pPictureIn->pData1 + nMemSizeC;
|
||
|
pPictureOut->pData1 = pPictureOut->pData0 + nMemSizeY;
|
||
|
|
||
|
for(i=0; i<(pPictureIn->nHeight+1)/2; i++)
|
||
|
{
|
||
|
for(j=0; j<(pPictureIn->nWidth+1)/2; j++)
|
||
|
{
|
||
|
pPictureOut->pData1[i*nLineStride+2*j] = \
|
||
|
pPictureIn->pData2[i*nLineStride/2+j];
|
||
|
pPictureOut->pData1[i*nLineStride+2*j+1] = \
|
||
|
pPictureIn->pData1[i*nLineStride/2+j];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//AdapterMemFlushCache((void*)pPictureOut->pData0, nMemSizeY+2*nMemSizeC);
|
||
|
}
|
||
|
|
||
|
int RotatePicture0Degree(VideoPicture* pPictureIn,
|
||
|
VideoPicture* pPictureOut,
|
||
|
int nGpuYAlign,
|
||
|
int nGpuCAlign)
|
||
|
{
|
||
|
int nMemSizeY = 0;
|
||
|
int nMemSizeC = 0;
|
||
|
int nLineStride = 0;
|
||
|
int ePixelFormat = 0;
|
||
|
int nHeight16Align = 0;
|
||
|
int nHeight32Align = 0;
|
||
|
int nHeight64Align = 0;
|
||
|
|
||
|
nLineStride = pPictureIn->nLineStride;
|
||
|
ePixelFormat = pPictureIn->ePixelFormat;
|
||
|
nHeight16Align = (pPictureIn->nHeight+15) &~15;
|
||
|
nHeight32Align = (pPictureIn->nHeight+31) &~31;
|
||
|
nHeight64Align = (pPictureIn->nHeight+63) &~63;
|
||
|
|
||
|
switch(pPictureOut->ePixelFormat)
|
||
|
{
|
||
|
case PIXEL_FORMAT_YUV_PLANER_420:
|
||
|
case PIXEL_FORMAT_YUV_PLANER_422:
|
||
|
case PIXEL_FORMAT_YUV_PLANER_444:
|
||
|
case PIXEL_FORMAT_YV12:
|
||
|
case PIXEL_FORMAT_NV21:
|
||
|
//* for decoder,
|
||
|
//* height of Y component is required to be 16 aligned,
|
||
|
//* for example, 1080 becomes to 1088.
|
||
|
//* width and height of U or V component are both required to be 8 aligned.
|
||
|
|
||
|
//* nLineStride should be 16 aligned.
|
||
|
nMemSizeY = nLineStride*nHeight16Align;
|
||
|
if(ePixelFormat == PIXEL_FORMAT_YUV_PLANER_420 ||
|
||
|
ePixelFormat == PIXEL_FORMAT_YV12 ||
|
||
|
ePixelFormat == PIXEL_FORMAT_NV21)
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
else if(ePixelFormat == PIXEL_FORMAT_YUV_PLANER_422)
|
||
|
nMemSizeC = nMemSizeY>>1;
|
||
|
else
|
||
|
nMemSizeC = nMemSizeY; //* PIXEL_FORMAT_YUV_PLANER_444
|
||
|
|
||
|
//* copy relay on gpuYAlign and gpuCAlign if the format is YV12
|
||
|
if(pPictureOut->ePixelFormat == PIXEL_FORMAT_YV12)
|
||
|
{
|
||
|
//* we can memcpy directly if gpuYAlign is 16 and gpuCAlign is 8
|
||
|
if(nGpuYAlign == 16 && nGpuCAlign == 8)
|
||
|
{
|
||
|
memcpy(pPictureOut->pData0, pPictureIn->pData0, nMemSizeY+nMemSizeC*2);
|
||
|
}
|
||
|
else if(nGpuYAlign == 16 && nGpuCAlign == 16)
|
||
|
{
|
||
|
int i;
|
||
|
int nCpyWidthSize = pPictureOut->nLineStride;
|
||
|
char* pDstData = pPictureOut->pData0;
|
||
|
char* pSrcData = pPictureIn->pData0;
|
||
|
//* cpy y
|
||
|
for(i = 0;i < pPictureIn->nHeight;i++)
|
||
|
{
|
||
|
memcpy(pDstData,pSrcData,pPictureIn->nWidth);
|
||
|
pDstData += nCpyWidthSize;
|
||
|
pSrcData += pPictureIn->nLineStride;
|
||
|
}
|
||
|
//* cpy v
|
||
|
pDstData = pPictureOut->pData0 + pPictureOut->nLineStride*pPictureOut->nHeight;
|
||
|
pSrcData = pPictureIn->pData0 + nMemSizeY;
|
||
|
nCpyWidthSize = (nCpyWidthSize/2 + 15) & ~15;
|
||
|
|
||
|
for(i = 0;i < pPictureIn->nHeight/2;i++)
|
||
|
{
|
||
|
memcpy(pDstData,pSrcData,pPictureIn->nWidth/2);
|
||
|
pDstData += nCpyWidthSize;
|
||
|
pSrcData += pPictureIn->nLineStride/2;
|
||
|
}
|
||
|
//* cpy u
|
||
|
int nCSize = nCpyWidthSize*pPictureOut->nHeight/2;
|
||
|
pDstData = pPictureOut->pData0 + \
|
||
|
pPictureOut->nLineStride*pPictureOut->nHeight + nCSize;
|
||
|
pSrcData = pPictureIn->pData0 + nMemSizeY+nMemSizeC;
|
||
|
for(i = 0;i < pPictureIn->nHeight/2;i++)
|
||
|
{
|
||
|
memcpy(pDstData,pSrcData,pPictureIn->nWidth/2);
|
||
|
pDstData += nCpyWidthSize;
|
||
|
pSrcData += pPictureIn->nLineStride/2;
|
||
|
}
|
||
|
}
|
||
|
else if(nGpuYAlign == 32 && nGpuCAlign == 16)
|
||
|
{
|
||
|
int i;
|
||
|
int nCpyWidthSize = pPictureOut->nLineStride;
|
||
|
char* pDstData = pPictureOut->pData0;
|
||
|
char* pSrcData = pPictureIn->pData0;
|
||
|
//* cpy y
|
||
|
for(i = 0;i < pPictureIn->nHeight;i++)
|
||
|
{
|
||
|
memcpy(pDstData,pSrcData,pPictureIn->nWidth);
|
||
|
pDstData += nCpyWidthSize;
|
||
|
pSrcData += pPictureIn->nLineStride;
|
||
|
}
|
||
|
//* cpy v
|
||
|
pDstData = pPictureOut->pData0 + \
|
||
|
pPictureOut->nLineStride*pPictureOut->nHeight;
|
||
|
pSrcData = pPictureIn->pData0 + nMemSizeY;
|
||
|
for(i = 0;i < pPictureIn->nHeight/2;i++)
|
||
|
{
|
||
|
memcpy(pDstData,pSrcData,pPictureIn->nWidth/2);
|
||
|
pDstData += nCpyWidthSize/2;
|
||
|
pSrcData += pPictureIn->nLineStride/2;
|
||
|
}
|
||
|
//* cpy u
|
||
|
pDstData = pPictureOut->pData0 + \
|
||
|
pPictureOut->nLineStride*pPictureOut->nHeight*5/4;
|
||
|
pSrcData = pPictureIn->pData0 + nMemSizeY+nMemSizeC;
|
||
|
for(i = 0;i < pPictureIn->nHeight/2;i++)
|
||
|
{
|
||
|
memcpy(pDstData,pSrcData,pPictureIn->nWidth/2);
|
||
|
pDstData += nCpyWidthSize/2;
|
||
|
pSrcData += pPictureIn->nLineStride/2;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
loge("the nGpuYAlign[%d] and nGpuCAlign[%d] is not surpport!", \
|
||
|
nGpuYAlign,nGpuCAlign);
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
memcpy(pPictureOut->pData0, pPictureIn->pData0, nMemSizeY+nMemSizeC*2);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case PIXEL_FORMAT_YUV_MB32_420:
|
||
|
case PIXEL_FORMAT_YUV_MB32_422:
|
||
|
case PIXEL_FORMAT_YUV_MB32_444:
|
||
|
//* for decoder,
|
||
|
//* height of Y component is required to be 32 aligned.
|
||
|
//* height of UV component are both required to be 32 aligned.
|
||
|
//* nLineStride should be 32 aligned.
|
||
|
nMemSizeY = nLineStride*nHeight32Align;
|
||
|
if(ePixelFormat == PIXEL_FORMAT_YUV_MB32_420)
|
||
|
nMemSizeC = nLineStride*nHeight64Align/4;
|
||
|
else if(ePixelFormat == PIXEL_FORMAT_YUV_MB32_422)
|
||
|
nMemSizeC = nLineStride*nHeight64Align/2;
|
||
|
else
|
||
|
nMemSizeC = nLineStride*nHeight64Align;
|
||
|
|
||
|
memcpy(pPictureOut->pData0, pPictureIn->pData0, nMemSizeY);
|
||
|
memcpy(pPictureOut->pData1, pPictureIn->pData1, nMemSizeC*2);
|
||
|
//AdapterMemFlushCache((void*)pPictureOut->pData0, nMemSizeY);
|
||
|
//AdapterMemFlushCache((void*)pPictureOut->pData1, 2*nMemSizeC);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
loge("pixel format incorrect, ePixelFormat=%d", ePixelFormat);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int RotatePicture90Degree(VideoPicture* pPictureIn, VideoPicture* pPictureOut)
|
||
|
{
|
||
|
int nLeftOffset = 0;
|
||
|
int nRightOffset = 0;
|
||
|
int nBottomOffset = 0;
|
||
|
int nTopOffset = 0;
|
||
|
|
||
|
pPictureOut->nLineStride = (pPictureIn->nHeight+15) &~15;
|
||
|
pPictureOut->nHeight = pPictureIn->nWidth;
|
||
|
pPictureOut->nWidth = pPictureIn->nHeight;
|
||
|
|
||
|
if(pPictureOut->ePixelFormat==PIXEL_FORMAT_YV12
|
||
|
||(pPictureOut->ePixelFormat == PIXEL_FORMAT_NV21)
|
||
|
||(pPictureOut->ePixelFormat == PIXEL_FORMAT_NV12))
|
||
|
{
|
||
|
int i;
|
||
|
int j;
|
||
|
for(j=0; j<pPictureIn->nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<pPictureIn->nWidth; i++)
|
||
|
{
|
||
|
pPictureOut->pData0[i*pPictureOut->nLineStride+pPictureIn->nHeight-j-1] = \
|
||
|
pPictureIn->pData0[j*pPictureIn->nLineStride+i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int nHeight = pPictureIn->nHeight/2;
|
||
|
int nWidth = pPictureIn->nWidth/2;
|
||
|
int nLineStride = pPictureIn->nLineStride/2;
|
||
|
int nRotateLineStride = pPictureOut->nLineStride/2;
|
||
|
|
||
|
int nMemSizeY = 0;
|
||
|
int nMemSizeC = 0;
|
||
|
if(pPictureOut->ePixelFormat==PIXEL_FORMAT_YV12)
|
||
|
{
|
||
|
nMemSizeY = pPictureIn->nLineStride*((pPictureIn->nHeight+15)&~15);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
pPictureIn->pData2 = pPictureIn->pData1 + nMemSizeC;
|
||
|
|
||
|
nMemSizeY = pPictureOut->nLineStride*((pPictureOut->nHeight+15)&~15);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
pPictureOut->pData1 = pPictureOut->pData0+ nMemSizeY;
|
||
|
pPictureOut->pData2 = pPictureOut->pData1+ nMemSizeC;
|
||
|
|
||
|
for(j=0; j<nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<nWidth; i++)
|
||
|
{
|
||
|
pPictureOut->pData1[i*nRotateLineStride+nHeight-j-1] = \
|
||
|
pPictureIn->pData1[j*nLineStride+i];
|
||
|
pPictureOut->pData2[i*nRotateLineStride+nHeight-j-1] = \
|
||
|
pPictureIn->pData2[j*nLineStride+i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if((pPictureOut->ePixelFormat==PIXEL_FORMAT_NV21)|| \
|
||
|
(pPictureOut->ePixelFormat==PIXEL_FORMAT_NV12))
|
||
|
{
|
||
|
nMemSizeY = pPictureIn->nLineStride*((pPictureIn->nHeight+15)&~15);
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
|
||
|
nMemSizeY = pPictureOut->nLineStride*((pPictureOut->nHeight+15)&~15);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
CEDARC_UNUSE(nMemSizeC);
|
||
|
pPictureOut->pData1 = pPictureOut->pData0+ nMemSizeY;
|
||
|
|
||
|
for(j=0; j<nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<nWidth; i++)
|
||
|
{
|
||
|
pPictureOut->pData1[2*i*nRotateLineStride+2*nHeight-(2*j+1)-1] = \
|
||
|
pPictureIn->pData1[2*j*nLineStride+2*i];
|
||
|
pPictureOut->pData1[2*i*nRotateLineStride+2*nHeight-(2*j)-1] = \
|
||
|
pPictureIn->pData1[2*j*nLineStride+2*i+1];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//AdapterMemFlushCache((void*)pPictureOut->pData0, nMemSizeY+2*nMemSizeC);
|
||
|
|
||
|
nLeftOffset = pPictureIn->nLeftOffset;
|
||
|
nRightOffset = pPictureIn->nWidth - pPictureIn->nRightOffset;
|
||
|
nTopOffset = pPictureIn->nTopOffset;
|
||
|
nBottomOffset = pPictureIn->nHeight - pPictureIn->nTopOffset;
|
||
|
|
||
|
pPictureOut->nLeftOffset = nBottomOffset;
|
||
|
pPictureOut->nBottomOffset = nRightOffset;
|
||
|
pPictureOut->nRightOffset = nTopOffset;
|
||
|
pPictureOut->nTopOffset = nLeftOffset;
|
||
|
pPictureOut->nRightOffset = pPictureOut->nWidth - pPictureOut->nRightOffset;
|
||
|
pPictureOut->nBottomOffset = pPictureOut->nHeight -pPictureOut->nBottomOffset;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int RotatePicture180Degree(VideoPicture* pPictureIn, VideoPicture* pPictureOut)
|
||
|
{
|
||
|
//int nRotateLineStride = 0;
|
||
|
int nLeftOffset = 0;
|
||
|
int nRightOffset = 0;
|
||
|
int nBottomOffset = 0;
|
||
|
int nTopOffset = 0;
|
||
|
|
||
|
pPictureOut->nLineStride = pPictureIn->nLineStride;
|
||
|
|
||
|
if(pPictureOut->ePixelFormat==PIXEL_FORMAT_YV12
|
||
|
||(pPictureOut->ePixelFormat == PIXEL_FORMAT_NV21)
|
||
|
||(pPictureOut->ePixelFormat == PIXEL_FORMAT_NV12))
|
||
|
{
|
||
|
|
||
|
int i;
|
||
|
int j;
|
||
|
for(j=0; j<pPictureIn->nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<pPictureIn->nWidth; i++)
|
||
|
{
|
||
|
int index = (pPictureIn->nHeight-1-j)*pPictureIn->nLineStride+ \
|
||
|
(pPictureIn->nWidth-1-i);
|
||
|
pPictureOut->pData0[index] = pPictureIn->pData0[j*pPictureIn->nLineStride+i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int nHeight = pPictureIn->nHeight/2;
|
||
|
int nWidth = pPictureIn->nWidth/2;
|
||
|
int nLineStride = pPictureIn->nLineStride/2;
|
||
|
|
||
|
int nMemSizeY;
|
||
|
int nMemSizeC;
|
||
|
if(pPictureOut->ePixelFormat==PIXEL_FORMAT_YV12)
|
||
|
{
|
||
|
nMemSizeY = pPictureIn->nLineStride*((pPictureIn->nHeight+15)&~15);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
pPictureOut->pData1 = pPictureOut->pData0+ nMemSizeY;
|
||
|
pPictureOut->pData2 = pPictureOut->pData1+ nMemSizeC;
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
pPictureIn->pData2 = pPictureIn->pData1 + nMemSizeC;
|
||
|
|
||
|
for(j=0; j<nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<nWidth; i++)
|
||
|
{
|
||
|
pPictureOut->pData1[(nHeight-1-j)*nLineStride+(nWidth-1-i)] = \
|
||
|
pPictureIn->pData1[j*nLineStride+i];
|
||
|
pPictureOut->pData2[(nHeight-1-j)*nLineStride+(nWidth-1-i)] = \
|
||
|
pPictureIn->pData2[j*nLineStride+i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if((pPictureOut->ePixelFormat==PIXEL_FORMAT_NV21)|| \
|
||
|
(pPictureOut->ePixelFormat==PIXEL_FORMAT_NV12))
|
||
|
{
|
||
|
nMemSizeY = pPictureIn->nLineStride*((pPictureIn->nHeight+15)&~15);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
CEDARC_UNUSE(nMemSizeC);
|
||
|
|
||
|
pPictureOut->pData1 = pPictureOut->pData0+ nMemSizeY;
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
for(j=0; j<nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<nWidth; i++)
|
||
|
{
|
||
|
pPictureOut->pData1[2*(nHeight-1-j)*nLineStride+2*(nWidth-1-i)] = \
|
||
|
pPictureIn->pData1[2*j*nLineStride+2*i];
|
||
|
pPictureOut->pData1[2*(nHeight-1-j)*nLineStride+2*(nWidth-1-i)+1] = \
|
||
|
pPictureIn->pData1[2*j*nLineStride+2*i+1];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//AdapterMemFlushCache((void*)pPictureOut->pData0, nMemSizeY+2*nMemSizeC);
|
||
|
pPictureOut->nHeight = pPictureIn->nHeight;
|
||
|
pPictureOut->nWidth = pPictureIn->nWidth;
|
||
|
|
||
|
nLeftOffset = pPictureIn->nLeftOffset;
|
||
|
nRightOffset = pPictureIn->nWidth - pPictureIn->nRightOffset;
|
||
|
nTopOffset = pPictureIn->nTopOffset;
|
||
|
nBottomOffset = pPictureIn->nHeight - pPictureIn->nTopOffset;
|
||
|
|
||
|
pPictureOut->nLeftOffset = nRightOffset;
|
||
|
pPictureOut->nBottomOffset = nTopOffset;
|
||
|
pPictureOut->nRightOffset = nLeftOffset;
|
||
|
pPictureOut->nTopOffset = nBottomOffset;
|
||
|
|
||
|
pPictureOut->nRightOffset = pPictureOut->nWidth - pPictureOut->nRightOffset;
|
||
|
pPictureOut->nBottomOffset = pPictureOut->nHeight -pPictureOut->nBottomOffset;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int RotatePicture270Degree(VideoPicture* pPictureIn, VideoPicture* pPictureOut)
|
||
|
{
|
||
|
int nLeftOffset = 0;
|
||
|
int nRightOffset = 0;
|
||
|
int nBottomOffset = 0;
|
||
|
int nTopOffset = 0;
|
||
|
|
||
|
pPictureOut->nLineStride = (pPictureIn->nHeight+15) &~15;
|
||
|
pPictureOut->nHeight = pPictureIn->nWidth;
|
||
|
pPictureOut->nWidth = pPictureIn->nHeight;
|
||
|
|
||
|
if(pPictureOut->ePixelFormat==PIXEL_FORMAT_YV12
|
||
|
||(pPictureOut->ePixelFormat == PIXEL_FORMAT_NV21)
|
||
|
||(pPictureOut->ePixelFormat == PIXEL_FORMAT_NV12))
|
||
|
|
||
|
{
|
||
|
int i = 0;
|
||
|
int j = 0;
|
||
|
for(j=0; j<pPictureIn->nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<pPictureIn->nWidth; i++)
|
||
|
{
|
||
|
pPictureOut->pData0[(pPictureIn->nWidth-1-i)*pPictureOut->nLineStride+j] = \
|
||
|
pPictureIn->pData0[j*pPictureIn->nLineStride+i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int nHeight = pPictureIn->nHeight/2;
|
||
|
int nWidth = pPictureIn->nWidth/2;
|
||
|
int nLineStride = pPictureIn->nLineStride/2;
|
||
|
int nRotateLineStride = pPictureOut->nLineStride/2;
|
||
|
|
||
|
int nMemSizeY = 0;
|
||
|
int nMemSizeC = 0;
|
||
|
if(pPictureOut->ePixelFormat==PIXEL_FORMAT_YV12)
|
||
|
{
|
||
|
nMemSizeY = pPictureIn->nLineStride*((pPictureIn->nHeight+15)&~15);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
pPictureIn->pData2 = pPictureIn->pData1 + nMemSizeC;
|
||
|
|
||
|
nMemSizeY = pPictureOut->nLineStride*((pPictureOut->nHeight+15)&~15);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
pPictureOut->pData1 = pPictureOut->pData0+ nMemSizeY;
|
||
|
pPictureOut->pData2 = pPictureOut->pData1+ nMemSizeC;
|
||
|
|
||
|
for(j=0; j<nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<nWidth; i++)
|
||
|
{
|
||
|
pPictureOut->pData1[(nWidth-1-i)*nRotateLineStride+j] = \
|
||
|
pPictureIn->pData1[j*nLineStride+i];
|
||
|
pPictureOut->pData2[(nWidth-1-i)*nRotateLineStride+j] = \
|
||
|
pPictureIn->pData2[j*nLineStride+i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if((pPictureOut->ePixelFormat==PIXEL_FORMAT_NV21) || \
|
||
|
(pPictureOut->ePixelFormat==PIXEL_FORMAT_NV12))
|
||
|
{
|
||
|
nMemSizeY = pPictureIn->nLineStride*((pPictureIn->nHeight+15)&~15);
|
||
|
pPictureIn->pData1 = pPictureIn->pData0 + nMemSizeY;
|
||
|
|
||
|
nMemSizeY = pPictureOut->nLineStride*((pPictureOut->nHeight+15)&~15);
|
||
|
nMemSizeC = nMemSizeY>>2;
|
||
|
CEDARC_UNUSE(nMemSizeC);
|
||
|
|
||
|
for(j=0; j<nHeight; j++)
|
||
|
{
|
||
|
for(i=0; i<nWidth; i++)
|
||
|
{
|
||
|
pPictureOut->pData1[2*(nWidth-1-i)*nRotateLineStride+2*j] = \
|
||
|
pPictureIn->pData1[2*j*nLineStride+2*i];
|
||
|
pPictureOut->pData1[2*(nWidth-1-i)*nRotateLineStride+2*j+1] = \
|
||
|
pPictureIn->pData1[2*j*nLineStride+2*i+1];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//AdapterMemFlushCache((void*)pPictureOut->pData0, nMemSizeY+2*nMemSizeC);
|
||
|
nLeftOffset = pPictureIn->nLeftOffset;
|
||
|
nRightOffset = pPictureIn->nWidth - pPictureIn->nRightOffset;
|
||
|
nTopOffset = pPictureIn->nTopOffset;
|
||
|
nBottomOffset = pPictureIn->nHeight - pPictureIn->nTopOffset;
|
||
|
|
||
|
pPictureOut->nLeftOffset = nTopOffset;
|
||
|
pPictureOut->nBottomOffset = nLeftOffset;
|
||
|
pPictureOut->nRightOffset = nBottomOffset;
|
||
|
pPictureOut->nTopOffset = nRightOffset;
|
||
|
|
||
|
pPictureOut->nRightOffset = pPictureOut->nWidth - pPictureOut->nRightOffset;
|
||
|
pPictureOut->nBottomOffset = pPictureOut->nHeight -pPictureOut->nBottomOffset;
|
||
|
return 0;
|
||
|
}
|