日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

android 的overlay渲染

 傳真閱覽室 2014-01-17
#define LOG_TAG "Android_Overlay"
#include <android/api-level.h>
//android threads
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

//for android surface and overlay
#if __ANDROID_API__ >= 9
#include <surfaceflinger/Surface.h>
#include <surfaceflinger/ISurface.h>
#include <surfaceflinger/SurfaceComposerClient.h>
#include <surfaceflinger/ISurfaceComposer.h>
#include <surfaceflinger/ISurfaceComposerClient.h>
#include <ui/IOverlay.h>
#else
#include <ui/Surface.h>
#include <ui/ISurface.h>
#include <ui/SurfaceComposerClient.h>
#endif
#include <utils/log.h>
#include <ui/Overlay.h>
#include "media_Overlays.h"

// ------------------------------micro and variable----------------------------------------------
#define CACHEABLE_BUFFERS 0x1

//mobile type
//#define MOBILE_OPHONE
#define MOBILE_ANDROID

//android threads
android_thread_id_t g_ThreadID;
bool g_Thread_keep;


// define in V412_utils.h
typedef struct
{
  int fd;
  size_t length;
  uint32_t offset;
  void *ptr;
} mapping_data_t;
mapping_data_t *mdata;

// define it for video data
typedef struct{
int index;
int buf_count;
uint16_t* buf_addr;
uint16_t*  address[8];
} packet_data;
packet_data pdata;

//image format
typedef struct{
int index;
int left;
int top;
uint32_t width;
uint32_t height;
int32_t format;
int format_yuv;
} image_format;
image_format imgfmt;

//view size
typedef struct{
int left;
int top;
int width;
int height;
}view_size;
view_size viewfmt;

typedef enum{
Unknown_size = -1,
Normal_ver_and_hor,
Normal_ver_enlarge_hor,
Normal_ver_full_hor,
Enlarge_ver_and_hor,
Enlarge_ver_full_hor
}ScreenType;

using namespace android;


sp<SurfaceComposerClient> client;
sp<SurfaceControl> sc;
sp<ISurface>                mSurface;
sp<Overlay> mOverlay;

namespace android {
class Test {
public:
static const sp<ISurface>& getISurface(const sp<Surface>& s) {
Surface* p;
p=s.get();
ISurface*q = (p->mSurface).get();
// LOGI("sur->mSurface=0x%x\n",q);
return s->getISurface();
}
};
}

// ----------------------------------implement------------------------------------------
sp<Overlay> InitOverlay(int screentype, int format)
{
Video_Overlay_Stop();

  int left,top,width,height;

//   LOGI("Starting");

  // set up the thread-pool
  sp<ProcessState> proc(android::ProcessState::self());
  android::ProcessState::self()->startThreadPool();

  // create a client to surfaceflinger,

// LOGI("SurfaceComposerClient format = %d\n", format);
  client = new SurfaceComposerClient();
  if(client == NULL){
  return 0;
  }

  // create pushbuffer surface
  sc = client->createSurface(getpid(), 0, imgfmt.width,imgfmt.height,imgfmt.format, ISurfaceComposer::ePushBuffers);
  if(sc == NULL){
return 0;
}
// LOGI("createSurface,pid %d, %d x %d, %d\n",getpid(),imgfmt.width,imgfmt.height,imgfmt.format);
  Video_Overlay_Set_Screen(screentype);

  sp<Surface> surface = sc->getSurface();

  // get to the isurface
  sp<ISurface> isurface = Test::getISurface(surface);

//   LOGI("getISurface = %p\n", isurface.get());

  sp<ISurface> mSurface = isurface.get();

//   LOGI("createOverlaying %d x %d, %d",imgfmt.width,imgfmt.height,imgfmt.format);
#if __ANDROID_API__ >= 9
sp<OverlayRef> ref = mSurface->createOverlay(imgfmt.width,imgfmt.height,imgfmt.format,0);
#else
sp<OverlayRef> ref = mSurface->createOverlay(imgfmt.width,imgfmt.height,imgfmt.format);
#endif

  if(ref.get()==NULL){
  return 0;
  }

  sp<Overlay> overlay = new Overlay(ref);
  LOGI("init End");

return overlay;
}

