OSDN Git Service

added video renderer from StateFright
authorOhkeun Kwon <pinebud77@hotmail.com>
Sun, 11 Jul 2010 16:21:12 +0000 (01:21 +0900)
committerOhkeun Kwon <pinebud77@hotmail.com>
Sun, 11 Jul 2010 16:21:12 +0000 (01:21 +0900)
Android.mk
MPlayer.cpp
MPlayer.h
MPlayerRenderer.cpp [new file with mode: 0644]
MPlayerRenderer.h [new file with mode: 0644]

index 89262a0..855dffa 100644 (file)
@@ -723,7 +723,7 @@ include $(BUILD_STATIC_LIBRARY)
 include $(CLEAR_VARS)
 LOCAL_MODULE = libandroidmplayer
 LOCAL_CFLAGS = 
-LOCAL_SRC_FILES = MPlayer.cpp MPlayerMetadataRetriever.cpp
+LOCAL_SRC_FILES = MPlayer.cpp MPlayerMetadataRetriever.cpp MPlayerRenderer.cpp
 LOCAL_SHARED_LIBRARIES := libz libasound libc libdl libutils libcutils \
        libmedia libui libandroid_runtime liblog
 LOCAL_STATIC_LIBRARIES := libmplayer $(FFMPEGPARTS) libft2
index 56172d8..54759f4 100644 (file)
@@ -142,6 +142,21 @@ namespace android {
                }
        }
 
