Android Media Server - MediaPlayer - setDisplay

 

 

 

 

 

1.    MediaPlayer::setDisplay()

Frameworks/base/media/java/android/media/MediaPlayer.java

   public void setDisplay(SurfaceHolder sh) {

        mSurfaceHolder = sh;

        Surface surface;

        if (sh != null) {

            surface = sh.getSurface();

        } else {

            surface = null;

        }

        _setVideoSurface(surface);

        updateSurfaceScreenOn();

    }

2.  android_media_MediaPlayer_setVideoSurface ()

Frameworks/base/media/jni/Android_media_MediaPlayer.cpp

 

static void

android_media_MediaPlayer_setVideoSurface(JNIEnv *env,jobject thiz, jobject jsurface)

{

   setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);

}

 

3.    MediaPlayer:: setVideoSurface()

Frameworks/base/media/jni/Android_media_MediaPlayer.cpp

 

static void

setVideoSurface(JNIEnv *env, jobject thiz, jobjectjsurface, jboolean mediaPlayerMustBeAlive)

{

// 得到本地MediaPlayer对象

 

   sp<MediaPlayer> mp = getMediaPlayer(env, thiz);

 

    if (mp == NULL) {

        if (mediaPlayerMustBeAlive) {

            jniThrowException(env,"java/lang/IllegalStateException", NULL);

        }

        return;

    }

 

    decVideoSurfaceRef(env, thiz);

 

    sp<IGraphicBufferProducer> new_st;

    if (jsurface) {

 

// java env中得到surface对象

 

        sp<Surface>surface(android_view_Surface_getSurface(env, jsurface));

        if (surface != NULL) {

 

// 得到surface对象的BufferProducer

 

            new_st =surface->getIGraphicBufferProducer();

            if (new_st == NULL) {

                jniThrowException(env,"java/lang/IllegalArgumentException",

                    "The surface does nothave a binding SurfaceTexture!");

                return;

            }

            new_st->incStrong((void*)decVideoSurfaceRef);

        } else {

            jniThrowException(env,"java/lang/IllegalArgumentException",

                    "The surface has beenreleased");

            return;

        }

    }

// BufferProducer对象保存在java env

    env->SetIntField(thiz,fields.surface_texture, (int)new_st.get());

    // This will fail if the media player hasnot been initialized yet. This

    // can be the case if setDisplay() onMediaPlayer.java has been called

    // before setDataSource(). The redundantcall to setVideoSurfaceTexture()

    // in prepare/prepareAsync covers for thiscase.

 

   mp->setVideoSurfaceTexture(new_st);

}

 

status_t MediaPlayer::setVideoSurfaceTexture(

       constsp<IGraphicBufferProducer>& bufferProducer)

{

    ALOGV("setVideoSurfaceTexture");

    Mutex::Autolock _l(mLock);

    if (mPlayer == 0) return NO_INIT;

 

// mPlayer是一个BpMediaPlayer(BpBinder)对象

 

    returnmPlayer->setVideoSurfaceTexture(bufferProducer);

}

 

4.    BpMediaPlayer:: setVideoSurfaceTexture()

Frameworks/av/media/libmedia/IMediaServer.cpp

class BpMediaPlayer: public BpInterface<IMediaPlayer>

{

 

    // pass the buffered IGraphicBufferProducerto the media player service

    status_t setVideoSurfaceTexture(constsp<IGraphicBufferProducer>& bufferProducer)

    {

        Parcel data, reply;

       data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());

        sp<IBinder>b(bufferProducer->asBinder());

        data.writeStrongBinder(b);

 

// remote() 返回 BpMediaServer(BpBinder)中的BpBinder

 

        remote()->transact(SET_VIDEO_SURFACETEXTURE,data, &reply);

 

        return reply.readInt32();

}

 

}

 

5.    BnMediaPlayer::onTransact ()

Frameworks/av/media/libmedia/IMediaServer.cpp

通过Biner机制调用BnMediaPlayer::onTransact()

 

status_tBnMediaPlayer::onTransact(

    uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)

