OSDN Git Service

init and deinit ffmpeg globally.
authorMichael Chen <omxcodec@gmail.com>
Fri, 9 Nov 2012 17:16:09 +0000 (01:16 +0800)
committerMichael Chen <omxcodec@gmail.com>
Fri, 9 Nov 2012 17:16:09 +0000 (01:16 +0800)
ffmpeg_utils/Android.mk
ffmpeg_utils/ffmpeg_utils.cpp
ffmpeg_utils/ffmpeg_utils.h
libstagefright/FFmpegExtractor/FFmpegExtractor.cpp
libstagefright/FFmpegExtractor/FFmpegExtractor.h
libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.cpp
libstagefright/codecs/ffmpegdec/adec/SoftFFmpegAudio.h
libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.cpp
libstagefright/codecs/ffmpegdec/vdec/SoftFFmpegVideo.h

index a339f6b..7bd7c71 100644 (file)
@@ -10,11 +10,16 @@ LOCAL_SRC_FILES := \
        ../../../external/ffmpeg/cmdutils.c
 
 LOCAL_C_INCLUDES := \
+       $(TOP)/frameworks/base/include \
+       $(TOP)/external/sdl/include
+
+LOCAL_C_INCLUDES += \
        $(FFMPEG_SRC_DIR) \
        $(FFMPEG_BUILD_DIR)
 
 LOCAL_SHARED_LIBRARIES := \
-       libutils
+       libutils          \
+       libSDL
 
 FFMPEG_BUILD_LIBS := \
         -L$(FFMPEG_BUILD_DIR)/libavutil         \
index 4625b50..6438a77 100644 (file)
@@ -17,6 +17,8 @@
 #define LOG_TAG "FFMPEG"
 #include <utils/Log.h>
 
+#include <utils/Errors.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -48,6 +50,11 @@ extern "C" {
 #include "libavcodec/avfft.h"
 #include "libswresample/swresample.h"
 
+#include "cmdutils.h"
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
 #undef strncpy
 #include <string.h>
 
@@ -55,13 +62,43 @@ extern "C" {
 }
 #endif
 
-//////////////////////////////////////////////////////////////////////////////////
 // log
-//////////////////////////////////////////////////////////////////////////////////
 static int flags;
 
