简单记录一下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 } 330 331 env->SetLongField(thiz, fields.surface_texture, (jlong)new_st.get()); 332 333 // This will fail if the media player has not been initialized yet. This 334 // can be the case if setDisplay() on MediaPlayer.java has been called 335 // 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); 1333 1334 status_t err; 1335 if (bufferProducer != NULL) { 1336 err = setNativeWindow_l(new Surface(bufferProducer)); 1337 } else { 1338 err = setNativeWindow_l(NULL); 1339 } 1340 1341 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; 2007 2008 initRenderer_l(); 2009 }
2011 if (mVideoRenderer != NULL) { 2012 mSinceLastDropped++; 2013 mVideoBuffer->meta_data()->setInt64(kKeyTime, looperTimeUs - latenessUs); 2014 2015 mVideoRenderer->render(mVideoBuffer); 2016 if (!mVideoRenderingStarted) { 2017 mVideoRenderingStarted = true; 2018 notifyListener_l(MEDIA_INFO, MEDIA_INFO_RENDERING_START); 2019 } 2020 2021 if (mFlags & PLAYING) { 2022 notifyIfMediaStarted_l(); 2023 } 2024 }.....
1214void AwesomePlayer::initRenderer_l() { 1215 ATRACE_CALL(); 1216 1217 if (mNativeWindow == NULL) { 1218 return; 1219 }
......
1237 mVideoRenderer.clear(); 1238 1239 // Must ensure that mVideoRenderer's destructor is actually executed 1240 // before creating a new one. 1241 IPCThreadState::self()->flushCommands(); 1242 1243 // Even if set scaling mode fails, we will continue anyway 1244 setVideoScalingMode_l(mVideoScalingMode); 1245 if (USE_SURFACE_ALLOC 1246 && !strncmp(component, "OMX.", 4) 1247 && strncmp(component, "OMX.google.", 11)) { 1248 // Hardware decoders avoid the CPU color conversion by decoding 1249 // directly to ANativeBuffers, so we must use a renderer that 1250 // 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 consequence 1255 // allocate their buffers in local address space. This renderer 1256 // then performs a color conversion and copy to get the data 1257 // 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 } 110 111 virtual void render(MediaBuffer *buffer) { 112 int64_t timeUs; 113 CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); 114 115 render((const uint8_t *)buffer->data() + buffer->range_offset(), 116 buffer->range_length(), timeUs, timeUs * 1000); 117 } 118 119 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 } 122 123protected: 124 virtual ~AwesomeLocalRenderer() { 125 delete mTarget; 126 mTarget = NULL; 127 } 128 129private: 130 sp<AMessage> mFormat; 131 SoftwareRenderer *mTarget; 132 133 AwesomeLocalRenderer(const AwesomeLocalRenderer &); 134 AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);; 135}; 136 137struct AwesomeNativeWindowRenderer : public AwesomeRenderer { 138 AwesomeNativeWindowRenderer( 139 const sp<ANativeWindow> &nativeWindow, 140 int32_t rotationDegrees) 141 : mNativeWindow(nativeWindow) { 142 applyRotation(rotationDegrees); 143 } 144 145 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 } 157 158 sp<MetaData> metaData = buffer->meta_data(); 159 metaData->setInt32(kKeyRendered, 1); 160 } 161 162protected: 163 virtual ~AwesomeNativeWindowRenderer() {} 164 165private: 166 sp<ANativeWindow> mNativeWindow; 167 168 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 } 177 178 if (transform) { 179 CHECK_EQ(0, native_window_set_buffers_transform( 180 mNativeWindow.get(), transform)); 181 } 182 } 183 184 AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &); 185 AwesomeNativeWindowRenderer &operator=( 186 const AwesomeNativeWindowRenderer &); 187};
最好数据送往ANativeWindow,接下来进入SurfaceFlinger已经android graphis系统。
这部分架构的简介 https://source.android.com/devices/graphics/architecture.html
来源:CSDN
作者:sujia13
链接:https://blog.csdn.net/sujia13/article/details/51568776