移植FFmpeg到Android ics


想到把FFmpeg移植到Android上面

网上有现成的2.2的移植,可以下载下来,链接https://github.com/havlenapetr,里面的ffmpeg和framework下面的libaudio和libviedo两个so,就是全部的东西。

看过一些东西,都说不开放某些代码,挺没劲的,人家都已经放出全部代码了,有什么藏匿的。

app下面的代码几乎不需要修改,就是一些编译的错误,就是framework下面的本地适配需要需要改一下,适应一下ics,就是surface.cpp这个文件。

  1. /* 
  2. * Copyright (C) 2009 The Android Open Source Project 
  3. * 
  4. * Licensed under the Apache License, Version 2.0 (the "License"); 
  5. * you may not use this file except in compliance with the License. 
  6. * You may obtain a copy of the License at 
  7. * 
  8. * http://www.apache.org/licenses/LICENSE-2.0 
  9. * 
  10. * Unless required by applicable law or agreed to in writing, software 
  11. * distributed under the License is distributed on an "AS IS" BASIS, 
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13. * See the License for the specific language governing permissions and 
  14. * limitations under the License. 
  15. */  
  16. #include <android/surface.h>   
  17. #include <surfaceflinger/Surface.h>   
  18. #include <utils/Log.h>   
  19. #include <SkBitmap.h>   
  20. #include <SkCanvas.h>   
  21.   
  22. #define TAG "SurfaceWrapper"   
  23.   
  24. using namespace android;  
  25.   
  26. static Surface *sSurface;  
  27. static SkBitmap sBitmapClient;  
  28. static SkBitmap sBitmapSurface;  
  29.   
  30. static Surface *getNativeSurface (JNIEnv * env, jobject jsurface)  
  31. {  
  32.     jclass clazz = env->FindClass ("android/view/Surface");  
  33.     jfieldID field_surface = env->GetFieldID (clazz, "mNativeSurface""I");  
  34.     if (field_surface == NULL)  
  35.     {  
  36.         return NULL;  
  37.     }  
  38.     return (Surface *) env->GetIntField (jsurface, field_surface);  
  39. }  
  40.   
  41. static int initBitmap (SkBitmap * bitmap, int format, int width, int height, bool allocPixels)  
  42. {  
  43.     switch (format)  
  44.     {  
  45.     case PIXEL_FORMAT_RGBA_8888:  
  46.         bitmap->setConfig (SkBitmap::kARGB_8888_Config, width, height);  
  47.         break;  
  48.   
  49.     case PIXEL_FORMAT_RGBA_4444:  
  50.         bitmap->setConfig (SkBitmap::kARGB_4444_Config, width, height);  
  51.         break;  
  52.   
  53.     case PIXEL_FORMAT_RGB_565:  
  54.         bitmap->setConfig (SkBitmap::kRGB_565_Config, width, height);  
  55.         break;  
  56.   
  57.     case PIXEL_FORMAT_A_8:  
  58.         bitmap->setConfig (SkBitmap::kA8_Config, width, height);  
  59.         break;  
  60.   
  61.     default:  
  62.         bitmap->setConfig (SkBitmap::kNo_Config, width, height);  
  63.         break;  
  64.     }  
  65.   
  66.     if (allocPixels)  
  67.     {  
  68.         bitmap->setIsOpaque (true);  
  69. //-- alloc array of pixels   
  70.         if (!bitmap->allocPixels ())  
  71.         {  
  72.             return -1;  
  73.         }  
  74.     }  
  75.     return 0;  
  76. }  
  77.   
  78. int AndroidSurface_register (JNIEnv * env, jobject jsurface)  
  79. {  
  80.     __android_log_print (ANDROID_LOG_INFO, TAG, "registering video surface");  
  81.   
  82.     sSurface = getNativeSurface (env, jsurface);  
  83.     if (sSurface == NULL)  
  84.     {  
  85.         return ANDROID_SURFACE_RESULT_JNI_EXCEPTION;  
  86.     }  
  87.   
  88.     __android_log_print (ANDROID_LOG_INFO, TAG, "registered");  
  89.   
  90.     return ANDROID_SURFACE_RESULT_SUCCESS;  
  91. }  
  92.   
  93. int AndroidSurface_getPixels (int width, int height, void **pixels)  
  94. {  
  95.     __android_log_print (ANDROID_LOG_INFO, TAG, "getting surface's pixels %ix%i", width, height);  
  96.     if (sSurface == NULL)  
  97.     {  
  98.         return ANDROID_SURFACE_RESULT_JNI_EXCEPTION;  
  99.     }  
  100.     if (initBitmap (&sBitmapClient, PIXEL_FORMAT_RGB_565, width, height, true) < 0)  
  101.     {  
  102.         return ANDROID_SURFACE_RESULT_COULDNT_INIT_BITMAP_CLIENT;  
  103.     }  
  104.     *pixels = sBitmapClient.getPixels ();  
  105.     __android_log_print (ANDROID_LOG_INFO, TAG, "getted");  
  106.     return ANDROID_SURFACE_RESULT_SUCCESS;  
  107. }  
  108.   
  109. static void doUpdateSurface ()  
  110. {  
  111.     SkCanvas canvas (sBitmapSurface);  
  112.     SkRect surface_sBitmapClient;  
  113.     SkRect surface_sBitmapSurface;  
  114.     SkMatrix matrix;  
  115.   
  116.     surface_sBitmapSurface.set (0, 0, sBitmapSurface.width (), sBitmapSurface.height ());  
  117.     surface_sBitmapClient.set (0, 0, sBitmapClient.width (), sBitmapClient.height ());  
  118.     matrix.setRectToRect (surface_sBitmapClient, surface_sBitmapSurface, SkMatrix::kFill_ScaleToFit);  
  119.   
  120.     canvas.drawBitmapMatrix (sBitmapClient, matrix);  
  121. }  
  122.   
  123. static int prepareSurfaceBitmap (Surface::SurfaceInfo * info)  
  124. {  
  125.     if (initBitmap (&sBitmapSurface, info->format, info->w, info->h, false) < 0)  
  126.     {  
  127.         return -1;  
  128.     }  
  129.     sBitmapSurface.setPixels (info->bits);  
  130.     return 0;  
  131. }  
  132.   
  133. int AndroidSurface_updateSurface ()  
  134. {  
  135.     static Surface::SurfaceInfo surfaceInfo;  
  136.     if (sSurface == NULL)  
  137.     {  
  138.         return ANDROID_SURFACE_RESULT_JNI_EXCEPTION;  
  139.     }  
  140.   
  141.     if (!Surface::isValid (sSurface))  
  142.     {  
  143.         return ANDROID_SURFACE_RESULT_NOT_VALID;  
  144.     }  
  145.     if (sSurface->lock (&surfaceInfo,NULL) < 0)  
  146.     {  
  147.         return ANDROID_SURFACE_RESULT_COULDNT_LOCK;  
  148.     }  
  149.   
  150.     if (prepareSurfaceBitmap (&surfaceInfo) < 0)  
  151.     {  
  152.         return ANDROID_SURFACE_RESULT_COULDNT_INIT_BITMAP_SURFACE;  
  153.     }  
  154.   
  155.     doUpdateSurface ();  
  156.   
  157.     if (sSurface->unlockAndPost () < 0)  
  158.     {  
  159.         return ANDROID_SURFACE_RESULT_COULDNT_UNLOCK_AND_POST;  
  160.     }  
  161.     return ANDROID_SURFACE_RESULT_SUCCESS;  
  162. }  
  163.   
  164. int AndroidSurface_unregister ()  
  165. {  
  166.     __android_log_print (ANDROID_LOG_INFO, TAG, "unregistering video surface");  
  167.     __android_log_print (ANDROID_LOG_INFO, TAG, "unregistered");  
  168.     return ANDROID_SURFACE_RESULT_SUCCESS;  
  169. }  

改完以后,编译出来的apk就是可以播放的,但是效果相当的差,问题太多了,需要时间来分析一下。

更多Android相关信息见Android 专题页面 http://www.bkjia.com/topicnews.aspx?tid=11

相关内容