{

    switch (code) {

        case DISCONNECT: {

            CHECK_INTERFACE(IMediaPlayer, data,reply);

            disconnect();

            return NO_ERROR;

        } break;

        case SET_DATA_SOURCE_URL: {

            CHECK_INTERFACE(IMediaPlayer, data,reply);

            const char* url =data.readCString();

            KeyedVector<String8, String8>headers;

            int32_t numHeaders =data.readInt32();

            for (int i = 0; i < numHeaders;++i) {

                String8 key =data.readString8();

                String8 value =data.readString8();

                headers.add(key, value);

            }

           reply->writeInt32(setDataSource(url, numHeaders > 0 ? &headers: NULL));

            return NO_ERROR;

        } break;

        case SET_DATA_SOURCE_FD: {

            CHECK_INTERFACE(IMediaPlayer, data,reply);

            int fd = data.readFileDescriptor();

            int64_t offset = data.readInt64();

            int64_t length = data.readInt64();

           reply->writeInt32(setDataSource(fd, offset, length));

            return NO_ERROR;

        }

        case SET_DATA_SOURCE_STREAM: {

            CHECK_INTERFACE(IMediaPlayer, data,reply);

            sp<IStreamSource> source =

               interface_cast<IStreamSource>(data.readStrongBinder());

           reply->writeInt32(setDataSource(source));

            return NO_ERROR;

        }

        caseSET_VIDEO_SURFACETEXTURE: {

           CHECK_INTERFACE(IMediaPlayer, data, reply);

           sp<IGraphicBufferProducer> bufferProducer =

                   interface_cast<IGraphicBufferProducer>(data.readStrongBinder());

           reply->writeInt32(setVideoSurfaceTexture(bufferProducer));

            returnNO_ERROR;

        } break;

        case SET_NEXT_PLAYER: {

            CHECK_INTERFACE(IMediaPlayer, data,reply);

           reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));

 

            return NO_ERROR;

        }break;

        default:

            return BBinder::onTransact(code,data, reply, flags);

    }

}

 

 

 

6.    BnMediaPlayer::onTransact ()

Frameworks/av/media/libmediaplayerservice/MediaPlayerService.h

Frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

 

classMediaPlayerService : public BnMediaPlayerService

