`
mmdev
  • 浏览: 12912198 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

庆祝一下,Android视频采集+H264编码成功

 
阅读更多

编码器使用的是x264的开源库,

很容易看懂的

简单的封装了一个JNI库

编码库在BBS里 CSDN的资源太难用了

http://www.eoeandroid.com/forum.php?mod=viewthread&tid=52739&extra=

x264的编译放方法

export ARM_ROOT=$ANDROID_NDK_ROOT
export ARM_INC=$ARM_ROOT/build/platforms/android-5/arch-arm/usr/include/
export ARM_LIB=$ARM_ROOT/build/platforms/android-5/arch-arm/usr/lib/
export ARM_TOOL=$ARM_ROOT/build/prebuilt/windows/arm-eabi-4.4.0
export ARM_LIBO=$ARM_TOOL/lib/gcc/arm-eabi/4.4.0
export PATH=$ARM_TOOL/bin:$PATH
export ARM_PRE=arm-eabi

./configure --prefix=/home/egmkang/libx264 --enable-shared /
-disable-asm --host=arm-linux --cross-prefix=arm-eabi-/
--extra-cflags=" -I$ARM_INC -fPIC -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,--noexecstack -MMD -MP "/
--extra-ldflags="-nostdlib -Bdynamic -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$ARM_LIB -nostdlib $ARM_LIB/crtbegin_dynamic.o $ARM_LIB/crtend_android.o -lc -lm -ldl -lgcc"

这里生成的是x264的静态库

整个工程唯一有点麻烦的是 生成 JNI 动态库的时候 报错 。。

后来发现是少链接了一个库,

于是根据x264的编译方法 在Android.mk添加一些配置就可以了。当然这就是难点,在网上查了很多都没有结果。

有些目录的参数自己调整哈

我把前面生成的libx264.a 和 x264.h 文件放到jni的libx264目录下了 有问题自己调整

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_C_INCLUDES +=$(LOCAL_PATH)/libx264/include
LOCAL_MODULE := H264Android
LOCAL_SRC_FILES := H264Android.c
LOCAL_LDFLAGS += $(LOCAL_PATH)/libx264/lib/libx264.a
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lgcc


include $(BUILD_SHARED_LIBRARY)

估计很多人都会发现很熟悉 嘻嘻 这个就是根据

http://www.cnblogs.com/mcodec/articles/1780598.html

改的 连文件名字都没有换!!比较懒

另: 编码的效率很低下啊

AndroidVideo.java

  1. importjava.io.File;
  2. importjava.io.RandomAccessFile;
  3. importandroid.app.Activity;
  4. importandroid.content.Intent;
  5. importandroid.os.Bundle;
  6. importandroid.view.View;
  7. importandroid.content.res.Configuration;
  8. importandroid.os.Bundle;
  9. importandroid.util.Log;
  10. importandroid.view.SurfaceHolder;
  11. importandroid.view.SurfaceView;
  12. importandroid.view.Window;
  13. importandroid.view.WindowManager;
  14. importandroid.view.SurfaceHolder.Callback;
  15. importandroid.graphics.PixelFormat;
  16. importandroid.hardware.Camera;
  17. publicclassAndroidVideoextendsActivityimplementsCallback,
  18. Camera.PictureCallback{
  19. privateSurfaceViewmSurfaceView=null;
  20. privateSurfaceHoldermSurfaceHolder=null;
  21. privateCameramCamera=null;
  22. privatebooleanmPreviewRunning=false;
  23. publicvoidonCreate(BundlesavedInstanceState){
  24. super.onCreate(savedInstanceState);
  25. getWindow().setFormat(PixelFormat.TRANSLUCENT);
  26. requestWindowFeature(Window.FEATURE_NO_TITLE);
  27. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  28. WindowManager.LayoutParams.FLAG_FULLSCREEN);
  29. setContentView(R.layout.camera);
  30. mSurfaceView=(SurfaceView)this.findViewById(R.id.surface_camera);
  31. mSurfaceHolder=mSurfaceView.getHolder();
  32. mSurfaceHolder.addCallback(this);
  33. mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  34. }
  35. @Override
  36. publicvoidonPictureTaken(byte[]data,Cameracamera){
  37. }
  38. @Override
  39. publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,
  40. intheight){
  41. if(mPreviewRunning){
  42. mCamera.stopPreview();
  43. }
  44. Camera.Parametersp=mCamera.getParameters();
  45. p.setPreviewSize(352,288);
  46. mCamera.setPreviewCallback(newH264Encoder(352,288));
  47. mCamera.setParameters(p);
  48. try{
  49. mCamera.setPreviewDisplay(holder);
  50. }catch(Exceptionex){
  51. }
  52. mCamera.startPreview();
  53. mPreviewRunning=true;
  54. }
  55. @Override
  56. publicvoidsurfaceCreated(SurfaceHolderholder){
  57. mCamera=Camera.open();
  58. }
  59. @Override
  60. publicvoidsurfaceDestroyed(SurfaceHolderholder){
  61. if(mCamera!=null){
  62. mCamera.setPreviewCallback(null);
  63. mCamera.stopPreview();
  64. mPreviewRunning=false;
  65. mCamera.release();
  66. mCamera=null;
  67. }
  68. }
  69. publicvoidonConfigurationChanged(ConfigurationnewConfig){
  70. try{
  71. super.onConfigurationChanged(newConfig);
  72. if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE){
  73. }elseif(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT){
  74. }
  75. }catch(Exceptionex){
  76. }
  77. }
  78. }
  79. classH264EncoderimplementsCamera.PreviewCallback{
  80. longencoder=0;
  81. RandomAccessFileraf=null;
  82. byte[]h264Buff=null;
  83. static{
  84. System.loadLibrary("H264Android");
  85. }
  86. privateH264Encoder(){};
  87. publicH264Encoder(intwidth,intheight){
  88. encoder=CompressBegin(width,height);
  89. h264Buff=newbyte[width*height*8];
  90. try{
  91. Filefile=newFile("/sdcard/camera.h264");
  92. raf=newRandomAccessFile(file,"rw");
  93. }catch(Exceptionex){
  94. Log.v("System.out",ex.toString());
  95. }
  96. };
  97. protectedvoidfinalize()
  98. {
  99. CompressEnd(encoder);
  100. if(null!=raf)
  101. {
  102. try{
  103. raf.close();
  104. }catch(Exceptionex){
  105. Log.v("System.out",ex.toString());
  106. }
  107. }
  108. try{
  109. super.finalize();
  110. }catch(Throwablee){
  111. //TODOAuto-generatedcatchblock
  112. e.printStackTrace();
  113. }
  114. }
  115. privatenativelongCompressBegin(intwidth,intheight);
  116. privatenativeintCompressBuffer(longencoder,inttype,byte[]in,intinsize,byte[]out);
  117. privatenativeintCompressEnd(longencoder);
  118. @Override
  119. publicvoidonPreviewFrame(byte[]data,Cameracamera){
  120. intresult=CompressBuffer(encoder,-1,data,data.length,h264Buff);
  121. try{
  122. if(result>0)
  123. raf.write(h264Buff,0,result);
  124. }catch(Exceptionex){
  125. Log.v("System.out",ex.toString());
  126. }
  127. }
  128. }

H264Android.c

  1. #include<string.h>
  2. #include<jni.h>
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include<arpa/inet.h>
  6. #include<x264.h>
  7. #defineDATA_MAX3000000
  8. #defineH264_MTU1024
  9. typedefstruct
  10. {
  11. x264_param_t*param;
  12. x264_t*handle;
  13. x264_picture_t*picture;
  14. x264_nal_t*nal;
  15. }Encoder;
  16. jlongJava_h264_com_H264Encoder_CompressBegin(JNIEnv*env,jobjectthiz,
  17. jintwidth,jintheight){
  18. Encoder*en=(Encoder*)malloc(sizeof(Encoder));
  19. en->param=(x264_param_t*)malloc(sizeof(x264_param_t));
  20. en->picture=(x264_param_t*)malloc(sizeof(x264_picture_t));
  21. x264_param_default(en->param);//setdefaultparam
  22. //en->param->rc.i_rc_method=X264_RC_CQP;
  23. en->param->i_log_level=X264_LOG_NONE;
  24. en->param->i_width=width;//setframewidth
  25. en->param->i_height=height;//setframeheight
  26. en->param->rc.i_lookahead=0;
  27. en->param->i_bframe=0;
  28. en->param->i_fps_num=5;
  29. en->param->i_fps_den=1;
  30. if((en->handle=x264_encoder_open(en->param))==0){
  31. return0;
  32. }
  33. /*Createanewpic*/
  34. x264_picture_alloc(en->picture,X264_CSP_I420,en->param->i_width,
  35. en->param->i_height);
  36. return(jlong)en;
  37. }
  38. jintJava_h264_com_H264Encoder_CompressEnd(JNIEnv*env,jobjectthiz,jlonghandle)
  39. {
  40. Encoder*en=(Encoder*)handle;
  41. if(en->picture)
  42. {
  43. x264_picture_clean(en->picture);
  44. free(en->picture);
  45. en->picture=0;
  46. }
  47. if(en->param)
  48. {
  49. free(en->param);
  50. en->param=0;
  51. }
  52. if(en->handle)
  53. {
  54. x264_encoder_close(en->handle);
  55. }
  56. free(en);
  57. return0;
  58. }
  59. jintJava_h264_com_H264Encoder_CompressBuffer(JNIEnv*env,jobjectthiz,jlonghandle,jinttype,jbyteArrayin,jintinsize,jbyteArrayout)
  60. {
  61. Encoder*en=(Encoder*)handle;
  62. x264_picture_tpic_out;
  63. inti_data=0;
  64. intnNal=-1;
  65. intresult=0;
  66. inti=0,j=0;
  67. intnPix=0;
  68. jbyte*Buf=(jbyte*)(*env)->GetByteArrayElements(env,in,0);
  69. jbyte*h264Buf=(jbyte*)(*env)->GetByteArrayElements(env,out,0);
  70. unsignedchar*pTmpOut=h264Buf;
  71. intnPicSize=en->param->i_width*en->param->i_height;
  72. /*
  73. Y数据全部从在一块,UV数据使用interleave方式存储
  74. YYYY
  75. YYYY
  76. UVUV
  77. */
  78. jbyte*y=en->picture->img.plane[0];
  79. jbyte*v=en->picture->img.plane[1];
  80. jbyte*u=en->picture->img.plane[2];
  81. memcpy(en->picture->img.plane[0],Buf,nPicSize);
  82. for(i=0;i<nPicSize/4;i++)
  83. {
  84. *(u+i)=*(Buf+nPicSize+i*2);
  85. *(v+i)=*(Buf+nPicSize+i*2+1);
  86. }
  87. switch(type)
  88. {
  89. case0:
  90. en->picture->i_type=X264_TYPE_P;
  91. break;
  92. case1:
  93. en->picture->i_type=X264_TYPE_IDR;
  94. break;
  95. case2:
  96. en->picture->i_type=X264_TYPE_I;
  97. break;
  98. default:
  99. en->picture->i_type=X264_TYPE_AUTO;
  100. break;
  101. }
  102. if(x264_encoder_encode(en->handle,&(en->nal),&nNal,en->picture,&pic_out)<0)
  103. {
  104. return-1;
  105. }
  106. for(i=0;i<nNal;i++){
  107. memcpy(pTmpOut,en->nal[i].p_payload,en->nal[i].i_payload);
  108. pTmpOut+=en->nal[i].i_payload;
  109. result+=en->nal[i].i_payload;
  110. }
  111. returnresult;
  112. }


转自http://blog.chinaunix.net/link.php?url=http://blog.csdn.net%2Fzblue78%2Farchive%2F2010%2F12%2F06%2F6058147.aspx%23

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics