Ubuntu下为AndroidStudio编译并使用x264(二)AndroidStudio部分

来源:互联网 发布:seo软件 编辑:程序博客网 时间:2024/06/07 05:24
Android使用C/C++代码或库需要通过JNI方式,详细的可见相关文章。

1. 添加C/C++源文件

复制/opt/android/ndk/android-ndk-r10e/resources/x264下的文件:
x264.h
x264_config.h
到jni目录下

在jni目录下添加
x264encoder.h
x264encoder.cpp
main.cpp
三个源文件,详细源码如下:

  1. /*
  2.  * \File
  3.  * x264encoder.h
  4.  * \Author
  5.  * Hank
  6.  */
  7. #ifndef x264encoder_h 
  8. #define x264encoder_h 


  9. extern "C" 
  10. { 
  11. #include "stdint.h" 
  12. #include "x264.h" 


  13.     enum bitrate_level 
  14.     { 
  15.         HIGH_LEVEL = 0, 
  16.         STANDARD_LEVEL = 1, 
  17.         MEDIUM_LEVEL = 2, 
  18.         LOW_LEVEL = 3, 
  19.     }; 


  20.     class X264Encoder 
  21.     { 
  22.         public: 
  23.             X264Encoder(); 
  24.             ~X264Encoder(); 


  25.             bool openX264Encoder(); 
  26.             // long x264EncoderProcess(uint8_t *pSrcData, int srcDataSize, x264_nal_t **nals, int& nalsCount);


  27.             long x264EncoderProcess(x264_picture_t *pPicture, x264_nal_t **nals, int& nalsCount);


  28.             bool closeX264Encoder(); 


  29.             void setSourceFormat(unsigned int sourcformat); 
  30.             void setResolution(unsigned int w, unsigned int h); 
  31.             void setBitrate(unsigned int i_bitrate); 
  32.             void setFps(unsigned int fps); 
  33.             void setI_KeyInt_Max(unsigned int i_frame_max); 
  34.             void setQp_Max(unsigned int qp_max); 
  35.             void setQp_Min(unsigned int qp_min); 


  36.             void forceIDRFrame(); 


  37.             void upgradeBitrateLevel(); 
  38.             void declineBitrateLevel(); 
  39.             void setLeastBitrateLevel(); 




  40.         private: 
  41.             x264_param_t *pParameter; 
  42.             x264_t *x264EncoderHandle; 
  43.             // x264_picture_t *pPicture; 
  44.             x264_picture_t *pOutput; 


  45.             unsigned int sourceFormat; 
  46.             // unsigned int i_bitrate; 
  47.             unsigned int bitratelevel; 
  48.             unsigned int i_fps; 
  49.             unsigned int i_keyint_max; 
  50.             unsigned int width; 
  51.             unsigned int height; 
  52.             unsigned int qp_max; 
  53.             unsigned int qp_min; 


  54.             unsigned int current_f_rf_constant; 
  55.             unsigned int userSetting_f_rf_constant; 


  56.             int64_t frameNo; 


  57.             bool isForceIDRFrameEnabled; 
  58.      }; 
  59. } 
  60. #endif

/*
 * \File
 *   x264encoder.cpp
 * \Author
 *   Hank
 */

  1. #include <stdlib.h> 
  2. #include <string.h> 
  3. #include "x264encoder.h" 


  4. // new version for x264 encoder 
  5. X264Encoder::X264Encoder() 
  6. { 
  7.      this->bitratelevel = STANDARD_LEVEL; 
  8.      qp_max = 30; 
  9.      qp_min = 0; 
  10.      i_fps = 20; 
  11.      i_keyint_max = 300; 
  12.      width = 352; 
  13.      height = 288; 


  14.      frameNo = 0; 
  15.      isForceIDRFrameEnabled = false; 


  16.      pParameter = NULL; 
  17.      x264EncoderHandle = NULL; 
  18.      // pPicture = NULL; 
  19.      pOutput = NULL; 
  20. } 


  21. X264Encoder::~X264Encoder() 
  22. { 
  23.      this->closeX264Encoder(); 
  24. } 


  25. void X264Encoder::setSourceFormat(unsigned int sourcformat) 
  26. { 
  27.      this->sourceFormat = sourcformat; 
  28. } 


  29. void X264Encoder::setResolution(unsigned int w, unsigned int h) 
  30. { 
  31.      width = w; 
  32.      height = h; 
  33. } 


  34. void X264Encoder::setBitrate(unsigned int i_bitrate) 
  35. { 
  36.      if (i_bitrate > 0 && i_bitrate <= 64) { 
  37.           this->bitratelevel = LOW_LEVEL; 
  38.      }else if(i_bitrate > 64 && i_bitrate <= 128){ 
  39.           this->bitratelevel = MEDIUM_LEVEL; 
  40.      }else if (i_bitrate > 128 && i_bitrate <= 256) { 
  41.           this->bitratelevel = STANDARD_LEVEL; 
  42.      }else if (i_bitrate > 256 && i_bitrate <= 384) { 
  43.           this->bitratelevel = HIGH_LEVEL; 
  44.      }else if (i_bitrate > 384 && i_bitrate <= 512) { 
  45.           this->bitratelevel = HIGH_LEVEL; 
  46.      }else { 
  47.           this->bitratelevel = STANDARD_LEVEL; 
  48.      } 
  49. } 


  50. void X264Encoder::setFps(unsigned int fps) 
  51. { 
  52.      i_fps = fps; 
  53. } 


  54. void X264Encoder::setI_KeyInt_Max(unsigned int i_frame_max) 
  55. { 
  56.      i_keyint_max = i_frame_max; 
  57. } 


  58. void X264Encoder::setQp_Max(unsigned int qp_max) 
  59. { 
  60.      this->qp_max = qp_max; 
  61. } 


  62. void X264Encoder::setQp_Min(unsigned int qp_min) 
  63. { 
  64.      this->qp_min = qp_min; 
  65. } 


  66. bool X264Encoder::openX264Encoder() { 
  67.     this->closeX264Encoder(); 


  68.     if(!pParameter) 
  69.     { 
  70.         pParameter = (x264_param_t *)malloc(sizeof(x264_param_t)); 


  71.         if (!pParameter) { 
  72.             this->closeX264Encoder(); 
  73.             return false; 
  74.         } 
  75.         memset(pParameter, 0, sizeof(x264_param_t)); 
  76.     } 


  77.     int ret = x264_param_default_preset(pParameter, "ultrafast", "zerolatency"); 
  78.     if (ret != 0) { 
  79.         this->closeX264Encoder(); 
  80.         return false; 
  81.     } 


  82.     pParameter->i_level_idc = 30; 


  83.     pParameter->i_width = width;
  84.     pParameter->i_height = height;


  85.     pParameter->b_deterministic = 1; 
  86.     // pParameter->b_sliced_threads = 1; 
  87.     pParameter->i_threads = 1; 


  88.     pParameter->i_csp = X264_CSP_I420;//X264_CSP_NV12;//X264_CSP_I420; 


  89.     pParameter->i_fps_num = i_fps;
  90.     pParameter->i_fps_den = 1;
  91.     pParameter->i_bframe = 0;
  92.     pParameter->i_keyint_max = i_keyint_max;
  93.     
  94.     // pParameter->b_open_gop = 1;
  95.     
  96.     // pParameter->rc.i_bitrate = i_bitrate;
  97.     
  98.     pParameter->rc.i_rc_method = X264_RC_CRF;//X264_RC_CQP;
  99.     
  100.     if (this->bitratelevel == LOW_LEVEL) {
  101.     pParameter->rc.f_rf_constant = 32;
  102.     }else if(this->bitratelevel == MEDIUM_LEVEL){
  103.     pParameter->rc.f_rf_constant = 29;
  104.     }else if (this->bitratelevel == STANDARD_LEVEL) {
  105.     pParameter->rc.f_rf_constant = 26;
  106.     }else if (this->bitratelevel == HIGH_LEVEL) {
  107.     pParameter->rc.f_rf_constant = 24;
  108.     }else {
  109.     pParameter->rc.f_rf_constant = 24;
  110.     }
  111.     
  112.     current_f_rf_constant = pParameter->rc.f_rf_constant;
  113.     userSetting_f_rf_constant = pParameter->rc.f_rf_constant;
  114.     
  115.     // from huxiaopeng
  116.     pParameter->analyse.b_transform_8x8 = 1;
  117.     pParameter->rc.f_aq_strength = 1.5;
  118.     
  119.     pParameter->rc.i_aq_mode = 0;
  120.     pParameter->rc.f_qcompress = 0.0;
  121.     pParameter->rc.f_ip_factor = 0.5;
  122.     pParameter->rc.f_rate_tolerance = 0.1;
  123.     
  124.     pParameter->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
  125.     pParameter->analyse.i_me_method = X264_ME_DIA;
  126.     pParameter->analyse.i_me_range = 16;
  127.     pParameter->analyse.i_subpel_refine = 2;
  128.     // pParameter->analyse.i_noise_reduction = 1;
  129.     
  130.     pParameter->i_slice_max_size = 1200;
  131.     
  132.     // pParameter->i_nal_hrd = X264_NAL_HRD_NONE;
  133.     
  134.     pParameter->b_deblocking_filter = 1;
  135.     pParameter->i_deblocking_filter_alphac0 = 4;
  136.     pParameter->i_deblocking_filter_beta = 4;
  137.     
  138.     pParameter->rc.b_mb_tree = 0;
  139.     
  140.     pParameter->i_log_level = X264_LOG_NONE;
  141.     
  142.     if(x264_param_apply_profile(pParameter, "baseline"))
  143.     //if(x264_param_apply_profile(pParameter, "main"))
  144.     {
  145.     this->closeX264Encoder();
  146.     
  147.     return false;
  148.     }
  149.     
  150.     if (!x264EncoderHandle) {
  151.     x264EncoderHandle = x264_encoder_open(pParameter);
  152.     
  153.     if (!x264EncoderHandle) {
  154.     this->closeX264Encoder();
  155.     
  156.     return false;
  157.     }
  158.     }


  159.     if (!pOutput) {
  160.     pOutput = (x264_picture_t *)malloc(sizeof(x264_picture_t));
  161.     
  162.     if (!pOutput) {
  163.     this->closeX264Encoder();
  164.     return false;
  165.     }
  166.     
  167.     memset(pOutput, 0, sizeof(x264_picture_t));
  168.     }
  169.     
  170.     return true;
  171. }


  172. void X264Encoder::forceIDRFrame() 
  173. { 
  174.         isForceIDRFrameEnabled = true; 
  175. } 


  176. void X264Encoder::upgradeBitrateLevel() 
  177. { 
  178.         /* 
  179.            if (this->bitratelevel == HIGH_LEVEL) { 
  180.            return; 
  181.            } 


  182.            this->bitratelevel++; 


  183.            if (this->bitratelevel == LOW_LEVEL) { 
  184.            pParameter->rc.f_rf_constant = 30; 
  185.            }else if(this->bitratelevel == MEDIUM_LEVEL){ 
  186.            pParameter->rc.f_rf_constant = 27; 
  187.            }else if (this->bitratelevel == STANDARD_LEVEL) { 
  188.            pParameter->rc.f_rf_constant = 24; 
  189.            }else if (this->bitratelevel == HIGH_LEVEL) { 
  190.            pParameter->rc.f_rf_constant = 22; 
  191.            }else { 
  192.            pParameter->rc.f_rf_constant = 23; 
  193.            } 
  194.          */ 


  195.         if (userSetting_f_rf_constant >= current_f_rf_constant) { 
  196.                 return; 
  197.         } 


  198.         pParameter->rc.f_rf_constant--; 
  199.         current_f_rf_constant = pParameter->rc.f_rf_constant; 


  200.         x264_encoder_reconfig(x264EncoderHandle, pParameter); 
  201. } 


  202. void X264Encoder::setLeastBitrateLevel() 
  203. { 
  204.         pParameter->rc.f_rf_constant = 32; 
  205.         current_f_rf_constant = pParameter->rc.f_rf_constant; 


  206.         x264_encoder_reconfig(x264EncoderHandle, pParameter); 
  207. } 


  208. void X264Encoder::declineBitrateLevel() 
  209. { 


  210.         if (32 <= current_f_rf_constant) { 
  211.                 return; 
  212.         } 


  213.         pParameter->rc.f_rf_constant++; 
  214.         current_f_rf_constant = pParameter->rc.f_rf_constant; 


  215.         x264_encoder_reconfig(x264EncoderHandle, pParameter); 
  216. } 


  217. long X264Encoder::x264EncoderProcess(x264_picture_t *pPicture, x264_nal_t **nals, int& nalsCount)
  218. { 
  219.     pPicture->i_pts = (int64_t)(frameNo * pParameter->i_fps_den);
  220.     pPicture->i_type = X264_TYPE_AUTO;
  221.     pPicture->i_qpplus1 = 0;//X264_QP_AUTO;
  222.     
  223.     if (isForceIDRFrameEnabled) {
  224.     pPicture->i_type = X264_TYPE_IDR;
  225.     isForceIDRFrameEnabled = false;
  226.     }
  227.     
  228.     int32_t framesize = -1;
  229.     
  230.     
  231.     framesize = x264_encoder_encode(x264EncoderHandle, nals, &nalsCount, pPicture, pOutput);
  232.     
  233.     
  234.     if (framesize>0) {
  235.     frameNo++;
  236.     }
  237.     
  238.     return framesize;
  239. } 


  240.  
  241. bool X264Encoder::closeX264Encoder() 
  242. { 
  243.     if (pOutput) {
  244.     free(pOutput);
  245.     pOutput = NULL;
  246.     }
  247.     /*
  248.     if (pPicture) {
  249.     free(pPicture);
  250.     pPicture = NULL;
  251.     }
  252.     */
  253.     if (pParameter) {
  254.     free(pParameter);
  255.     pParameter = NULL;
  256.     }
  257.     
  258.     if (x264EncoderHandle) {
  259.     x264_encoder_close(x264EncoderHandle);
  260.     x264EncoderHandle = NULL;
  261.     }
  262.     
  263.     return true;
  264. }

