android MediaPlayer surface分析
来源:互联网 发布:淘宝直通车在哪里找图 编辑:程序博客网 时间:2024/04/30 05:58
简单记录一下mediaplayer Surface和Render的过程
void setSurface(Surface surface) ------MediaPlayer.java
void android_media_MediaPlayer_setVideoSurface ---- android_media_MediaPlayer.cpp
313 sp<IGraphicBufferProducer> new_st;314 if (jsurface) {315 sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));316 if (surface != NULL) {317 new_st = surface->getIGraphicBufferProducer();318 if (new_st == NULL) {319 jniThrowException(env, "java/lang/IllegalArgumentException",320 "The surface does not have a binding SurfaceTexture!");321 return;322 }323 new_st->incStrong((void*)decVideoSurfaceRef);324 } else {325 jniThrowException(env, "java/lang/IllegalArgumentException",326 "The surface has been released");327 return;328 }329 }330331 env->SetLongField(thiz, fields.surface_texture, (jlong)new_st.get());332333 // This will fail if the media player has not been initialized yet. This334 // can be the case if setDisplay() on MediaPlayer.java has been called335 // before setDataSource(). The redundant call to setVideoSurfaceTexture()336 // in prepare/prepareAsync covers for this case.337 mp->setVideoSurfaceTexture(new_st);setVideoSurfaceText MediaPlayer.cpp-->MediaPlayerService.cpp--->StageFrightPlayer.cpp
setSurfaceTexture AwesomePlayer.cpp
1331status_t AwesomePlayer::setSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer) {1332 Mutex::Autolock autoLock(mLock);13331334 status_t err;1335 if (bufferProducer != NULL) {1336 err = setNativeWindow_l(new Surface(bufferProducer));1337 } else {1338 err = setNativeWindow_l(NULL);1339 }13401341 return err;1342}1364status_t AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {1365 mNativeWindow = native;到这里,把java层Surface赋给mNativeWindow。
接下来简单看一下mNativeWindow和Render的关系
mNativeWindow非空,则初始化Render
1767void AwesomePlayer::onVideoEvent() {.....2004 if ((mNativeWindow != NULL)2005 && (mVideoRendererIsPreview || mVideoRenderer == NULL)) {2006 mVideoRendererIsPreview = false;20072008 initRenderer_l();2009 }2011 if (mVideoRenderer != NULL) {2012 mSinceLastDropped++;2013 mVideoBuffer->meta_data()->setInt64(kKeyTime, looperTimeUs - latenessUs);20142015 mVideoRenderer->render(mVideoBuffer);2016 if (!mVideoRenderingStarted) {2017 mVideoRenderingStarted = true;2018 notifyListener_l(MEDIA_INFO, MEDIA_INFO_RENDERING_START);2019 }20202021 if (mFlags & PLAYING) {2022 notifyIfMediaStarted_l();2023 }2024 }.....1214void AwesomePlayer::initRenderer_l() {1215 ATRACE_CALL();12161217 if (mNativeWindow == NULL) {1218 return;1219 }......1237 mVideoRenderer.clear();12381239 // Must ensure that mVideoRenderer's destructor is actually executed1240 // before creating a new one.1241 IPCThreadState::self()->flushCommands();12421243 // Even if set scaling mode fails, we will continue anyway1244 setVideoScalingMode_l(mVideoScalingMode);1245 if (USE_SURFACE_ALLOC1246 && !strncmp(component, "OMX.", 4)1247 && strncmp(component, "OMX.google.", 11)) {1248 // Hardware decoders avoid the CPU color conversion by decoding1249 // directly to ANativeBuffers, so we must use a renderer that1250 // just pushes those buffers to the ANativeWindow.1251 mVideoRenderer =1252 new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);1253 } else {1254 // Other decoders are instantiated locally and as a consequence1255 // allocate their buffers in local address space. This renderer1256 // then performs a color conversion and copy to get the data1257 // into the ANativeBuffer.1258 sp<AMessage> format;1259 convertMetaDataToMessage(meta, &format);1260 mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, format);1261 }104struct AwesomeLocalRenderer : public AwesomeRenderer {105 AwesomeLocalRenderer(106 const sp<ANativeWindow> &nativeWindow, const sp<AMessage> &format)107 : mFormat(format),108 mTarget(new SoftwareRenderer(nativeWindow)) {109 }110111 virtual void render(MediaBuffer *buffer) {112 int64_t timeUs;113 CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));114115 render((const uint8_t *)buffer->data() + buffer->range_offset(),116 buffer->range_length(), timeUs, timeUs * 1000);117 }118119 void render(const void *data, size_t size, int64_t mediaTimeUs, nsecs_t renderTimeNs) {120 (void)mTarget->render(data, size, mediaTimeUs, renderTimeNs, NULL, mFormat);121 }122123protected:124 virtual ~AwesomeLocalRenderer() {125 delete mTarget;126 mTarget = NULL;127 }128129private:130 sp<AMessage> mFormat;131 SoftwareRenderer *mTarget;132133 AwesomeLocalRenderer(const AwesomeLocalRenderer &);134 AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;135};136137struct AwesomeNativeWindowRenderer : public AwesomeRenderer {138 AwesomeNativeWindowRenderer(139 const sp<ANativeWindow> &nativeWindow,140 int32_t rotationDegrees)141 : mNativeWindow(nativeWindow) {142 applyRotation(rotationDegrees);143 }144145 virtual void render(MediaBuffer *buffer) {146 ATRACE_CALL();147 int64_t timeUs;148 CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));149 native_window_set_buffers_timestamp(mNativeWindow.get(), timeUs * 1000);150 status_t err = mNativeWindow->queueBuffer(151 mNativeWindow.get(), buffer->graphicBuffer().get(), -1);152 if (err != 0) {153 ALOGE("queueBuffer failed with error %s (%d)", strerror(-err),154 -err);155 return;156 }157158 sp<MetaData> metaData = buffer->meta_data();159 metaData->setInt32(kKeyRendered, 1);160 }161162protected:163 virtual ~AwesomeNativeWindowRenderer() {}164165private:166 sp<ANativeWindow> mNativeWindow;167168 void applyRotation(int32_t rotationDegrees) {169 uint32_t transform;170 switch (rotationDegrees) {171 case 0: transform = 0; break;172 case 90: transform = HAL_TRANSFORM_ROT_90; break;173 case 180: transform = HAL_TRANSFORM_ROT_180; break;174 case 270: transform = HAL_TRANSFORM_ROT_270; break;175 default: transform = 0; break;176 }177178 if (transform) {179 CHECK_EQ(0, native_window_set_buffers_transform(180 mNativeWindow.get(), transform));181 }182 }183184 AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &);185 AwesomeNativeWindowRenderer &operator=(186 const AwesomeNativeWindowRenderer &);187};最好数据送往ANativeWindow,接下来进入SurfaceFlinger已经android graphis系统。
这部分架构的简介 https://source.android.com/devices/graphics/architecture.html
0 0
- android MediaPlayer surface分析
- android mediaplayer 分析
- android MediaPlayer深入分析
- android MediaPlayer深入分析
- Android MediaPlayer分析
- Android MediaPlayer框架分析
- android使用MediaPlayer+Surface实现简单视频播放器
- Surface+MediaPlayer显示视频
- Android MediaPlayer 分析- MediaPlayerService.cpp
- Android MediaPlayer 分析 - client库
- Android Display System Surface Flinger详细分析
- Android应用程序创建Surface过程源码分析
- android的Surface Flinger服务启动分析
- Surface 分析
- Surface分析
- Android MediaPlayer 分析 - service端文件结构
- Android(2.3+)源码分析MediaPlayer之RTSP
- Android JB MediaPlayer MediaPlayerService Binder 构建 分析
- HashMap死循环
- DevExpress GridControl 控件中GridView 加组,加行
- OS X Core Controls Tutorial: Part 2/2学习笔记
- 知道创宇的一个rtcp分析,加上外面找到的一个tcp udp端口转发的
- 为什么现在多数软件都默认选择安装目录为user下的AppData而非Progamfiles?
- android MediaPlayer surface分析
- 北航面试之英语部分
- LLDB调试命令(三)thread return 命令 帮你排除项目中的疑难杂症
- javaScript事件捕获和冒泡
- java常用几种枚举类型
- Kernel启动流程源码解析 1 head.S
- dsquery心得
- 如何在interlliJ IDEA上配置tomcat
- Linux常用命令:nl命令