/*
video format:
OVERLAY_FORMAT_RGB_565      = HAL_PIXEL_FORMAT_RGB_565, 4
OVERLAY_FORMAT_BGRA_8888    = HAL_PIXEL_FORMAT_BGRA_8888, 1
OVERLAY_FORMAT_YCbCr_422_SP = HAL_PIXEL_FORMAT_YCbCr_422_SP, 16
OVERLAY_FORMAT_YCbCr_420_SP = HAL_PIXEL_FORMAT_YCbCr_420_SP, 17
OVERLAY_FORMAT_YCbYCr_422_I = HAL_PIXEL_FORMAT_YCbCr_422_I, 20
OVERLAY_FORMAT_YCbYCr_420_I = HAL_PIXEL_FORMAT_YCbCr_420_I, 21
OVERLAY_FORMAT_CbYCrY_422_I = HAL_PIXEL_FORMAT_CbYCrY_422_I, 22
OVERLAY_FORMAT_CbYCrY_420_I = HAL_PIXEL_FORMAT_CbYCrY_420_I, 23
OVERLAY_FORMAT_DEFAULT      = 99
*/
int Video_Overlay_Init(int screentype, int format)
{
imgfmt.index = 0;

if(0 == format)
{
imgfmt.format = OVERLAY_FORMAT_RGB_565;
}
else if(1 == format)
{
imgfmt.format = OVERLAY_FORMAT_BGRA_8888;
}
else if(4 == format)
{
imgfmt.format = OVERLAY_FORMAT_YCbYCr_422_I;
}
else if(6 == format)
{
imgfmt.format = OVERLAY_FORMAT_CbYCrY_422_I;
}
else if(8 == format)
{
imgfmt.format = OVERLAY_FORMAT_DEFAULT;
}
#if __ANDROID_API__ < 9
else if(2 == format)
{
imgfmt.format = OVERLAY_FORMAT_YCbCr_422_SP;
}
else if(3 == format)
{
imgfmt.format = OVERLAY_FORMAT_YCbCr_420_SP;
}
else if(5 == format)
{
imgfmt.format = OVERLAY_FORMAT_YCbYCr_420_I;
}
else if(7 == format)
{
imgfmt.format = OVERLAY_FORMAT_CbYCrY_420_I;
}
#endif

pdata.index = 0;
pdata.buf_count = 0;
pdata.buf_addr = NULL;

mOverlay = InitOverlay(screentype, format);
if(mOverlay == NULL)
{
LOGE("Maybe the device did not support overlay mode.\n");
return 0;
}
else
{
pdata.buf_count = mOverlay->getBufferCount();

for(int i = 0;i<pdata.buf_count;i++)
{
mdata = (mapping_data_t*)mOverlay->getBufferAddress((void*)i);

pdata.address[i] = (uint16_t*)mdata->ptr;
LOGI("buffer count (%d),i(%d),pdata.address(%p)\n",pdata.buf_count,i,pdata.address[i]);
}
return 1;
}
}

void* Video_Overlay_WriteData(int screentype)
{
if(mOverlay == NULL){
return NULL;
}

if(pdata.index >= pdata.buf_count)
{
pdata.index = 0;
}

Video_Overlay_Set_Screen(screentype);
overlay_buffer_t overlay_buffer;

  mOverlay->dequeueBuffer(&overlay_buffer);

LOGI("WriteData index (%d),pdata.address(%p)\n",pdata.index,pdata.address[pdata.index]);

return pdata.address[pdata.index];
}

void set_screen_size(int left, int top, int width, int height, int nSec)
{
// if(imgfmt.width <= viewfmt.width)
{
  client->openTransaction();
// client->freezeDisplay(1);
sc->setSize(width,height);
sc->setPosition(left,top);
// client->unfreezeDisplay(1);
client->closeTransaction();
usleep(nSec * 1000);
}
}