+// dummy
+const char program_name[] = "dummy";
+const int program_birth_year = 2012;
+
+// init ffmpeg
+static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+static int ref_count = 0;
+
 namespace android {
 
+//////////////////////////////////////////////////////////////////////////////////
+// dummy
+//////////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void av_noreturn exit_program(int ret)
+{
+    // do nothing
+}
+
+void show_help_default(const char *opt, const char *arg)
+{
+    // do nothing
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////
+// log
+//////////////////////////////////////////////////////////////////////////////////
 static void sanitize(uint8_t *line){
     while(*line){
         if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
@@ -136,7 +173,6 @@ void nam_av_log_set_flags(int arg)
 }
 
 #if 0
-
 const struct { const char *name; int level; } log_levels[] = {
     { "quiet"  , AV_LOG_QUIET   },
     { "panic"  , AV_LOG_PANIC   },
@@ -156,8 +192,80 @@ const struct { const char *name; int level; } log_levels[] = {
 #define AV_LOG_INFO     32
 #define AV_LOG_VERBOSE  40
 #define AV_LOG_DEBUG    48
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////
+// constructor and destructor
+//////////////////////////////////////////////////////////////////////////////////
+static int lockmgr(void **mtx, enum AVLockOp op)
+{
+   switch(op) {
+      case AV_LOCK_CREATE:
+          *mtx = (void *)SDL_CreateMutex();
+          if(!*mtx)
+              return 1;
+          return 0;
+      case AV_LOCK_OBTAIN:
+          return !!SDL_LockMutex((SDL_mutex *)*mtx);
+      case AV_LOCK_RELEASE:
+          return !!SDL_UnlockMutex((SDL_mutex *)*mtx);
+      case AV_LOCK_DESTROY:
+          SDL_DestroyMutex((SDL_mutex *)*mtx);
+          return 0;
+   }
+   return 1;
+}
+
+status_t initFFmpeg() 
+{
+    status_t ret = OK;
 
+    pthread_mutex_lock(&init_mutex);
+
+    if(ref_count == 0) {
+        nam_av_log_set_flags(AV_LOG_SKIP_REPEATED);
+        //av_log_set_level(AV_LOG_DEBUG);
+        av_log_set_callback(nam_av_log_callback);
+
+        /* register all codecs, demux and protocols */
+        avcodec_register_all();
+#if CONFIG_AVDEVICE
+        avdevice_register_all();
 #endif
+        av_register_all();
+        avformat_network_init();
+
+        init_opts();
+
+        if (av_lockmgr_register(lockmgr)) {
+            LOGE("could not initialize lock manager!");
+            ret = NO_INIT;
+        }
+    }
+
+    // update counter
+    ref_count++;
+
+    pthread_mutex_unlock(&init_mutex);
+
+    return ret;
+}
+
+void deInitFFmpeg()
+{
+    pthread_mutex_lock(&init_mutex);
+
+    // update counter
+    ref_count--;
+
+    if(ref_count == 0) {
+        av_lockmgr_register(NULL);
+        uninit_opts();
+        avformat_network_deinit();
+    }
+
+    pthread_mutex_unlock(&init_mutex);
+}
 
 //////////////////////////////////////////////////////////////////////////////////
 // parser
@@ -251,32 +359,5 @@ int is_extradata_compatible_with_android(AVCodecContext *avctx)
     }
 }
 
-//////////////////////////////////////////////////////////////////////////////////
-// dummy
-//////////////////////////////////////////////////////////////////////////////////
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "cmdutils.h"
-
-const char program_name[] = "dummy";
-const int program_birth_year = 2012;
-
-void av_noreturn exit_program(int ret)
-{
-    // do nothing
-}
-
-void show_help_default(const char *opt, const char *arg)
-{
-    // do nothing
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-
 }  // namespace android
 
index 05a4658..f35e980 100644 (file)
@@ -21,6 +21,8 @@
 #include <unistd.h>
 #include <stdlib.h>
 
+#include <utils/Errors.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -32,9 +34,11 @@ extern "C" {
 }
 #endif
 
-
 namespace android {
 
+status_t initFFmpeg();
+void deInitFFmpeg();
+
 void nam_av_log_callback(void* ptr, int level, const char* fmt, va_list vl);
 void nam_av_log_set_flags(int arg);
 
index a2b57c4..8e94180 100644 (file)
@@ -118,7 +118,7 @@ FFmpegExtractor::FFmpegExtractor(const sp<DataSource> &source)
     }
     LOGI("url: %s, mFilename: %s", url, mFilename);
 
-    err = initFFmpeg();
+    err = initStreams();
     if (err < 0) {
         LOGE("failed to init ffmpeg");
         return;
@@ -146,7 +146,7 @@ FFmpegExtractor::~FFmpegExtractor() {
     // stop reader here if no track!
     stopReaderThread();
 
-    deInitFFmpeg();
+    deInitStreams();
 }
 
 size_t FFmpegExtractor::countTracks() {
@@ -916,9 +916,10 @@ void FFmpegExtractor::setFFmpegDefaultOpts()
     mEOF          = false;
 }
 
-int FFmpegExtractor::initFFmpeg()
+int FFmpegExtractor::initStreams()
 {
     int err, i;
+    status_t status;
     int eof = 0;
     int ret = 0, audio_ret = 0, video_ret = 0;
     int pkt_in_play_range = 0;
@@ -933,23 +934,11 @@ int FFmpegExtractor::initFFmpeg()
     wanted_stream[AVMEDIA_TYPE_VIDEO]  = -1;
 
     setFFmpegDefaultOpts();
-    //nam_av_log_set_flags(AV_LOG_SKIP_REPEATED);
-    //av_log_set_level(AV_LOG_DEBUG);
-    av_log_set_callback(nam_av_log_callback);
-
-    /* register all codecs, demux and protocols */
-    avcodec_register_all();
-#if CONFIG_AVDEVICE
-    avdevice_register_all();
-#endif
-    av_register_all();
-    avformat_network_init();
-
-    init_opts();
 
-    if (av_lockmgr_register(lockmgr)) {
-        LOGE("could not initialize lock manager!");
+    status = initFFmpeg();
+    if (status != OK) {
+        ret = -1;
+        goto fail;
     }
 
     av_init_packet(&flush_pkt);
@@ -1058,17 +1047,13 @@ fail:
     return ret;
 }
 
-void FFmpegExtractor::deInitFFmpeg()
+void FFmpegExtractor::deInitStreams()
 {
     if (mFormatCtx) {
         avformat_close_input(&mFormatCtx);
     }
-        
-    av_lockmgr_register(NULL);
-    uninit_opts();
-    avformat_network_deinit();
 
-    av_log(NULL, AV_LOG_QUIET, "%s", "");
+    deInitFFmpeg();
 }
 
 status_t FFmpegExtractor::startReaderThread() {
index 2d82a75..c1e02ea 100644 (file)
@@ -138,8 +138,8 @@ private:
     AVBitStreamFilterContext *mAudioBsfc;
     static int decode_interrupt_cb(void *ctx);
     void print_error_ex(const char *filename, int err);
-    int initFFmpeg();
-    void deInitFFmpeg();
+    int initStreams();
+    void deInitStreams();
     void setFFmpegDefaultOpts();
     int stream_component_open(int stream_index);
     void stream_component_close(int stream_index);
index 95c11bd..04620db 100644 (file)
@@ -180,35 +180,6 @@ static int lockmgr(void **mtx, enum AVLockOp op) {
    return 1;
 }
 
-status_t SoftFFmpegAudio::initFFmpeg() {
-    //nam_av_log_set_flags(AV_LOG_SKIP_REPEATED);
-    //av_log_set_level(AV_LOG_DEBUG);
-    av_log_set_callback(nam_av_log_callback);
-
-    /* register all codecs, demux and protocols */
-    avcodec_register_all();
-#if CONFIG_AVDEVICE
-    avdevice_register_all();
-#endif
-    av_register_all();
-    avformat_network_init();
-
-    init_opts();
-
-    if (av_lockmgr_register(lockmgr)) {
-        LOGE("could not initialize lock manager!");
-        return NO_INIT;
-    }
-
-    return OK;
-}
-
-void SoftFFmpegAudio::deInitFFmpeg() {
-    av_lockmgr_register(NULL);
-    uninit_opts();
-    avformat_network_deinit();
-}
-
 void SoftFFmpegAudio::setAVCtxToDefault(AVCodecContext *avctx, const AVCodec *codec) {
     int fast = 0;
 
index 7e2f1a3..620677a 100644 (file)
@@ -139,8 +139,6 @@ private:
         AWAITING_ENABLED
     } mOutputPortSettingsChange;
 
-    status_t initFFmpeg();
-    void deInitFFmpeg();
     void setAVCtxToDefault(AVCodecContext *avctx, const AVCodec *codec);
 
     void initPorts();
index 69eea3f..1f9bd9e 100644 (file)
@@ -187,36 +187,6 @@ static int lockmgr(void **mtx, enum AVLockOp op) {
    return 1;
 }
 
-status_t SoftFFmpegVideo::initFFmpeg() {
-    //nam_av_log_set_flags(AV_LOG_SKIP_REPEATED);
-    //av_log_set_level(AV_LOG_DEBUG);
-    av_log_set_callback(nam_av_log_callback);
-
-    /* register all codecs, demux and protocols */
-    avcodec_register_all();
-#if CONFIG_AVDEVICE
-    avdevice_register_all();
-#endif
-    av_register_all();
-    avformat_network_init();
-
-    init_opts();
-
-    if (av_lockmgr_register(lockmgr)) {
-        LOGE("could not initialize lock manager!");
-        return NO_INIT;
-    }
-
-    return OK;
-}
-
-void SoftFFmpegVideo::deInitFFmpeg() {
-    av_lockmgr_register(NULL);
-    uninit_opts();
-    avformat_network_deinit();
-}
-
-
 void SoftFFmpegVideo::setAVCtxToDefault(AVCodecContext *avctx, const AVCodec *codec) {
     int fast = 0;
 
index 49a003d..e7f8b0d 100644 (file)
@@ -113,9 +113,6 @@ private:
         AWAITING_ENABLED
     } mOutputPortSettingsChange;
 
-
-    status_t initFFmpeg();
-    void deInitFFmpeg();
     void setAVCtxToDefault(AVCodecContext *avctx, const AVCodec *codec);
 
     void initPorts();