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
原创粉丝点击