• cpp层直接操作 surface


    #include
    #include
    #include  
    #include  
    #include  
      
    #include  
    #include  
    #include  
    #include  
    #include  
    #include  
    #include  
    #include  
    #include  
    #include  
    #include  
    //ANativeWindow 就是surface,对应surface.cpp里的code  

    using namespace android;  

    extern "C" int mainxx123(void);

    //将x规整为y的倍数,也就是将x按y对齐  
    static int ALIGN(int x, int y) {  
        // y must be a power of 2.  
        return (x + y - 1) & ~(y - 1);  
    }  

    void fill_color(void *vaddr)
    {
        int cnt;
        unsigned int * p_data;

        p_data = (unsigned int *)vaddr;
        for( int i=0x00; i<60*640; i++ ){
             p_data[i] = 0xff0000ff;
        }
    }

      
    void render(  
            const void *data, size_t size, const sp &nativeWindow,int width,int height) {  
        sp mNativeWindow = nativeWindow;  
        int err;  
        int mCropWidth = width;  
        int mCropHeight = height;  
          
        //int halFormat = HAL_PIXEL_FORMAT_YV12;//颜色空间  


        int halFormat = HAL_PIXEL_FORMAT_RGBA_8888;

        
        int bufWidth = (mCropWidth + 1) & ~1;//按2对齐  
        int bufHeight = (mCropHeight + 1) & ~1;  
          
        CHECK_EQ(0,  
                native_window_set_usage(  
                mNativeWindow.get(),  
                GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN  
                | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));  
      
        CHECK_EQ(0,  
                native_window_set_scaling_mode(  
                mNativeWindow.get(),  
                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));  
      
        // Width must be multiple of 32???  
        //很重要,配置宽高和和指定颜色空间yuv420  
        //如果这里不配置好,下面deque_buffer只能去申请一个默认宽高的图形缓冲区  
        CHECK_EQ(0, native_window_set_buffers_geometry(  
                    mNativeWindow.get(),  
                    bufWidth,  
                    bufHeight,  
                    halFormat));  
          
          
        ANativeWindowBuffer *buf;//描述buffer  
        //申请一块空闲的图形缓冲区  
        if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(),  
                &buf)) != 0) {  
            ALOGW("Surface::dequeueBuffer returned error %d", err);  
            return;  
        }  
      
        GraphicBufferMapper &mapper = GraphicBufferMapper::get();  
      
        Rect bounds(mCropWidth, mCropHeight);  
      
        void *dst;  
        CHECK_EQ(0, mapper.lock(//用来锁定一个图形缓冲区并将缓冲区映射到用户进程  
                    buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));//dst就指向图形缓冲区首地址  
      
        if (true){  
            size_t dst_y_size = buf->stride * buf->height;  
            size_t dst_c_stride = ALIGN(buf->stride / 2, 16);//1行v/u的大小  
            size_t dst_c_size = dst_c_stride * buf->height / 2;//u/v的大小  
              
            memcpy(dst, data, dst_y_size + dst_c_size*2);//将yuv数据copy到图形缓冲区  
        }  


      fill_color(dst);
        CHECK_EQ(0, mapper.unlock(buf->handle));  
      
        if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf, -1)) != 0) {  
            ALOGW("Surface::queueBuffer returned error %d", err);  
        }  
        buf = NULL;  
    }  


      
    bool getYV12Data(const char *path,unsigned char * pYUVData,int size){  
        FILE *fp = fopen(path,"rb");  
        if(fp == NULL){  
            printf("read %s fail !!!!!!!!!!!!!!!!!!!\n",path);  
            return false;  
        }  
        fread(pYUVData,size,1,fp);  
        fclose(fp);  
        return true;  
    }  


    int mainxx123(void)
    {  
        //set up the thread-pool  
        sp proc(ProcessState::self());  
        ProcessState::self()->startThreadPool();  
          
        //create a client to surfaceflinger  
        sp client = new SurfaceComposerClient();  
        sp dtoken(SurfaceComposerClient::getBuiltInDisplay(  
                ISurfaceComposer::eDisplayIdMain));  
        DisplayInfo dinfo;  
        //获取屏幕的宽高等信息  
        status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);  
        printf("w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f\n",   
            dinfo.w, dinfo.h, dinfo.xdpi, dinfo.ydpi, dinfo.fps, dinfo.density);  
        if (status)  
            return -1;  
        //创建surface  
        sp surfaceControl = client->createSurface(String8("testsurface"),  
                dinfo.w, dinfo.h, PIXEL_FORMAT_RGBA_8888, 0);  
                  
    /*************************get yuv data from file;****************************************/            
        printf("[%s][%d]\n",__FILE__,__LINE__);  
        int width,height;  
        width = 640;  
        height = 480;  
        int size = width * height * 3/2;  
        unsigned char *data = new unsigned char[size];  
        const char *path = "/mnt/sdcard/yuv_320_240.yuv";  
        getYV12Data(path,data,size);//get yuv data from file;  
          
    /*********************配置surface*******************************************************************/  
        SurfaceComposerClient::openGlobalTransaction();  
        surfaceControl->setLayer(100000);//设定Z坐标  
        surfaceControl->setPosition(100, 100);//以左上角为(0,0)设定显示位置  
        surfaceControl->setSize(width, height);//设定视频显示大小  
        SurfaceComposerClient::closeGlobalTransaction();  
        sp surface = surfaceControl->getSurface();  
        printf("[%s][%d]\n",__FILE__,__LINE__);  
          
    /**********************显示yuv数据******************************************************************/     
        render(data,size,surface,width,height);  
        printf("[%s][%d]\n",__FILE__,__LINE__);  
          
        IPCThreadState::self()->joinThreadPool();//可以保证画面一直显示,否则瞬间消失  
        IPCThreadState::self()->stopProcess();  
        return 0;  

      

    Android.mk
    LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libbinder libui libgui libstagefright_foundation

  • 相关阅读:
    Centos7系统重装报错“ /dev/root does not exist“解决办法
    Spring Boot构建框架中尝试连接到表格时出错
    WebGL(ThreeJS)加载乐高Ldraw模型案例
    Docker项目部署lnmp+wordpress
    排序算法—
    学习网络编程No.6【将服务器日志和守护进程化】
    Netty 学习(五):服务端启动核心流程源码说明
    【CMU15-445 Part-9】Multi-Threaded Index Concurrency Control
    springboot毕设项目超市收银系统ybza4(java+VUE+Mybatis+Maven+Mysql)
    Android Camera性能分析 - 第18讲 预览Buffer Path详解
  • 原文地址:https://blog.csdn.net/dp__mcu/article/details/126022620