想弄個小東西,自己練習一下,就想到把FFmpeg移植到android上面
網上有現成的2.2的移植,可以下載下來,連結https://github.com/havlenapetr,裡面的ffmpeg和framework下面的libaudio和libviedo兩個so,就是全部的東西。
看過一些東西,都說不開放某些代碼,挺沒勁的,人家都已經放出全部代碼了,有什麼藏匿的。
app下面的代碼幾乎不需要修改,就是一些編譯的錯誤,就是framework下面的本地適配需要需要改一下,適應一下ics,就是surface.cpp這個檔案。
/** Copyright (C) 2009 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#include <android/surface.h>#include <surfaceflinger/Surface.h>#include <utils/Log.h>#include <SkBitmap.h>#include <SkCanvas.h>#define TAG "SurfaceWrapper"using namespace android;static Surface *sSurface;static SkBitmap sBitmapClient;static SkBitmap sBitmapSurface;static Surface *getNativeSurface (JNIEnv * env, jobject jsurface){jclass clazz = env->FindClass ("android/view/Surface");jfieldID field_surface = env->GetFieldID (clazz, "mNativeSurface", "I");if (field_surface == NULL){return NULL;}return (Surface *) env->GetIntField (jsurface, field_surface);}static int initBitmap (SkBitmap * bitmap, int format, int width, int height, bool allocPixels){switch (format){case PIXEL_FORMAT_RGBA_8888:bitmap->setConfig (SkBitmap::kARGB_8888_Config, width, height);break;case PIXEL_FORMAT_RGBA_4444:bitmap->setConfig (SkBitmap::kARGB_4444_Config, width, height);break;case PIXEL_FORMAT_RGB_565:bitmap->setConfig (SkBitmap::kRGB_565_Config, width, height);break;case PIXEL_FORMAT_A_8:bitmap->setConfig (SkBitmap::kA8_Config, width, height);break;default:bitmap->setConfig (SkBitmap::kNo_Config, width, height);break;}if (allocPixels){bitmap->setIsOpaque (true);//-- alloc array of pixelsif (!bitmap->allocPixels ()){return -1;}}return 0;}int AndroidSurface_register (JNIEnv * env, jobject jsurface){__android_log_print (ANDROID_LOG_INFO, TAG, "registering video surface");sSurface = getNativeSurface (env, jsurface);if (sSurface == NULL){return ANDROID_SURFACE_RESULT_JNI_EXCEPTION;}__android_log_print (ANDROID_LOG_INFO, TAG, "registered");return ANDROID_SURFACE_RESULT_SUCCESS;}int AndroidSurface_getPixels (int width, int height, void **pixels){__android_log_print (ANDROID_LOG_INFO, TAG, "getting surface's pixels %ix%i", width, height);if (sSurface == NULL){return ANDROID_SURFACE_RESULT_JNI_EXCEPTION;}if (initBitmap (&sBitmapClient, PIXEL_FORMAT_RGB_565, width, height, true) < 0){return ANDROID_SURFACE_RESULT_COULDNT_INIT_BITMAP_CLIENT;}*pixels = sBitmapClient.getPixels ();__android_log_print (ANDROID_LOG_INFO, TAG, "getted");return ANDROID_SURFACE_RESULT_SUCCESS;}static void doUpdateSurface (){SkCanvas canvas (sBitmapSurface);SkRect surface_sBitmapClient;SkRect surface_sBitmapSurface;SkMatrix matrix;surface_sBitmapSurface.set (0, 0, sBitmapSurface.width (), sBitmapSurface.height ());surface_sBitmapClient.set (0, 0, sBitmapClient.width (), sBitmapClient.height ());matrix.setRectToRect (surface_sBitmapClient, surface_sBitmapSurface, SkMatrix::kFill_ScaleToFit);canvas.drawBitmapMatrix (sBitmapClient, matrix);}static int prepareSurfaceBitmap (Surface::SurfaceInfo * info){if (initBitmap (&sBitmapSurface, info->format, info->w, info->h, false) < 0){return -1;}sBitmapSurface.setPixels (info->bits);return 0;}int AndroidSurface_updateSurface (){static Surface::SurfaceInfo surfaceInfo;if (sSurface == NULL){return ANDROID_SURFACE_RESULT_JNI_EXCEPTION;}if (!Surface::isValid (sSurface)){return ANDROID_SURFACE_RESULT_NOT_VALID;}if (sSurface->lock (&surfaceInfo,NULL) < 0){return ANDROID_SURFACE_RESULT_COULDNT_LOCK;}if (prepareSurfaceBitmap (&surfaceInfo) < 0){return ANDROID_SURFACE_RESULT_COULDNT_INIT_BITMAP_SURFACE;}doUpdateSurface ();if (sSurface->unlockAndPost () < 0){return ANDROID_SURFACE_RESULT_COULDNT_UNLOCK_AND_POST;}return ANDROID_SURFACE_RESULT_SUCCESS;}int AndroidSurface_unregister (){__android_log_print (ANDROID_LOG_INFO, TAG, "unregistering video surface");__android_log_print (ANDROID_LOG_INFO, TAG, "unregistered");return ANDROID_SURFACE_RESULT_SUCCESS;}
改完以後,編譯出來的apk就是可以播放的,但是效果相當的差,問題太多了,需要時間來分析一下。