分享

Android用surface直接显示yuv数据(二)

 barry525 2015-07-21
001.#include <cutils/memory.h>
002. 
003.#include <unistd.h>
004.#include <utils/Log.h>
005. 
006.#include <binder/IPCThreadState.h>
007.#include <binder/ProcessState.h>
008.#include <binder/IServiceManager.h>
009.#include <media/stagefright/foundation/ADebug.h>
010.#include <gui/Surface.h>
011.#include <gui/SurfaceComposerClient.h>
012.#include <gui/ISurfaceComposer.h>
013.#include <ui/DisplayInfo.h>
014.#include <android/native_window.h>
015.#include <system/window.h>
016.#include <ui/GraphicBufferMapper.h>
017.//ANativeWindow 就是surface,对应surface.cpp里的code
018.using namespace android;
019. 
020.//将x规整为y的倍数,也就是将x按y对齐
021.static int ALIGN(int x, int y) {
022.    // y must be a power of 2.
023.    return (x + y - 1) & ~(y - 1);
024.}
025. 
026.void render(
027.        const void *data, size_t size, const sp<ANativeWindow> &nativeWindow,int width,int height) {
028.    sp<ANativeWindow> mNativeWindow = nativeWindow;
029.    int err;
030.    int mCropWidth = width;
031.    int mCropHeight = height;
032.     
033.    int halFormat = HAL_PIXEL_FORMAT_YV12;//颜色空间
034.    int bufWidth = (mCropWidth + 1) & ~1;//按2对齐
035.    int bufHeight = (mCropHeight + 1) & ~1;
036.     
037.    CHECK_EQ(0,
038.            native_window_set_usage(
039.            mNativeWindow.get(),
040.            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
041.            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
042. 
043.    CHECK_EQ(0,
044.            native_window_set_scaling_mode(
045.            mNativeWindow.get(),
046.            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
047. 
048.    // Width must be multiple of 32???
049.    //很重要,配置宽高和和指定颜色空间yuv420
050.    //如果这里不配置好,下面deque_buffer只能去申请一个默认宽高的图形缓冲区
051.    CHECK_EQ(0, native_window_set_buffers_geometry(
052.                mNativeWindow.get(),
053.                bufWidth,
054.                bufHeight,
055.                halFormat));
056.     
057.     
058.    ANativeWindowBuffer *buf;//描述buffer
059.    //申请一块空闲的图形缓冲区
060.    if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(),
061.            &buf)) != 0) {
062.        ALOGW("Surface::dequeueBuffer returned error %d", err);
063.        return;
064.    }
065. 
066.    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
067. 
068.    Rect bounds(mCropWidth, mCropHeight);
069. 
070.    void *dst;
071.    CHECK_EQ(0, mapper.lock(//用来锁定一个图形缓冲区并将缓冲区映射到用户进程
072.                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));//dst就指向图形缓冲区首地址
073. 
074.    if (true){
075.        size_t dst_y_size = buf->stride * buf->height;
076.        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);//1行v/u的大小
077.        size_t dst_c_size = dst_c_stride * buf->height / 2;//u/v的大小
078.         
079.        memcpy(dst, data, dst_y_size + dst_c_size*2);//将yuv数据copy到图形缓冲区
080.    }
081. 
082.    CHECK_EQ(0, mapper.unlock(buf->handle));
083. 
084.    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf,
085.            -1)) != 0) {
086.        ALOGW("Surface::queueBuffer returned error %d", err);
087.    }
088.    buf = NULL;
089.}
090. 
091.bool getYV12Data(const char *path,unsigned char * pYUVData,int size){
092.    FILE *fp = fopen(path,"rb");
093.    if(fp == NULL){
094.        printf("read %s fail !!!!!!!!!!!!!!!!!!!
095.",path);
096.        return false;
097.    }
098.    fread(pYUVData,size,1,fp);
099.    fclose(fp);
100.    return true;
101.}
102. 
103.int main(void){
104.    // set up the thread-pool
105.    sp<ProcessState> proc(ProcessState::self());
106.    ProcessState::self()->startThreadPool();
107.     
108.    // create a client to surfaceflinger
109.    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
110.    sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
111.            ISurfaceComposer::eDisplayIdMain));
112.    DisplayInfo dinfo;
113.    //获取屏幕的宽高等信息
114.    status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
115.    printf("w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f
116.",
117.        dinfo.w, dinfo.h, dinfo.xdpi, dinfo.ydpi, dinfo.fps, dinfo.density);
118.    if (status)
119.        return -1;
120.    //创建surface
121.    sp<SurfaceControl> surfaceControl = client->createSurface(String8("testsurface"),
122.            dinfo.w, dinfo.h, PIXEL_FORMAT_RGBA_8888, 0);
123.             
124./*************************get yuv data from file;****************************************/         
125.    printf("[%s][%d]
126.",__FILE__,__LINE__);
127.    int width,height;
128.    width = 320;
129.    height = 240;
130.    int size = width * height * 3/2;
131.    unsigned char *data = new unsigned char[size];
132.    const char *path = "/mnt/sdcard/yuv_320_240.yuv";
133.    getYV12Data(path,data,size);//get yuv data from file;
134.     
135./*********************配置surface*******************************************************************/
136.    SurfaceComposerClient::openGlobalTransaction();
137.    surfaceControl->setLayer(100000);//设定Z坐标
138.    surfaceControl->setPosition(100, 100);//以左上角为(0,0)设定显示位置
139.    surfaceControl->setSize(width, height);//设定视频显示大小
140.    SurfaceComposerClient::closeGlobalTransaction();
141.    sp<Surface> surface = surfaceControl->getSurface();
142.    printf("[%s][%d]
143.",__FILE__,__LINE__);
144.     
145./**********************显示yuv数据******************************************************************/  
146.    render(data,size,surface,width,height);
147.    printf("[%s][%d]
148.",__FILE__,__LINE__);
149.     
150.    IPCThreadState::self()->joinThreadPool();//可以保证画面一直显示,否则瞬间消失
151.    IPCThreadState::self()->stopProcess();
152.    return 0;
153.}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多