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
}
}
+ 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()
{
return ((MPlayer*)p)->render();
}
-#define AUDIOBUFFER_SIZE 4096
+#define AUDIOBUFFER_SIZE (4096*6)
int MPlayer::render() {
int result = -1;
}
//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;
/* 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();
namespace android {
+ class MPlayerRenderer;
+
class MPlayer : public MediaPlayerInterface {
public:
MPlayer ();
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();
status_t mState;
pid_t mRenderTid;
int mfd;
+ sp<MPlayerRenderer> mVideoRenderer;
};
}; // namespace android
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/* 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