{

class Client;

    class Client : public BnMediaPlayer {

        // IMediaPlayer interface

        virtual void            disconnect();

        virtualstatus_t        setVideoSurfaceTexture(

                            constsp<IGraphicBufferProducer>& bufferProducer);

        virtual status_t        prepareAsync();

…………………………………………………………………………………………….

}

 

7.    MediaPlayerService::Client::setVideoSurfaceTexture()

Frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

status_tMediaPlayerService::Client::setVideoSurfaceTexture(

        constsp<IGraphicBufferProducer>& bufferProducer)

{

    ALOGV("[%d]setVideoSurfaceTexture(%p)", mConnId, bufferProducer.get());

    sp<MediaPlayerBase> p = getPlayer();

    if (p == 0) return UNKNOWN_ERROR;

 

    sp<IBinder> binder(bufferProducer ==NULL ? NULL :

            bufferProducer->asBinder());

    if (mConnectedWindowBinder == binder) {

        return OK;

    }

 

    sp<ANativeWindow> anw;

    if (bufferProducer != NULL) {

        anw = new Surface(bufferProducer);

        status_t err =native_window_api_connect(anw.get(),

               NATIVE_WINDOW_API_MEDIA);

 

        if (err != OK) {

            ALOGE("setVideoSurfaceTexturefailed: %d", err);

            // Note that we must do the resetbefore disconnecting from the ANW.

            // Otherwise queue/dequeue callscould be made on the disconnected

            // ANW, which may result in errors.

            reset();

 

            disconnectNativeWindow();

 

            return err;

        }

    }

 

    // Note that we must set the player's newGraphicBufferProducer before

    // disconnecting the old one.  Otherwise queue/dequeue calls could be made

    // on the disconnected ANW, which mayresult in errors.

    status_t err =p->setVideoSurfaceTexture(bufferProducer);

 

    disconnectNativeWindow();

 

    mConnectedWindow = anw;

 

    if (err == OK) {

        mConnectedWindowBinder = binder;

    } else {

        disconnectNativeWindow();

    }

 

    return err;

}

 

8.    native_window_api_connect ()

system/core/include/system/window.h

staticinline int native_window_api_connect(

        struct ANativeWindow* window, int api)

{

    return window->perform(window,NATIVE_WINDOW_API_CONNECT, api);

}

 

 

9.    Surface::perform

Frameworks/native/libs/gui/Surface.cpp

int Surface::perform(int operation, va_listargs)

{

   int res = NO_ERROR;

   switch (operation) {

   case NATIVE_WINDOW_CONNECT:

       // deprecated. must return NO_ERROR.

       break;

   case NATIVE_WINDOW_DISCONNECT:

       // deprecated. must return NO_ERROR.

       break;

   case NATIVE_WINDOW_SET_USAGE:

       res = dispatchSetUsage(args);

       break;

   case NATIVE_WINDOW_SET_CROP:

       res = dispatchSetCrop(args);

       break;

   case NATIVE_WINDOW_SET_BUFFER_COUNT:

       res = dispatchSetBufferCount(args);

       break;

   case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:

       res = dispatchSetBuffersGeometry(args);

       break;

   case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:

       res = dispatchSetBuffersTransform(args);

       break;

   case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:

       res = dispatchSetBuffersTimestamp(args);

       break;

   case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:

       res = dispatchSetBuffersDimensions(args);

       break;

   case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:

       res = dispatchSetBuffersUserDimensions(args);

       break;

   case NATIVE_WINDOW_SET_BUFFERS_FORMAT:

        res = dispatchSetBuffersFormat(args);

       break;

   case NATIVE_WINDOW_LOCK:

       res = dispatchLock(args);

       break;

   case NATIVE_WINDOW_UNLOCK_AND_POST:

       res = dispatchUnlockAndPost(args);

       break;

   case NATIVE_WINDOW_SET_SCALING_MODE:

       res = dispatchSetScalingMode(args);

       break;

    case NATIVE_WINDOW_API_CONNECT:

        res = dispatchConnect(args);

       break;

   case NATIVE_WINDOW_API_DISCONNECT:

       res = dispatchDisconnect(args);

       break;

   default:

       res = NAME_NOT_FOUND;

       break;

    }

   return res;

}

 

int Surface::dispatchConnect(va_list args){

   int api = va_arg(args, int);

    return connect(api);

}

 

int Surface::connect(int api) {

   ATRACE_CALL();

   ALOGV("Surface::connect");

   Mutex::Autolock lock(mMutex);

   IGraphicBufferProducer::QueueBufferOutput output;

    int err =mGraphicBufferProducer->connect(api, &output);

   if (err == NO_ERROR) {

       uint32_t numPendingBuffers = 0;

        output.deflate(&mDefaultWidth,&mDefaultHeight, &mTransformHint,

                &numPendingBuffers);

       mConsumerRunningBehind = (numPendingBuffers >= 2);

    }

   if (!err && api == NATIVE_WINDOW_API_CPU) {

       mConnectedToCpu = true;

    }

   return err;

}

 

10.               BufferQueue::connect()

Frameworks/native/libs/gui/SurfaceQueue.cpp

status_t BufferQueue::connect(int api,QueueBufferOutput* output) {

   ATRACE_CALL();

   ST_LOGV("connect: api=%d", api);

   Mutex::Autolock lock(mMutex);

 

   if (mAbandoned) {

       ST_LOGE("connect: BufferQueue has been abandoned!");

       return NO_INIT;

    }

 

   if (mConsumerListener == NULL) {

       ST_LOGE("connect: BufferQueue has no consumer!");

       return NO_INIT;

    }

 

   int err = NO_ERROR;

   switch (api) {

       case NATIVE_WINDOW_API_EGL:

       case NATIVE_WINDOW_API_CPU:

       case NATIVE_WINDOW_API_MEDIA:

       case NATIVE_WINDOW_API_CAMERA:

           if (mConnectedApi != NO_CONNECTED_API) {

                ST_LOGE("connect: alreadyconnected (cur=%d, req=%d)",

                        mConnectedApi, api);

                err = -EINVAL;

           } else {

                mConnectedApi = api;

               output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,

                        mQueue.size());

           }

           break;

       default:

           err = -EINVAL;

           break;

    }

 

   mBufferHasBeenQueued = false;

 

   return err;

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值