OSDN Git Service

auto import from //branches/cupcake/...@126645
authorThe Android Open Source Project <initial-contribution@android.com>
Fri, 16 Jan 2009 00:12:08 +0000 (16:12 -0800)
committerThe Android Open Source Project <initial-contribution@android.com>
Fri, 16 Jan 2009 00:12:08 +0000 (16:12 -0800)
android/android_surface_output.cpp
android/android_surface_output.h
android/author/PVMediaRecorder.cpp
android/author/authordriver.cpp
android/author/authordriver.h
android/mediascanner.cpp
android/playerdriver.cpp
pvauthor/Android.mk

index 368e184..f42701f 100644 (file)
@@ -51,28 +51,32 @@ static const char* pmem = "/dev/pmem";
 // This class implements the reference media IO for file output
 // This class constitutes the Media IO component
 
-OSCL_EXPORT_REF AndroidSurfaceOutput::AndroidSurfaceOutput(
-        PVPlayer* pvPlayer, const sp<ISurface>& surface) :
+OSCL_EXPORT_REF AndroidSurfaceOutput::AndroidSurfaceOutput() :
     OsclTimerObject(OsclActiveObject::EPriorityNominal, "androidsurfaceoutput")
 {
-    LOGV("AndroidAudioSurfaceOutput surface=%p", surface.get());
     initData();
 
     iColorConverter = NULL;
     mInitialized = false;
     mEmulation = false;
     mHardwareCodec = false;
-    mSurface = surface;
-    mPvPlayer = pvPlayer;
+    mPvPlayer = NULL;
 
     // running in emulation?
     char value[PROPERTY_VALUE_MAX];
     if (property_get("ro.kernel.qemu", value, 0)) {
-        LOGV("Running in emulation - fallback to software codecs");
+        LOGV("Emulation mode - using software codecs");
         mEmulation = true;
     }
 }
 
