Merge "Stagefright: ANW::connect in MediaPlayerService" into ics-mr0
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user