void Video_Overlay_Set_Screen(int screentype)
{
int left,top,width,height;

if(screentype == 0){//Normal_ver_and_hor

width = imgfmt.width;
height = imgfmt.height;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 1);
}
else if(screentype == 1){//Normal_ver_enlarge_hor
if(viewfmt.width < viewfmt.height){
width = imgfmt.width;
height = imgfmt.height;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 1);
}
else{
height = viewfmt.height;
width = (height * imgfmt.width)/imgfmt.height;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 1);
}
}
else if(screentype == 2){//Normal_ver_full_hor
if(viewfmt.width < viewfmt.height){
width = imgfmt.width;
height = imgfmt.height;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 1);
}
else{
width = viewfmt.width;
height = viewfmt.height;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 2);
}
}
else if(screentype == 3){//Enlarge_ver_and_hor
#ifdef MOBILE_OPHONE
if(viewfmt.width < viewfmt.height){
width = viewfmt.width;
height = (width * imgfmt.height)/imgfmt.width;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 1);
}
else{
height = viewfmt.height;
width = (height * imgfmt.width)/imgfmt.height;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 2);
}
#else
#ifdef MOBILE_ANDROID
if(viewfmt.width <= viewfmt.height){
if(imgfmt.width <= viewfmt.width){
width = viewfmt.width;
height = (width * imgfmt.height)/imgfmt.width;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 1);
  LOGI("Set_Screen 1 view(%d x %d x %d x %d)\n",left,top,width,height);
}else{
width = viewfmt.width;
height = viewfmt.height-60;
left = 0;
top = 60;

set_screen_size(left, top, width, height, 2);
                LOGI("Set_Screen 2 view(%d x %d x %d x %d)\n",left,top,width,height);
}
}else{//viewfmt.width > viewfmt.height
if(imgfmt.width > viewfmt.width){
width = imgfmt.width;
height = imgfmt.height;
left = 0;
top = 60;

set_screen_size(left, top, width, height, 2);
                LOGI("Set_Screen 3 view(%d x %d x %d x %d)\n",left,top,width,height);
}else{//imgfmt.width <= viewfmt.width
height = viewfmt.height;
width = (height * imgfmt.width)/imgfmt.height;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2;

set_screen_size(left, top, width, height, 2);
                LOGI("Set_Screen 4 view(%d x %d x %d x %d)\n",left,top,width,height);
}
}
#endif
#endif
}
else if(screentype == 4){//Enlarge_ver_full_hor
if(viewfmt.width < viewfmt.height){
width = viewfmt.width;
height = (width * imgfmt.height)/imgfmt.width;
left = (viewfmt.width-width)/2;
top = (viewfmt.height-height)/2/2;
            LOGI("Set_Screen 5 view(%d x %d x %d x %d)\n",left,top,width,height);
set_screen_size(left, top, width, height, 1);
}else{
if (viewfmt.width >= 800)
{
width = viewfmt.width;
height = viewfmt.height;
left = 0;//(viewfmt.width-width)/2;
top = 0;//(viewfmt.height-height)/2;
                LOGI("Set_Screen 6 view(%d x %d x %d x %d)\n",left,top,width,height);

set_screen_size(left, top, width, height, 2);
}
else
{
width = viewfmt.width;
height = viewfmt.height;
left = viewfmt.left;//(viewfmt.width-width)/2;
top = viewfmt.top;//(viewfmt.height-height)/2;
                LOGI("Set_Screen 7 view(%d x %d x %d x %d)\n",left,top,width,height);

set_screen_size(left, top, width, height, 1);
}
}
}
    LOGI("Set_Screen end view(%d x %d x %d x %d)\n",left,top,width,height);
}

void Video_Overlay_GetViewSize(int contrl_x, int contrl_y, int contrl_w, int contrl_h)
{
viewfmt.left = contrl_x;
viewfmt.top = contrl_y;
viewfmt.width = contrl_w;
viewfmt.height = contrl_h;

  LOGI("Get Data view(%d x %d, %d x %d)\n",viewfmt.left,viewfmt.top,viewfmt.width,viewfmt.height);

}

