Merge "Stagefright: ANW::connect in MediaPlayerService" into ics-mr0

This commit is contained in:
Jamie Gennis
2011-10-27 16:04:45 -07:00
committed by Android (Google) Code Review
4 changed files with 65 additions and 100 deletions

View File

@ -209,7 +209,6 @@ private:
status_t prepareAsync_l();
status_t getDuration_l(int *msec);
status_t attachNewPlayer(const sp<IMediaPlayer>& player);
void disconnectNativeWindow();
status_t reset_l();
sp<IMediaPlayer> mPlayer;
@ -233,8 +232,6 @@ private:
int mVideoHeight;
int mAudioSessionId;
float mSendLevel;
sp<ANativeWindow> mConnectedWindow;
sp<IBinder> mConnectedWindowBinder;
};
}; // namespace android

View File

@ -86,8 +86,6 @@ void MediaPlayer::disconnect()
if (p != 0) {
p->disconnect();
}
disconnectNativeWindow();
}
// always call with lock held
@ -221,63 +219,12 @@ status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *m
return mPlayer->getMetadata(update_only, apply_filter, metadata);
}
void MediaPlayer::disconnectNativeWindow() {
if (mConnectedWindow != NULL) {
status_t err = native_window_api_disconnect(mConnectedWindow.get(),
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
LOGW("native_window_api_disconnect returned an error: %s (%d)",
strerror(-err), err);
}
}
mConnectedWindow.clear();
}
status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
{
LOGV("setVideoSurface");
Mutex::Autolock _l(mLock);
if (mPlayer == 0) return NO_INIT;
sp<IBinder> binder(surface == NULL ? NULL : surface->asBinder());
if (mConnectedWindowBinder == binder) {
return OK;
}
if (surface != NULL) {
status_t err = native_window_api_connect(surface.get(),
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
LOGE("setVideoSurface failed: %d", err);
// Note that we must do the reset before disconnecting from the ANW.
// Otherwise queue/dequeue calls could be made on the disconnected
// ANW, which may result in errors.
reset_l();
disconnectNativeWindow();
return err;
}
}
// Note that we must set the player's new surface before disconnecting the
// old one. Otherwise queue/dequeue calls could be made on the disconnected
// ANW, which may result in errors.
status_t err = mPlayer->setVideoSurface(surface);
disconnectNativeWindow();
mConnectedWindow = surface;
if (err == OK) {
mConnectedWindowBinder = binder;
} else {
disconnectNativeWindow();
}
return err;
return mPlayer->setVideoSurface(surface);
}
status_t MediaPlayer::setVideoSurfaceTexture(
@ -286,48 +233,7 @@ status_t MediaPlayer::setVideoSurfaceTexture(
LOGV("setVideoSurfaceTexture");
Mutex::Autolock _l(mLock);
if (mPlayer == 0) return NO_INIT;
sp<IBinder> binder(surfaceTexture == NULL ? NULL :
surfaceTexture->asBinder());
if (mConnectedWindowBinder == binder) {
return OK;
}
sp<ANativeWindow> anw;
if (surfaceTexture != NULL) {
anw = new SurfaceTextureClient(surfaceTexture);
status_t err = native_window_api_connect(anw.get(),
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
LOGE("setVideoSurfaceTexture failed: %d", err);
// Note that we must do the reset before disconnecting from the ANW.
// Otherwise queue/dequeue calls could be made on the disconnected
// ANW, which may result in errors.
reset_l();
disconnectNativeWindow();
return err;
}
}
// Note that we must set the player's new SurfaceTexture before
// disconnecting the old one. Otherwise queue/dequeue calls could be made
// on the disconnected ANW, which may result in errors.
status_t err = mPlayer->setVideoSurfaceTexture(surfaceTexture);
disconnectNativeWindow();
mConnectedWindow = anw;
if (err == OK) {
mConnectedWindowBinder = binder;
} else {
disconnectNativeWindow();
}
return err;
return mPlayer->setVideoSurfaceTexture(surfaceTexture);
}
// must call with lock held

View File

@ -40,6 +40,7 @@
#include <binder/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>
#include <gui/SurfaceTextureClient.h>
#include <utils/Errors.h> // for status_t
#include <utils/String8.h>
#include <utils/SystemClock.h>
@ -528,6 +529,8 @@ void MediaPlayerService::Client::disconnect()
p->reset();
}
disconnectNativeWindow();
IPCThreadState::self()->flushCommands();
}
@ -789,13 +792,67 @@ status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface)
return p->setVideoSurface(surface);
}
void MediaPlayerService::Client::disconnectNativeWindow() {
if (mConnectedWindow != NULL) {
status_t err = native_window_api_disconnect(mConnectedWindow.get(),
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
LOGW("native_window_api_disconnect returned an error: %s (%d)",
strerror(-err), err);
}
}
mConnectedWindow.clear();
}
status_t MediaPlayerService::Client::setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture)
{
LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
return p->setVideoSurfaceTexture(surfaceTexture);
sp<IBinder> binder(surfaceTexture == NULL ? NULL :
surfaceTexture->asBinder());
if (mConnectedWindowBinder == binder) {
return OK;
}
sp<ANativeWindow> anw;
if (surfaceTexture != NULL) {
anw = new SurfaceTextureClient(surfaceTexture);
status_t err = native_window_api_connect(anw.get(),
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
LOGE("setVideoSurfaceTexture failed: %d", err);
// Note that we must do the reset before disconnecting from the ANW.
// Otherwise queue/dequeue calls could be made on the disconnected
// ANW, which may result in errors.
reset();
disconnectNativeWindow();
return err;
}
}
// Note that we must set the player's new SurfaceTexture before
// disconnecting the old one. Otherwise queue/dequeue calls could be made
// on the disconnected ANW, which may result in errors.
status_t err = p->setVideoSurfaceTexture(surfaceTexture);
disconnectNativeWindow();
mConnectedWindow = anw;
if (err == OK) {
mConnectedWindowBinder = binder;
} else {
disconnectNativeWindow();
}
return err;
}
status_t MediaPlayerService::Client::invoke(const Parcel& request,

View File

@ -318,6 +318,9 @@ private:
// @param type Of the metadata to be recorded.
void addNewMetadataUpdate(media::Metadata::Type type);
// Disconnect from the currently connected ANativeWindow.
void disconnectNativeWindow();
mutable Mutex mLock;
sp<MediaPlayerBase> mPlayer;
sp<MediaPlayerService> mService;
@ -329,6 +332,8 @@ private:
int32_t mConnId;
int mAudioSessionId;
uid_t mUID;
sp<ANativeWindow> mConnectedWindow;
sp<IBinder> mConnectedWindowBinder;
// Metadata filters.
media::Metadata::Filter mMetadataAllow; // protected by mLock