Android displays YUV data directly with surface (iii)

Source: Internet
Author: User

This article uses Java to create UI and joint JNI layer operations surface to directly display YUV data (YV12), the development environment for Android 4.4, the full A23 platform.

Package Com.example.myyuvviewer;import Java.io.file;import Java.io.fileinputstream;import android.app.Activity; Import Android.os.bundle;import android.os.environment;import Android.util.log;import Android.view.Surface;import Android.view.surfaceholder;import Android.view.surfaceholder.callback;import Android.view.SurfaceView;public Class Mainactivity extends Activity {Final private string TAG = "Myyuvviewer"; final private string file_name = "yuv_320_24 0.YUV ";p rivate int width = 320;private int height = 240;private int size = width * Height * 3/2; @Overrideprotected void on Create (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Nativetest (); Surfaceview Surfaceview = (surfaceview) Findviewbyid (R.id.surfaceview); Surfaceholder holder = Surfaceview.getholder () holder.addcallback (new Callback () {@Overridepublic void surfacecreated (Surfaceholder Holder) {//TODO auto-generated method Stublog.d (TAG, "surfacecreated"); Byte[]yuvarray = new Byte[sIze];readyuvfile (Yuvarray, file_name); Nativesetvideosurface (Holder.getsurface ()); Nativeshowyuv (YuvArray,width, height);}  @Overridepublic void Surfacechanged (surfaceholder holder, int format,int width, int height) {//TODO auto-generated method stub} @Overridepublic void Surfacedestroyed (Surfaceholder holder) {//TODO auto-generated Method stub}}); Private Boolean Readyuvfile (byte[] yuvarray,string filename) {try {//If the phone is plugged into an SD card and the application has access to the SD if (Environment.getexternalstoragestate (). Equals (environment.media_mounted))                {//Get SD card corresponding storage directory File Sdcarddir = Environment.getexternalstoragedirectory (); Gets the input stream corresponding to the specified file FileInputStream fis = new FileInputStream (Sdcarddir.getcanonicalp                Ath () + "/" + filename);                Fis.read (yuvarray, 0, size);                Fis.close ();            return true;            } else {return false; }        }catch (Exception e) {e.printstacktrace ();        return false; }}private native void Nativetest ();p rivate native Boolean nativesetvideosurface (surface surface);p rivate native void    NATIVESHOWYUV (byte[] yuvarray,int width,int height); static {system.loadlibrary ("SHOWYUV"); }}
Activity_main.xml
<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"      android:layout_width= "Fill_ Parent "      android:layout_height=" fill_parent "      android:orientation=" vertical ">        <surfaceview          android:id= "@+id/surfaceview"          android:layout_width= "fill_parent"          android:layout_height= "360DP"/ >         </LinearLayout>

The JNI layer, showYUV.cpp (libshowyuv.so), employs a method of dynamically registering JNI functions.

#include <jni.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_ surface.h> #include <gui/Surface.h> #include <assert.h> #include <utils/Log.h> #include < jnihelp.h> #include <media/stagefright/foundation/ADebug.h> #include <ui/graphicbuffermapper.h># Include <cutils/properties.h>using namespace android;static sp<surface> surface;static int ALIGN (int x, int    Y) {//Y must be a power of 2. return (x + y-1) & ~ (y-1);} static void render (const void *data, size_t size, const sp<anativewindow> &nativewindow,int width,int He    ight) {Aloge ("[%s]%d", __file__,__line__);    sp<anativewindow> Mnativewindow = NativeWindow; int Err;int Mcropwidth = width;int Mcropheight = height;int Halformat = hal_pixel_format_yv12;//color space int bufWidth = (MC Ropwidth + 1) & ~1;//by 2 aligned int bufheight = (mcropheight + 1) & to;       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_mo    De_scale_crop)); 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, &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;} static void Nativetest () {Aloge ("[%s]%d", __file__,__line__);} Static Jbooleannativesetvideosurface (jnienv *env, Jobject thiz, Jobject jsurface) {aloge ("[%s]%d", __FILE__,__LINE__); Surface = Android_view_surface_getsurface (env, Jsurface), if (Android::surface::isvalid (surface)) {Aloge ("surface is Valid ");} else {aloge ("surface is invalid"); return false;} Aloge ("[%s][%d]\n", __file__,__line__); return TRUE;} Static VOIDNATIVESHOWYUV (jnienv *env, jobject thiz,jbytearray yuvdata,jint width,jint height) {aloge ("width =%d,height = %d ", width,height); Jint len = Env->getarraylength (yuvdata); Aloge ("Len =%d", len); Jbyte *bytebuf = env->getbytearrayelements (yuvdata, 0); render (Bytebuf,len,surface,width, height);} Static Jninativemethod gmethods[] = {{"Nativetest", "() V", (void *) nativetest},{"Nativesetvideosurface", "(Lan droid/view/surface;) Z ", (void *) nativesetvideosurface},{" Nativeshowyuv "," ([BII) V ", (void *) nativeshowyuv},};static Const char* Const KCLASSPATHNAME = "com/example/myyuvviewer/mainactivity";//This function is only registers the native Metho    dsstatic int Register_com_example_myyuvviewer (jnienv *env) {aloge ("[%s]%d", __file__,__line__); Return Androidruntime::registernativemethods (env, Kclasspathname, Gmethods, Nelem (Gmethods));}    Jint jni_onload (javavm* vm, void* reserved) {Aloge ("[%s]%d", __file__,__line__);    jnienv* env = NULL;    Jint result =-1; If (Vm->getenv (void**) &env, jni_version_1_4)! = JNI_OK)        {Aloge ("error:getenv failed\n");    Goto bail; } assert (env! = NULL);   Aloge ("[%s]%d", __file__,__line__);        if (Register_com_example_myyuvviewer (env) < 0) {Aloge ("Error:mediaplayer native registration failed\n");    Goto bail; }/* Success--Return valid version number */result = Jni_version_1_4;bail:return result;}

Android.mk

Local_path:= $ (call My-dir) include $ (clear_vars) local_src_files:= showyuv.cpplocal_shared_libraries: = Libcutils Libutils libbinder     libui     Libgui libandroid_runtime libstagefright_foundationlocal_module:= LibshowYUVLOCAL _module_tags: = Testsinclude $ (build_shared_library)

The resulting so file is copied to the Java project in the Libs/armeabi directory, which is tied to SRC, without creating the directory manually.

So eclipse will automatically pack the so library into the apk.

Reprint Please specify source: http://blog.csdn.net/tung214/article/details/37762487

Yuvdata: Click to open link


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.