void Video_Overlay_GetFrameSize(int video_w, int video_h)
{
imgfmt.width = video_w;
imgfmt.height = video_h;

  LOGI("Get Frame Data", "video(%d x %d)\n",imgfmt.width,imgfmt.height);
}

void Video_Overlay_Display()
{
  mOverlay->queueBuffer((void*)pdata.index);

LOGI("Display pdata.index(%d),width(%d),height(%d)\n",pdata.index,imgfmt.width,imgfmt.height);

pdata.index++;

if(pdata.index > pdata.buf_count)
{
pdata.index = 0;
}

// usleep(50000);
}

void Video_Overlay_Stop()
{
// g_Thread_keep = false;
if (mOverlay != NULL)
{
mOverlay->destroy();
mOverlay = NULL;
}

}

void yuv420_convert(uint8_t * src[3], uint8_t * yuv420, int width, int height)
{
unsigned int w,h;
for (h=0; h<height; h++){
memcpy(yuv420, src[0], width);
src[0] += width+32;
yuv420 += width;
}

for (h=0; h<height/2; h++){
memcpy(yuv420, src[1], width/2);
memcpy(yuv420 + width/2, src[1], width/2);
src[1] += (width+32)/2;
yuv420 += width;
}

for (h=0; h<height/2; h++){
memcpy(yuv420, src[2], width/2);
memcpy(yuv420 + width/2, src[2], width/2);
src[2] += (width+32)/2;
yuv420 += width;
}
}

/* convert 4:2:0 to yuv 4:2:0sp */
void yuv420p_to_yuv420sp(uint8_t * src[3], uint8_t * yuv420sp, int width, int height)
{
unsigned int w,h;
for (h=0; h<height; h++){
memcpy(yuv420sp, src[0], width);
src[0] += width+32;
yuv420sp += width;
}

for (h=0; h<height/2; h++){
memcpy(yuv420sp, src[1], width/2);memcpy(yuv420sp, src[2], width/2);
memcpy(yuv420sp + width/2, src[1], width/2);memcpy(yuv420sp + width/2, src[2], width/2);
src[1] += (width+32)/2;src[2] += (width+32)/2;
yuv420sp += width;yuv420sp += width;
}
}