+       status_t MPlayer::setVideoSurface(const sp<ISurface> &surface) {
+               LOGE("setVideoSurface");
+
+               Mutex::Autolock l(mMutex);
+               if (mState != STATE_INIT && mState != STATE_OPEN) {
+                       return NO_INIT;
+               }
+               
+               size_t width, height;
+               mplayer_get_video_dimension(&width, &height);
+               mVideoRenderer = new MPlayerRenderer (surface, width, height);
+
+               return NO_ERROR;
+       }
+
 
        status_t MPlayer::prepare()
        {
@@ -319,7 +334,7 @@ namespace android {
                return ((MPlayer*)p)->render();
        }
 
-#define AUDIOBUFFER_SIZE 4096
+#define AUDIOBUFFER_SIZE (4096*6)
 
        int MPlayer::render() {
                int result = -1;
@@ -389,7 +404,7 @@ namespace android {
                        }
 
                        //this function will decode video and sleep for video output timing
-                       mpresult = mplayer_decode_video(&mMPContext, NULL);
+                       mpresult |= mplayer_decode_video(&mMPContext, NULL);
                        if (mpresult)  {
                                LOGI("mplayer_decode_video returned %d", mpresult);
                                break;
@@ -397,11 +412,49 @@ namespace android {
 
                        /* render video */
 
-                       mpresult = mplayer_after_decode (&mMPContext);
+                       mpresult |= mplayer_after_decode (&mMPContext);
                        if (mpresult) {
                                LOGI("mplayer_after_decode %d", mpresult);
                                break;
                        }
+
+                       if (mpresult) {
+                               /* EOF reached -_-? */
+                               if (mLoop || mAndroidLoop) {
+                                       mplayer_seek (&mMPContext, 0);
+                                       /*
+                                       mpresult = mplayer_decode_audio(&mMPContext, mAudioBuffer,
+                                                       AUDIOBUFFER_SIZE, &audio_pos);
+                                                       */
+                               } else {
+                                       int endpos;
+
+                                       mAudioSink->stop();
+                                       audioStarted = false;
+                                       mRender = false;
+                                       mPaused = true;
+                                       mplayer_get_pos (&mMPContext, &endpos);
+
+                                       LOGE("send MEDIA_PLAYBACK_COMPLETE");
+                                       sendEvent(MEDIA_PLAYBACK_COMPLETE);
+
+                                       LOGE("playback complete - wait for signal");
+                                       mCondition.wait(mMutex);
+                                       LOGE("playback complete - signal rx'd");
+                                       if (mExit) break;
+
+                                       if (mState == STATE_OPEN) {
+                                               int curpos;
+                                               mplayer_get_pos(&mMPContext, &curpos);
+                                               if (curpos == endpos) {
+                                                       mplayer_seek (&mMPContext, 0);
+                                               }
+                                               mplayer_decode_audio(&mMPContext, mAudioBuffer,
+                                                               AUDIOBUFFER_SIZE, &audio_pos);
+                                       }
+                               }
+                       }
+
                }
 threadExit:
                mAudioSink.clear();
index b84d1a9..b970c43 100644 (file)
--- a/MPlayer.h
+++ b/MPlayer.h
@@ -19,6 +19,8 @@
 
 namespace android {
 
+       class MPlayerRenderer;
+
        class MPlayer : public MediaPlayerInterface {
                public:
                        MPlayer ();
@@ -28,7 +30,7 @@ namespace android {
                        virtual status_t    initCheck();
                        virtual status_t    setDataSource(const char* path);
                        virtual status_t    setDataSource(int fd, int64_t offset, int64_t length);
-                       virtual status_t    setVideoSurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; }
+                       virtual status_t    setVideoSurface(const sp<ISurface>& surface);
                        virtual status_t    prepare();
                        virtual status_t    prepareAsync();
                        virtual status_t    start();
@@ -69,6 +71,7 @@ namespace android {
                        status_t        mState;
                        pid_t           mRenderTid;
                        int             mfd;
+                       sp<MPlayerRenderer> mVideoRenderer;
        };
 };     // namespace android
 
diff --git a/MPlayerRenderer.cpp b/MPlayerRenderer.cpp
new file mode 100644 (file)
index 0000000..8ddd52e
--- /dev/null
@@ -0,0 +1,55 @@
+/* 
+ * copied from StageFright
+ *
+ * okkwon <pinebud@gmail.com>
+ *
+ */
+
+#define LOG_TAG "MPlayerRenderer"
+#include <utils/Log.h>
+
+#include <binder/MemoryHeapBase.h>
+#include <ui/ISurface.h>
+#include "MPDebug.h"
+#include "MPlayerRenderer.h"
+
+namespace android {
+       MPlayerRenderer::MPlayerRenderer(
+                       const sp<ISurface> &surface,
+                       size_t displayWidth, size_t displayHeight)
+               : mISurface(surface),
+               mDisplayWidth(displayWidth),
+               mDisplayHeight(displayHeight),
+               mFrameSize(displayWidth * displayHeight * 2), //RGB565
+               mIndex(0)
+       {
+               ISurface::BufferHeap bufferHeap (
+                               mDisplayWidth, mDisplayHeight,
+                               mDisplayWidth, mDisplayHeight,
+                               PIXEL_FORMAT_RGB_565,
+                               mMemoryHeap);
+               CHECK(mISurface.get() != NULL);
+               CHECK(mDisplayWidth > 0);
+               CHECK(mDisplayHeight >0);
+               CHECK(mMemoryHeap->heapID() >= 0);
+
+               status_t err = mISurface->registerBuffers(bufferHeap);
+               CHECK_EQ(err, OK);
+       }
+
+       MPlayerRenderer::~MPlayerRenderer() {
+               mISurface->unregisterBuffers();
+       }
+
+       void MPlayerRenderer::renderBuffer() {
+               size_t offset = mIndex * mFrameSize;
+               mISurface->postBuffer(offset);
+               mIndex = 1 - mIndex;
+       }
+
+       bool MPlayerRenderer::getBuffer(char**pbuffer, size_t*size){
+               size_t offset = mIndex * mFrameSize;
+               *pbuffer = (char*)mMemoryHeap->getBase() + offset;
+               return true;
+       }
+}
diff --git a/MPlayerRenderer.h b/MPlayerRenderer.h
new file mode 100644 (file)
index 0000000..8c964f4
--- /dev/null
@@ -0,0 +1,36 @@
+/* copied from Stagefright SoftwareRender
+ *
+ * okkwon <pinebud@gmail.com>
+ *
+ *
+ * */
+
+#ifndef _MPLAYER_RENDERER_H
+#define _MPLAYER_RENDERER_H
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+       class ISurface;
+       class MemoryHeapBase;
+
+       class MPlayerRenderer {
+               public:
+                       MPlayerRenderer(
+                                       const sp<ISurface> &surface,
+                                       size_t displayWidth, size_t displayHeight);
+                       ~MPlayerRenderer();
+                       void renderBuffer();
+                       bool getBuffer(char **pbuffer, size_t *size);
+
+               private:
+                       sp<ISurface> mISurface;
+                       size_t mDisplayWidth, mDisplayHeight;
+                       size_t mFrameSize;
+                       sp<MemoryHeapBase> mMemoryHeap;
+                       int mIndex;
+       };
+}
+
+#endif