+status_t AndroidSurfaceOutput::set(PVPlayer* pvPlayer, const sp<ISurface>& surface)
+{
+    mPvPlayer = pvPlayer;
+    mSurface = surface;
+    return NO_ERROR;
+}
+
 void AndroidSurfaceOutput::initData()
 {
     iVideoHeight = iVideoWidth = iVideoDisplayHeight = iVideoDisplayWidth = 0;
index f4aeea6..2c2008b 100644 (file)
@@ -149,7 +149,10 @@ class AndroidSurfaceOutput :    public OsclTimerObject
 
 {
 public:
-    OSCL_IMPORT_REF AndroidSurfaceOutput(android::PVPlayer* pvPlayer, const sp<ISurface>& surface);
+    OSCL_IMPORT_REF AndroidSurfaceOutput();
+
+    // parameter initialization
+    virtual status_t set(android::PVPlayer* pvPlayer, const sp<ISurface>& surface);
 
     // For Frame Buffer
     OSCL_IMPORT_REF bool initCheck();
index e6ae4dc..1a5d8e4 100644 (file)
@@ -271,6 +271,19 @@ status_t PVMediaRecorder::start()
 status_t PVMediaRecorder::stop()
 {
     LOGV("stop");
+    status_t ret = doStop();
+    if (OK == ret) {
+        ret = reset();
+        if (OK == ret) {
+            ret = close();
+        }
+    }
+    return ret;
+}
+
+status_t PVMediaRecorder::doStop()
+{
+    LOGV("doStop");
     if (mAuthorDriverWrapper == NULL) {
         LOGE("author driver wrapper is not initialized yet");
         return UNKNOWN_ERROR;
index 57c25f2..e4baaee 100644 (file)
@@ -18,6 +18,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "AuthorDriver"
 
+#include <unistd.h>
 #include <media/thread_init.h>
 #include <ui/ISurface.h>
 #include <ui/ICamera.h>
@@ -31,21 +32,52 @@ AuthorDriverWrapper::AuthorDriverWrapper()
     mAuthorDriver = new AuthorDriver();
 }
 
+void AuthorDriverWrapper::resetAndClose()
+{
+    mAuthorDriver->enqueueCommand(new author_command(AUTHOR_RESET), NULL, NULL);
+    mAuthorDriver->enqueueCommand(new author_command(AUTHOR_CLOSE), NULL, NULL);
+}
+
 AuthorDriverWrapper::~AuthorDriverWrapper()
 {
-    author_command *ac = new author_command(AUTHOR_QUIT);
-    enqueueCommand(ac, NULL, NULL); // will wait on mSyncSem, signaled by author thread
-    delete ac; // have to delete this manually because CommandCompleted won't be called
+    if (mAuthorDriver) {
+        // set the authoring engine to the IDLE state.
+        PVAEState state = mAuthorDriver->getAuthorEngineState();
+        switch (state) {
+        case PVAE_STATE_IDLE:
+            break;
+
+        case PVAE_STATE_RECORDING:
+            mAuthorDriver->enqueueCommand(new author_command(AUTHOR_STOP),  NULL, NULL);
+            resetAndClose();
+            break;
+
+        default:
+            resetAndClose();
+            break;
+        }
+
+        // now it is safe to quit.
+        author_command *ac = new author_command(AUTHOR_QUIT);
+        enqueueCommand(ac, NULL, NULL); // will wait on mSyncSem, signaled by author thread
+        delete ac; // have to delete this manually because CommandCompleted won't be called
+    }
 }
 
 status_t AuthorDriverWrapper::getMaxAmplitude(int *max)
 {
-    return mAuthorDriver->getMaxAmplitude(max);
+    if (mAuthorDriver) {
+        return mAuthorDriver->getMaxAmplitude(max);
+    }
+    return NO_INIT;
 }
 
 status_t AuthorDriverWrapper::enqueueCommand(author_command *ac, media_completion_f comp, void *cookie)
 {
-    return mAuthorDriver->enqueueCommand(ac, comp, cookie);
+    if (mAuthorDriver) {
+        return mAuthorDriver->enqueueCommand(ac, comp, cookie);
+    }
+    return NO_INIT;
 }
 
 AuthorDriver::AuthorDriver()
@@ -58,6 +90,8 @@ AuthorDriver::AuthorDriver()
                mComposerConfig(NULL),
                mVideoEncoderConfig(NULL),
                mAudioEncoderConfig(NULL),
+               mOutputFileName(NULL),
+               mKeepOutputFile(false),
                mVideoWidth(DEFAULT_FRAME_WIDTH),
                mVideoHeight(DEFAULT_FRAME_HEIGHT),
                mVideoFrameRate((int)DEFAULT_FRAME_RATE),
@@ -452,10 +486,11 @@ void AuthorDriver::handleSetOutputFile(set_output_file_command *ac)
     ret = config->SetOutputFileName(wFileName);
 
 exit:
-    free(ac->path);
     if (ret == PVMFSuccess) {
+        mOutputFileName = ac->path;
         FinishNonAsyncCommand(ac);
     } else {
+        free(ac->path);
         commandFailed(ac);
     }
 }
@@ -477,10 +512,10 @@ void AuthorDriver::handleStart(author_command *ac)
 void AuthorDriver::handleStop(author_command *ac)
 {
     int error = 0;
-    OSCL_TRY(error, mAuthor->Stop());
+    OSCL_TRY(error, mAuthor->Stop(ac));
     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
-    handleReset(ac);
-    handleClose(ac);
+
+    mKeepOutputFile = true;
 }
 
 void AuthorDriver::handleClose(author_command *ac)
@@ -502,6 +537,15 @@ void AuthorDriver::handleReset(author_command *ac)
 
 void AuthorDriver::removeDataSources(author_command *ac)
 {
+    if (mOutputFileName) {
+        if (!mKeepOutputFile) {
+            LOGV("remove output filei(%s)", mOutputFileName);
+            unlink(mOutputFileName);
+        }
+        free(mOutputFileName);
+        mOutputFileName = NULL;
+    }
+
     if (mComposerConfig) {
         mComposerConfig->removeRef();
         mComposerConfig = NULL;
@@ -751,6 +795,12 @@ status_t AuthorDriver::getMaxAmplitude(int *max)
     return android::OK;
 }
 
-
+PVAEState AuthorDriver::getAuthorEngineState()
+{
+    if (mAuthor) {
+        return mAuthor->GetPVAuthorState();
+    }
+    return PVAE_STATE_IDLE;
+}
 
 
index 9380c52..db0826e 100644 (file)
@@ -203,6 +203,7 @@ public:
     void HandleInformationalEvent(const PVAsyncInformationalEvent& aEvent);
 
     status_t getMaxAmplitude(int *max);
+    PVAEState getAuthorEngineState();
 
 private:
     // Finish up a non-async command in such a way that
@@ -237,6 +238,9 @@ private:
     PVInterface                *mVideoEncoderConfig;
     PVInterface                *mAudioEncoderConfig;
 
+    char                    *mOutputFileName;
+    bool                    mKeepOutputFile;
+
     int                     mVideoWidth;
     int                     mVideoHeight;
     int                     mVideoFrameRate;
@@ -267,6 +271,8 @@ public:
     status_t getMaxAmplitude(int *max);
 
 private:
+    void resetAndClose();
+
     AuthorDriver    *mAuthorDriver;
 };
 
index 8c02940..6388c4a 100644 (file)
@@ -14,6 +14,7 @@
 #include "oscl_assert.h"
 #include "oscl_lock_base.h"
 #include "oscl_snprintf.h"
+#include "oscl_string_utf8.h"
 #include "pvmf_return_codes.h"
 #include "pv_mime_string_utils.h"
 #include "pv_id3_parcom_constants.h"
@@ -101,23 +102,34 @@ static PVMFStatus parseMP3(const char *filename, MediaScannerClient& client)
     for (uint32 i = 0; i < num_frames;i++)
     {
         const char* key = framevector[i]->key;
+        bool validUtf8 = true;
 
         // type should follow first semicolon
         const char* type = strchr(key, ';') + 1;
         if (type == 0) continue;
+        
+        const char* value = framevector[i]->value.pChar_value;
 
-        // KVP_VALTYPE_UTF8_CHAR check must be first, since KVP_VALTYPE_ISO88591_CHAR is a substring of KVP_VALTYPE_UTF8_CHAR
-        // similarly, KVP_VALTYPE_UTF16BE_WCHAR must be checked before KVP_VALTYPE_UTF16_WCHAR
+        // KVP_VALTYPE_UTF8_CHAR check must be first, since KVP_VALTYPE_ISO88591_CHAR 
+        // is a substring of KVP_VALTYPE_UTF8_CHAR.
+        // Similarly, KVP_VALTYPE_UTF16BE_WCHAR must be checked before KVP_VALTYPE_UTF16_WCHAR
         if (oscl_strncmp(type, KVP_VALTYPE_UTF8_CHAR, KVP_VALTYPE_UTF8_CHAR_LEN) == 0) {
-            // utf8
-            // pass through directly
-            if (!client.handleStringTag(key, framevector[i]->value.pChar_value)) goto failure;
-        } else if (oscl_strncmp(type, KVP_VALTYPE_ISO88591_CHAR, KVP_VALTYPE_ISO88591_CHAR_LEN) == 0) {
+            // utf8 can be passed through directly
+            // but first validate to make sure it is legal utf8
+            uint32 valid_chars;
+            validUtf8 = oscl_str_is_valid_utf8((const uint8 *)value, valid_chars);
+            if (validUtf8 && !client.handleStringTag(key, value)) goto failure;
+        } 
+
+        // if the value is not valid utf8, then we will treat it as iso-8859-1 
+        // and our native encoding detection will try to figure out what it is
+        if (oscl_strncmp(type, KVP_VALTYPE_ISO88591_CHAR, KVP_VALTYPE_ISO88591_CHAR_LEN) == 0 
+                || !validUtf8) {
             // iso-8859-1
             // convert to utf8
             // worse case is 2x inflation
-            const unsigned char* src = (const unsigned char *)framevector[i]->value.pChar_value;
-            char* temp = (char *)alloca(strlen(framevector[i]->value.pChar_value) * 2 + 1);
+            const unsigned char* src = (const unsigned char *)value;
+            char* temp = (char *)alloca(strlen(value) * 2 + 1);
             if (temp) {
                 char* dest = temp;
                 unsigned int uch;
index 72320ef..31f1a1e 100644 (file)
@@ -75,6 +75,11 @@ using namespace android;
 #  define PAGESIZE              4096
 # endif
 
+// library and function name to retrieve device-specific MIOs
+static const char* MIO_LIBRARY_NAME = "libopencorehal";
+static const char* VIDEO_MIO_FACTORY_NAME = "createVideoMio";
+typedef AndroidSurfaceOutput* (*VideoMioFactory)();
+
 class PlayerDriver :
     public OsclActiveObject,
     public PVCommandStatusObserver,
@@ -177,6 +182,8 @@ private:
     int                     mRecentSeek;
     bool                    mSeekComp;
     bool                    mSeekPending;
+
+    void*                   mLibHandle;
 };
 
 PlayerDriver::PlayerDriver(PVPlayer* pvPlayer) :
@@ -206,6 +213,9 @@ PlayerDriver::PlayerDriver(PVPlayer* pvPlayer) :
     mPlayerCapConfig = NULL;
     mDownloadContextData = NULL;
 
+    // attempt to open device-specific library
+    mLibHandle = ::dlopen(MIO_LIBRARY_NAME, RTLD_NOW);
+
     // start player thread
     LOGV("start player thread");
     createThreadEtc(PlayerDriver::startPlayerThread, this, "PV player");
@@ -217,6 +227,9 @@ PlayerDriver::PlayerDriver(PVPlayer* pvPlayer) :
 PlayerDriver::~PlayerDriver()
 {
     LOGV("destructor");
+    if (mLibHandle != NULL) {
+        ::dlclose(mLibHandle);
+    }
 }
 
 PlayerCommand* PlayerDriver::dequeueCommand()
@@ -582,8 +595,32 @@ void PlayerDriver::handleInit(PlayerInit* ec)
 void PlayerDriver::handleSetVideoSurface(PlayerSetVideoSurface* ec)
 {
     int error = 0;
+    AndroidSurfaceOutput* mio = NULL;
+
+    // attempt to load device-specific video MIO
+    if (mLibHandle != NULL) {
+        VideoMioFactory f = (VideoMioFactory) ::dlsym(mLibHandle, VIDEO_MIO_FACTORY_NAME);
+        if (f != NULL) {
+            mio = f();
+        }
+    }
+
+    // if no device-specific MIO was created, use the generic one
+    if (mio == NULL) {
+        LOGW("Using generic video MIO");
+        mio = new AndroidSurfaceOutput();
+    }
+
+    // initialize the MIO parameters
+    status_t ret = mio->set(mPvPlayer, ec->surface());
+    if (ret != NO_ERROR) {
+        LOGE("Video MIO set failed");
+        commandFailed(ec);
+        delete mio;
+        return;
+    }
+    mVideoOutputMIO = mio;
 
-    mVideoOutputMIO = new AndroidSurfaceOutput(mPvPlayer, ec->surface());
     mVideoNode = PVMediaOutputNodeFactory::CreateMediaOutputNode(mVideoOutputMIO);
     mVideoSink = new PVPlayerDataSinkPVMFNode;
 
index cdf38a3..fc598c8 100644 (file)
@@ -18,7 +18,7 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \
 
 LOCAL_LDLIBS := -lpthread
 
-LOCAL_SHARED_LIBRARIES := libopencoreplayer libutils libcutils libui libhardware libandroid_runtime libdrm1 libmedia libsgl libopencorecommon 
+LOCAL_SHARED_LIBRARIES := libopencoreplayer libutils libcutils libui libhardware_legacy libandroid_runtime libdrm1 libmedia libsgl libopencorecommon 
 
 ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
 LOCAL_LDLIBS += -ldl