/*
 * \File
 *   main.cpp
 * \Author
 *   Hank
 */


  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <arpa/inet.h>
  4. #include <stdio.h>
  5. #include <wchar.h>
  6. #include <time.h>


  7. #include <jni.h>


  8. /*for android logs*/
  9. #include <android/log.h>


  10. #include "x264.h"
  11. #include "x264_config.h"
  12. #include "x264encoder.h"


  13. #define LOG_TAG "android-ffmpeg-tutorial01"
  14. #define LOGI(...) __android_log_print(4, LOG_TAG, __VA_ARGS__);
  15. #define LOGE(...) __android_log_print(6, LOG_TAG, __VA_ARGS__);






  16. jint naMain(JNIEnv *pEnv, jobject pObj, jobject pMainAct, 
  17.                 jstring pFileName, jint pNumOfFrames,
  18.                 jint picWidth, jint picHeight) {
  19.     /* Preset */
  20.     int numOfFrames = pNumOfFrames;
  21.     int pictureWidth = picWidth;
  22.     int pictureHeight = picHeight;
  23.     int presetBitrate = 512;
  24.     int presetFps = 25;
  25.     int pictureSize = pictureWidth * pictureHeight;
  26.     int encodeTime = 0;
  27.     
  28.     X264Encoder x264Encoder;
  29.     
  30.     x264Encoder.setBitrate(presetBitrate);
  31.     x264Encoder.setResolution(pictureWidth,pictureHeight);
  32.     x264Encoder.setFps(presetFps);
  33.     
  34.     char *yuvFilename = NULL;
  35.     char *avcFilename = NULL;
  36.     char str[80];
  37.     
  38.     FILE *inputFile = NULL;
  39.     FILE *outputFile = NULL;
  40.     
  41.     // Get C string from JNI jstring
  42.     yuvFilename = (char *)pEnv->GetStringUTFChars(pFileName, NULL);
  43.     if((inputFile = fopen(yuvFilename,"rb")) == NULL){
  44.     LOGI("Can not open inputfile %s", yuvFilename);
  45.     return -1;
  46.     }
  47.     
  48.     strcpy(str, yuvFilename);
  49.     strcat(str, ".h264");
  50.     avcFilename = str;
  51.     LOGI("Output file: %s", avcFilename);
  52.     if ((outputFile = fopen(avcFilename,"wb")) == NULL) {
  53.     LOGI("Can not open outputfile %s", avcFilename);
  54.     return -1;
  55.     }
  56.     
  57.     
  58.     x264_picture_t inputPicture;
  59.     x264_picture_alloc(&inputPicture, X264_CSP_I420, pictureWidth, pictureHeight);
  60.     
  61.     x264_nal_t *p_nals = NULL;
  62.     int nalsCount = 0;
  63.     int ret = 0;
  64.     int j = 0;
  65.     
  66.     
  67.     if(x264Encoder.openX264Encoder())
  68.     {
  69.     struct timeval start, end;
  70.     struct timeval sum;
  71.     sum.tv_sec = 0;
  72.     sum.tv_usec = 0;
  73.     
  74.     /* Including the time of read & write file
  75.     gettimeofday(&start, NULL);
  76.     LOGI("Encode start time : %ld.%ld", start.tv_sec, start.tv_usec);
  77.     */
  78.     
  79.     for(j=0; j<numOfFrames; j++)
  80.     {
  81.             ret = fread(inputPicture.img.plane[0],1,pictureSize, inputFile);
  82.             if (ret < pictureSize)
  83.             {
  84.             break;
  85.             }
  86.             fread(inputPicture.img.plane[1],1,pictureSize/4, inputFile);
  87.             fread(inputPicture.img.plane[2],1,pictureSize/4, inputFile);
  88.             
  89.             gettimeofday(&start, NULL);
  90.             
  91.             x264Encoder.x264EncoderProcess(&inputPicture,&p_nals,nalsCount);
  92.             
  93.             gettimeofday(&end, NULL);
  94.             
  95.             if (end.tv_sec > start.tv_sec) {
  96.             sum.tv_sec += (end.tv_sec - (start.tv_sec + 1));
  97.             sum.tv_usec += ((1000000 - start.tv_usec) + end.tv_usec);
  98.             LOGI("A Spend time: %ld.%ld", sum.tv_sec, sum.tv_usec);
  99.             } else {
  100.             sum.tv_sec += (end.tv_sec - start.tv_sec);
  101.             sum.tv_usec += (end.tv_usec-start.tv_usec);
  102.             LOGI("B Spend time: %ld.%ld", sum.tv_sec, sum.tv_usec);
  103.             }
  104.             
  105.             if(p_nals)
  106.             {
  107.             for(int i=0; i<nalsCount; i++)
  108.             {
  109.             ret = fwrite(p_nals[i].p_payload, p_nals[i].i_payload, 1, outputFile);
  110.             LOGI("Write NO %d frame", j);
  111.             LOGI("Should write %d bytes, in fact write %d bytes into %s", p_nals[i].i_payload, ret, avcFilename);
  112.             }
  113.             }
  114.     }
  115.     
  116.     /* Including the time of read & write file
  117.     gettimeofday(&end, NULL);
  118.     LOGI("Encode end time : %ld.%ld", end.tv_sec, end.tv_usec);
  119.     if (end.tv_sec > start.tv_sec){
  120.     encodeTime = (end.tv_sec - (start.tv_sec+1))*1000000 + ((1000000-start.tv_usec) + end.tv_usec);
  121.     LOGI("Spend time: %ld.%ld", (end.tv_sec - (start.tv_sec+1)), ((1000000-start.tv_usec) + end.tv_usec));
  122.     } else {
  123.     encodeTime = (end.tv_sec - start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);
  124.     LOGI("Spend time: %ld.%ld", (end.tv_sec - start.tv_sec), end.tv_usec-start.tv_usec);
  125.     }
  126.     */
  127.     encodeTime = (sum.tv_sec + (sum.tv_usec/1000000))*1000000 + (sum.tv_usec%1000000);
  128.     LOGI("Spend time: %ld.%ld", sum.tv_sec, sum.tv_usec);
  129.     
  130.     }
  131.     
  132.     fclose(inputFile);
  133.     fclose(outputFile);
  134.     
  135.     LOGI("Closed the files!");
  136.     
  137.     x264_picture_clean(&inputPicture);
  138.     
  139.     x264Encoder.closeX264Encoder();
  140.     LOGI("Closed the handler of encoder!");
  141.     
  142.     return encodeTime;
  143.     //return 0;
  144. }




  145. static const JNINativeMethod gMethods[] = { 
  146.     {"naMain",
  147.     "(Lroman10/tutorial/android_ffmpeg_tutorial01/MainActivity;Ljava/lang/String;III)I",
  148.     (void*)naMain
  149.     },
  150. };


  151. jint JNI_OnLoad(JavaVM* vm, void *reserved)
  152. {
  153.     JNIEnv* env = NULL; jint result = -1;
  154.     
  155.     if((vm->GetEnv((void**)&env, JNI_VERSION_1_6)) != JNI_OK) return -1;
  156.     
  157.     jclass clazz; static const char* const
  158.     kClassName="roman10/tutorial/android_ffmpeg_tutorial01/MainActivity";
  159.     
  160.     clazz = env->FindClass(kClassName); if(clazz == NULL) { printf("cannot
  161.     get class:%s\n", kClassName); return -1; }
  162.     
  163.     if(env->RegisterNatives(clazz, gMethods,
  164.     sizeof(gMethods)/sizeof(gMethods[0]))!= JNI_OK) { printf("register
  165.     native method failed!\n"); return -1; }
  166.     
  167.     return JNI_VERSION_1_6;
  168. }

2. 修改相关配置并编译

1). 修改jni/Android.mk成如下:
#
# \File
#   Android.mk
#
LOCAL_PATH := $(call my-dir)


include $(CLEAR_VARS)


LOCAL_MODULE    := tutorial01
#LOCAL_SRC_FILES := tutorial01.c
LOCAL_SRC_FILES := x264encoder.cpp main.cpp
LOCAL_LDLIBS := -llog -ljnigraphics -lz 
#LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil
LOCAL_SHARED_LIBRARIES := libx264


include $(BUILD_SHARED_LIBRARY)
$(call import-module,x264-snapshot-20151015-2245/android/arm)




2). 修改 jni/Application.mk成如下:
#
# \File
#   Android.mk
#
APP_ABI := armeabi
#APP_ABI := armeabi-v7a
APP_PLATFORM := android-10




3). 修改 src/build.gradle成如下
apply plugin: 'com.android.application'


android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"


    defaultConfig {
        applicationId "roman10.tutorial.android_ffmpeg_tutorial01"
        minSdkVersion 19
        targetSdkVersion 23


        sourceSets.main{
            jni.srcDirs=[]
            jniLibs.srcDir "src/main/libs"
        }
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
        debug {
            debuggable true
            jniDebuggable true
            renderscriptDebuggable false
        }
    }
}