void yuyv422_to_yuv420sp(unsigned char *bufsrc, unsigned char *bufdest, int width, int height)
{
unsigned char *ptrsrcy1, *ptrsrcy2;
unsigned char *ptrsrcy3, *ptrsrcy4;
unsigned char *ptrsrccb1, *ptrsrccb2;
unsigned char *ptrsrccb3, *ptrsrccb4;
unsigned char *ptrsrccr1, *ptrsrccr2;
unsigned char *ptrsrccr3, *ptrsrccr4;
int srcystride, srcccstride;

ptrsrcy1  = bufsrc ;
ptrsrcy2  = bufsrc + (width<<1) ;
ptrsrcy3  = bufsrc + (width<<1)*2 ;
ptrsrcy4  = bufsrc + (width<<1)*3 ;

ptrsrccb1 = bufsrc + 1;
ptrsrccb2 = bufsrc + (width<<1) + 1;
ptrsrccb3 = bufsrc + (width<<1)*2 + 1;
ptrsrccb4 = bufsrc + (width<<1)*3 + 1;

ptrsrccr1 = bufsrc + 3;
ptrsrccr2 = bufsrc + (width<<1) + 3;
ptrsrccr3 = bufsrc + (width<<1)*2 + 3;
ptrsrccr4 = bufsrc + (width<<1)*3 + 3;

srcystride  = (width<<1)*3;
srcccstride = (width<<1)*3;

unsigned char *ptrdesty1, *ptrdesty2;
unsigned char *ptrdesty3, *ptrdesty4;
unsigned char *ptrdestcb1, *ptrdestcb2;
unsigned char *ptrdestcr1, *ptrdestcr2;
int destystride, destccstride;

ptrdesty1 = bufdest;
ptrdesty2 = bufdest + width;
ptrdesty3 = bufdest + width*2;
ptrdesty4 = bufdest + width*3;

ptrdestcb1 = bufdest + width*height;
ptrdestcb2 = bufdest + width*height + width;

ptrdestcr1 = bufdest + width*height + 1;
ptrdestcr2 = bufdest + width*height + width + 1;

destystride  = (width)*3;
destccstride = width;

int i, j;

for(j=0; j<(height/4); j++)
{
for(i=0;i<(width/2);i++)
{
(*ptrdesty1++) = (*ptrsrcy1);
(*ptrdesty2++) = (*ptrsrcy2);
(*ptrdesty3++) = (*ptrsrcy3);
(*ptrdesty4++) = (*ptrsrcy4);

ptrsrcy1 += 2;
ptrsrcy2 += 2;
ptrsrcy3 += 2;
ptrsrcy4 += 2;

(*ptrdesty1++) = (*ptrsrcy1);
(*ptrdesty2++) = (*ptrsrcy2);
(*ptrdesty3++) = (*ptrsrcy3);
(*ptrdesty4++) = (*ptrsrcy4);

ptrsrcy1 += 2;
ptrsrcy2 += 2;
ptrsrcy3 += 2;
ptrsrcy4 += 2;

(*ptrdestcb1) = (*ptrsrccb1);
(*ptrdestcb2) = (*ptrsrccb3);
ptrdestcb1 += 2;
ptrdestcb2 += 2;

ptrsrccb1 += 4;
ptrsrccb3 += 4;

(*ptrdestcr1) = (*ptrsrccr1);
(*ptrdestcr2) = (*ptrsrccr3);
ptrdestcr1 += 2;
ptrdestcr2 += 2;

ptrsrccr1 += 4;
ptrsrccr3 += 4;
}
/* Update src pointers */
ptrsrcy1  += srcystride;
ptrsrcy2  += srcystride;
ptrsrcy3  += srcystride;
ptrsrcy4  += srcystride;

ptrsrccb1 += srcccstride;
ptrsrccb3 += srcccstride;

ptrsrccr1 += srcccstride;
ptrsrccr3 += srcccstride;

/* Update dest pointers */
ptrdesty1 += destystride;
ptrdesty2 += destystride;
ptrdesty3 += destystride;
ptrdesty4 += destystride;

ptrdestcb1 += destccstride;
ptrdestcb2 += destccstride;

ptrdestcr1 += destccstride;
ptrdestcr2 += destccstride;
}
}
/* convert 4:2:0 to yuv 4:2:2 */
/*
*UYVY
*YUYV
*YVYU
*VYUY
*/
void yuv420p_to_yuv422(uint8_t * yuv420[3], uint8_t * dest, int width, int height, int yuv_tab)
{
unsigned int x, y;

for (y = 0; y < height; ++y)
{
uint8_t *Y = yuv420[0] + y *  (width+32);
uint8_t *U = yuv420[1] + (y / 2) * ((width+32) / 2);
uint8_t *V = yuv420[2] + (y / 2) * ((width+32) / 2);
for (x = 0; x < width; x += 2)
{
if(yuv_tab == YUV_UYVY){
*(dest + 0) = U[0];
*(dest + 1) = Y[0];
*(dest + 2) = V[0];
*(dest + 3) = Y[1];
}
else if(yuv_tab == YUV_YUYV){
*(dest + 0) = Y[0];
*(dest + 1) = U[0];
*(dest + 2) = Y[1];
*(dest + 3) = V[0];
}else if(yuv_tab == YUV_YVYU){
*(dest + 0) = Y[0];
*(dest + 1) = V[0];
*(dest + 2) = Y[1];
*(dest + 3) = U[0];
}else if(yuv_tab == YUV_VYUY){
*(dest + 0) = V[0];
*(dest + 1) = Y[0];
*(dest + 2) = U[1];
*(dest + 3) = Y[1];
}

dest += 4;
Y += 2;
++U;
++V;
}
}
}

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多