Android displays YUV data directly with surface (ii)

Source: Internet
Author: User

The previous article is mainly referring to Awesomeplayer directly with the Softwarerenderer class to display the YUV, in order to use this class, at all, relying on the libstagefright, libstagefright_color_ Conversion and other dynamic static library, which causes the program to have a high degree of coupling, nor is it easy for us to understand the underlying reasons for the direct display of YUV data.

So I began to study the specific implementation of Softwarerenderer, we have to extract the core code of Softwarerenderer, to implement the YUV display.

Softwarerenderer has only three methods, a constructor, a destructor, and a render method that is responsible for the display. There is a very important place in the construction method Native_window_set_buffers_geometry here is the configuration of the application of the graphics buffer width and color space, ignoring this place, the screen will be displayed with the default value, will cause the display is incorrect. The three most important places in the render function, one dequebuffer, one is mapper, the other is Queue_buffer.

native_window_set_buffers_geometry;//Setting the width height and color space yuv420native_window_dequeue_buffer_and_wait;// Request Graphics Buffer Mapper.lock (buf->handle, Gralloc_usage_sw_write_often, Bounds, &DST) based on the above configuration;// Maps the requested graphics buffer across processes to the user space memcpy (DST, data, dst_y_size + dst_c_size*2);//fills YUV data to the graphics buffer mnativewindow->queuebuffer;//display

The above five steps are an essential five step for surface display graphics.

With the above analysis, we directly on the code: (YUV Data Click Open Link, put to sdcard)

Main.cpp

#include <cutils/memory.h> #include <unistd.h> #include <utils/Log.h> #include <binder/ ipcthreadstate.h> #include <binder/ProcessState.h> #include <binder/IServiceManager.h> #include < media/stagefright/foundation/adebug.h> #include <gui/Surface.h> #include <gui/surfacecomposerclient.h > #include <gui/ISurfaceComposer.h> #include <ui/DisplayInfo.h> #include <android/native_window.h > #include <system/window.h> #include <ui/graphicbuffermapper.h>//anativewindow is surface, corresponding to the Codeusing namespace android;//in the Surface.cpp, the x is normalized to a multiple of y, that is, X is aligned by Y to the static int ALIGN (int x, int y) {//Y must be a power O    F 2. return (x + y-1) & ~ (y-1);}     void render (const void *data, size_t size, const sp<anativewindow> &nativewindow,int width,int height) {    sp<anativewindow> Mnativewindow = NativeWindow; int Err;int Mcropwidth = width;int Mcropheight = height;int Halformat = hal_pixel_format_yv12;//color space int bUfwidth = (mcropwidth + 1) & ~1;//Press 2 to align int bufheight = (mcropheight + 1) & to; Check_eq (0, Native_window_set_usage (Mnativewindow.get (), Gralloc_usage_sw_read_never | G Ralloc_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_mo    De_scale_to_window)); Width must be multiple of??? Very important, configure the width and height and specify the color space yuv420//if not configured here, the following deque_buffer can only apply a default wide-height graphics buffer check_eq (0, Native_window_set_buffers_ Geometry (Mnativewindow.get (), Bufwidth, Bufheight, Halformat) ); Anativewindowbuffer *buf;//describes the buffer//request for an idle graphics buffer if (err = native_window_dequeue_buffer_and_wait (        Mnativewindow.get (), &buf))! = 0) {ALOGW ("Surface::d Equeuebuffer returned error%d", err);    Return } graphicbuffermapper &mapper = GRaphicbuffermapper::get ();    Rect bounds (mcropwidth, mcropheight);    void *dst; Check_eq (0, Mapper.lock (//used to lock a graphics buffer and map buffers to user processes Buf->handle, gralloc_usage_sw_write_often, Bounds, &am        P;DST));//dst points to the first address of the graphics buffer if (true) {size_t dst_y_size = buf->stride * buf->height; size_t dst_c_stride = ALIGN (BUF-&GT;STRIDE/2, 16);//1 line v/u size size_t dst_c_size = dst_c_stride * Buf->height/ 2;//u/v size memcpy (DST, data, dst_y_size + dst_c_size*2);//copy YUV data to graphics buffer} check_eq (0, Mapper.unloc    K (Buf->handle)); if (err = Mnativewindow->queuebuffer (Mnativewindow.get (), buf,-1))! = 0) {ALOGW ("Surface::queuebuf    Fer 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 ("Re Ad%s fail!!!!!!!!!!!!!!!!!!! \ n ", path); return false;} Fread (PYUVDATA,SIZE,1,FP); fclose (FP); return true;} int main (void) {//SetUp the Thread-pool sp<processstate> proc (processstate::self ()); Processstate::self ()->startthreadpool ();//Create a client to Surfaceflinger sp<surfacecomposerclient> Client = new Surfacecomposerclient ();sp<ibinder> Dtoken (Surfacecomposerclient::getbuiltindisplay (ISURFAC Ecomposer::edisplayidmain));D isplayinfo dinfo;//Gets the width and high information of the screen status_t status = Surfacecomposerclient::getdisplayinfo ( Dtoken, &dinfo);p rintf ("w=%d,h=%d,xdpi=%f,ydpi=%f,fps=%f,ds=%f\n", DINFO.W, Dinfo.h, dinfo.xdpi, dinfo.ydpi, D    Info.fps, dinfo.density); if (status) return-1;//Create surface sp<surfacecontrol> Surfacecontrol = Client->createsurface (String8 ("Te Stsurface "), DINFO.W, Dinfo.h, pixel_format_rgba_8888, 0);/*************************get YUV data from file;**** /printf ("[%s][%d]\n", __file__,__line__); int width,height;width = 320;height = 240;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;/********************* Configuration surface*******************************************************************/    Surfacecomposerclient::openglobaltransaction (); Surfacecontrol->setlayer (100000);//Set z-coordinate surfacecontrol->setposition (100, 100);//with upper left corner (0,0) Set the display position surfacecontrol->setsize (width, height);//Set the video display size surfacecomposerclient::closeglobaltransaction (); SP <Surface> Surface = Surfacecontrol->getsurface ();p rintf ("[%s][%d]\n", __file__,__line__);/*************** Displays YUV data ******************************************************************/render (Data,size,surface, Width,height);p rintf ("[%s][%d]\n", __file__,__line__); Ipcthreadstate::self ()->jointhreadpool ();//To ensure that the screen is always displayed, Otherwise instantly disappears ipcthreadstate::self ()->stopprocess (); return 0;}

ANDROID.MK (this time dependent library is a lot less)

Local_path:= $ (call My-dir) include $ (clear_vars) local_src_files:= main.cpplocal_shared_libraries: = Libcutils Libutils libbinder     libui     libgui libstagefright_foundationlocal_module:= myshowyuvlocal_module_tags: = Testsinclude $ (build_executable)
Reprint please specify the source http://blog.csdn.net/tung214/article/details/37651825

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.