dependencies {
    compile 'com.android.support:support-v4:18.0.0'
}


4). 编译
在main目录下:
$ cd app/src/main
$ ndk-build
[armeabi] Compile++ thumb: tutorial01 <= x264encoder.cpp
[armeabi] Compile++ thumb: tutorial01 <= main.cpp
[armeabi] Prebuilt       : libx264.so <= <NDK>/sources/x264-snapshot-20151015-2245/android/arm/lib/
[armeabi] SharedLibrary  : libtutorial01.so
[armeabi] Install        : libtutorial01.so => libs/armeabi/libtutorial01.so
[armeabi] Install        : libx264.so => libs/armeabi/libx264.so


表示编码成功;


3. 修改java源文件

修改MainActivity.java,添加调用的接口
public class MainActivity extends Activity {
    
    // 调用参数的预定义
    private static final String FRAME_DUMP_FOLDER_PATH = Environment.getExternalStorageDirectory()
        + File.separator + "android-264-encoder";
    private static final String INPUT_YUV_FILENAME = "test_1920x1080.yuv";
    private static int pWidth = 1920;
    private static int pHeight = 1080;




    @override
    protected Void doInBackground(Void... params){
        // 实际调用
        encodeTime = naMain(mlOuterAct,
            FRAME_DUMP_FOLDER_PATH + File.separator + INPUT_YUV_FILENAME,
            mlNumOfFrames,
            pWidth, pHeight );
    }




    /*
     *  接口声明
     *    pVideoFileName : 表示输入文件名
     *    pNumOfFrame    : 编码帧数
     *    Width          : YUV源文件的图像宽度
     *    Height         : YUV源文件的图像高度
     */
    private static native int naMain(MainActivity pObject,
          String pVideoFileName, int pNumOfFrame,
          int Width, int Height);


    // 库加载
    static {
        System.loadLibrary("x264");
        System.loadLibrary("tutorial01");
    }
}

再以android工程方式,编译运行;
1 0
原创粉丝点击