Android MediaPlayer stream实现
2013-06-28 09:45
513 查看
对于Ait类的Camera,使用已编码数据(H264)进行Preview.若使用原始的SurfaceTexture实现,需要扩展ANativeWindow支持的视频格式,也会涉及到OpenGL相关的内容,工作量巨大。
另一种方式是使用MediaPlayer实现,MediaPlayer支持三种源,我们应该要使用Stream方式,但也不确定,看一下service的底层实现,也就是与Hardcodec的对接。另外关注一下Buffer的传递过程。
Java Framework
frameworks/base/media/java/android/media/MediaPlayer.java
JNI
frameworks/base/media/jni/android_media_MediaPlayer.cpp
cpp Framework(libmedia.so):client
frameworks/av/media/libmedia
include
frameworks/av/include/media
Service
frameworks/av/media/libmediaplayerservice
1、APP@packages/apps/Launchertv/src/com/xxxx/Launcher/VideoMediaPlayer.java
对于一个简单的APP,例如Jervis的Launcher 播放窗口,app需要做的较为简单
2、实现
源码中有一个stream的参考,framework/av/cmds/stagefright/stream.cpp,但不可用,看了以下代码,没有mMediaPlayer.prepare的调用,且原代码中并非对框架中MediaPlayer的调用,而是自己申请service。
因此新建类MyClient
在构造函数中new 一个MediaPlayer类,并设置Listener,此Listener是Service想MediaPlayer的通知。
另外新建streamSource类,在本例中,是通过打开一个Ts文件,读取数据并通知service进行播放,他继承了BnStreamSource类,并实现了三个重要的虚函数
setListener:设置mListener,通过此listener可调用service的一些函数实现。例如下面的两个函数
setBuffers:将server中申请的IMemory容器传递给StreamSource类,用于向其中写入ts数据。
onBufferAvailable(size_t index):向可用的内存块中写入数据,完成后通过IStreamListener通知server
3、CameraHD应用中的考虑
在Camera Service中将MyClient中的实现移植到startPreview中,获取到H264数据后,打包成TS流,通过MyStreamSource将数据写入MediaPlayerService的buffer中。
http://pan.baidu.com/share/link?shareid=3224742726&uk=2852507874
这是将H264数据打包为TS流的工程,备份
另一种方式是使用MediaPlayer实现,MediaPlayer支持三种源,我们应该要使用Stream方式,但也不确定,看一下service的底层实现,也就是与Hardcodec的对接。另外关注一下Buffer的传递过程。
Java Framework
frameworks/base/media/java/android/media/MediaPlayer.java
JNI
frameworks/base/media/jni/android_media_MediaPlayer.cpp
cpp Framework(libmedia.so):client
frameworks/av/media/libmedia
include
frameworks/av/include/media
Service
frameworks/av/media/libmediaplayerservice
1、APP@packages/apps/Launchertv/src/com/xxxx/Launcher/VideoMediaPlayer.java
对于一个简单的APP,例如Jervis的Launcher 播放窗口,app需要做的较为简单
mMediaPlayer = new MediaPlayer(); mMediaPlayer.reset(); mMediaPlayer.setDataSource(VIDEO_PATH + mFileName.get(mCurrentItem));// 针对与本地视频文件播放 mMediaPlayer.prepare(); mMediaPlayer.start();
2、实现
源码中有一个stream的参考,framework/av/cmds/stagefright/stream.cpp,但不可用,看了以下代码,没有mMediaPlayer.prepare的调用,且原代码中并非对框架中MediaPlayer的调用,而是自己申请service。
因此新建类MyClient
struct MyClient : RefBase { MyClient() : mEOS(false) { mp = new MediaPlayer(); mp->setListener(new MyListener(this)); } class MyListener: public MediaPlayerListener { public: MyListener(sp<MyClient> mc) { mc4listener = mc; } ~MyListener() { } virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) { Mutex::Autolock autoLock(mc4listener->mLock); fprintf(stderr, "leon msg=%d\n", msg); if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) { mc4listener->mEOS = true; mc4listener->mCondition.signal(); } } sp<MyClient> mc4listener; }; void waitForEOS() { Mutex::Autolock autoLock(mLock); while (!mEOS) { mCondition.wait(mLock); } } sp<MediaPlayer> mp; protected: virtual ~MyClient() { } private: Mutex mLock; Condition mCondition; bool mEOS; DISALLOW_EVIL_CONSTRUCTORS(MyClient); };
在构造函数中new 一个MediaPlayer类,并设置Listener,此Listener是Service想MediaPlayer的通知。
另外新建streamSource类,在本例中,是通过打开一个Ts文件,读取数据并通知service进行播放,他继承了BnStreamSource类,并实现了三个重要的虚函数
struct MyStreamSource : public BnStreamSource { // Object assumes ownership of fd. MyStreamSource(int fd); virtual void setListener(const sp<IStreamListener> &listener); virtual void setBuffers(const Vector<sp<IMemory> > &buffers); virtual void onBufferAvailable(size_t index); protected: virtual ~MyStreamSource(); private: int mFd; off64_t mFileSize; uint64_t mNumPacketsSent; sp<IStreamListener> mListener; Vector<sp<IMemory> > mBuffers; DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource); };
setListener:设置mListener,通过此listener可调用service的一些函数实现。例如下面的两个函数
void MyStreamSource::setListener(const sp<IStreamListener> &listener) { mListener = listener; }
setBuffers:将server中申请的IMemory容器传递给StreamSource类,用于向其中写入ts数据。
void MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) { mBuffers = buffers; }
onBufferAvailable(size_t index):向可用的内存块中写入数据,完成后通过IStreamListener通知server
void MyStreamSource::onBufferAvailable(size_t index) { //CHECK_LT(index, mBuffers.size()); if (index<0 || index >=8 ) { fprintf(stderr, "size=%d,\tindex=%u\n", mBuffers.size(), index); return; } sp<IMemory> mem = mBuffers.itemAt(index); ssize_t n = read(mFd, mem->pointer(), mem->size()); if (n <= 0) { mListener->issueCommand(IStreamListener::EOS, false /* synchronous */); } else { mListener->queueBuffer(index, n); mNumPacketsSent += n / 188; } }
3、CameraHD应用中的考虑
在Camera Service中将MyClient中的实现移植到startPreview中,获取到H264数据后,打包成TS流,通过MyStreamSource将数据写入MediaPlayerService的buffer中。
http://pan.baidu.com/share/link?shareid=3224742726&uk=2852507874
这是将H264数据打包为TS流的工程,备份
相关文章推荐
- android视频播放简单实现示例(VideoView&MediaPlayer)
- Android - SurfaceView + MediaPlayer实现分段视频无缝播放
- 【Android】MediaRecorder/MediaPlayer实现录音与播放录音
- Android SurfaceView + MediaPlayer实现视频播放器
- android使用MediaPlayer+Surface实现简单视频播放器
- Android SurfaceView + MediaPlayer实现分段视频无缝播放
- Android中使用SurfaceView+MediaPlayer+自定义的MediaController实现自定义的视屏播放器
- android MediaPlayer 简易播放器的实现 及类似斗地主音频池实现
- Android - SurfaceView + MediaPlayer实现分段视频无缝播放
- android开发SurfaceView+MediaPlayer实现视频播放
- Android视频播放框架Vitamio集成及使用MediaPlayer+SurfaceView、VideoView+MediaController实现播放网络视频
- Android MediaPlayer+SurfaceView实现视频播放
- Android 通过VideoView+MediaPlayer实现视频播放
- Android MediaPlayer+SurfaceView实现视频播放
- Android SurfaceView+MediaPlayer实现视频播放
- Android MediaPlayer实现音乐播放
- Android MediaPlayer Error/Info Code
- Android MediaPlayer之视频预加载
- vlc-android 获取MediaPlayerEncounteredError,MediaPlayerBuffering等各种事件的响应
- Android多媒体开发【1】-- 利用SurfaceView + MediaPlayer开发最简单的视频播放器