android MediaPlayer surface分析

简单记录一下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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值