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 prepareAsync_l();
|
||||||
status_t getDuration_l(int *msec);
|
status_t getDuration_l(int *msec);
|
||||||
status_t attachNewPlayer(const sp<IMediaPlayer>& player);
|
status_t attachNewPlayer(const sp<IMediaPlayer>& player);
|
||||||
void disconnectNativeWindow();
|
|
||||||
status_t reset_l();
|
status_t reset_l();
|
||||||
|
|
||||||
sp<IMediaPlayer> mPlayer;
|
sp<IMediaPlayer> mPlayer;
|
||||||
@ -233,8 +232,6 @@ private:
|
|||||||
int mVideoHeight;
|
int mVideoHeight;
|
||||||
int mAudioSessionId;
|
int mAudioSessionId;
|
||||||
float mSendLevel;
|
float mSendLevel;
|
||||||
sp<ANativeWindow> mConnectedWindow;
|
|
||||||
sp<IBinder> mConnectedWindowBinder;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
@ -86,8 +86,6 @@ void MediaPlayer::disconnect()
|
|||||||
if (p != 0) {
|
if (p != 0) {
|
||||||
p->disconnect();
|
p->disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectNativeWindow();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// always call with lock held
|
// 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);
|
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)
|
status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
|
||||||
{
|
{
|
||||||
LOGV("setVideoSurface");
|
LOGV("setVideoSurface");
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
if (mPlayer == 0) return NO_INIT;
|
if (mPlayer == 0) return NO_INIT;
|
||||||
|
return mPlayer->setVideoSurface(surface);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t MediaPlayer::setVideoSurfaceTexture(
|
status_t MediaPlayer::setVideoSurfaceTexture(
|
||||||
@ -286,48 +233,7 @@ status_t MediaPlayer::setVideoSurfaceTexture(
|
|||||||
LOGV("setVideoSurfaceTexture");
|
LOGV("setVideoSurfaceTexture");
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
if (mPlayer == 0) return NO_INIT;
|
if (mPlayer == 0) return NO_INIT;
|
||||||
|
return mPlayer->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_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// must call with lock held
|
// must call with lock held
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <binder/IServiceManager.h>
|
#include <binder/IServiceManager.h>
|
||||||
#include <binder/MemoryHeapBase.h>
|
#include <binder/MemoryHeapBase.h>
|
||||||
#include <binder/MemoryBase.h>
|
#include <binder/MemoryBase.h>
|
||||||
|
#include <gui/SurfaceTextureClient.h>
|
||||||
#include <utils/Errors.h> // for status_t
|
#include <utils/Errors.h> // for status_t
|
||||||
#include <utils/String8.h>
|
#include <utils/String8.h>
|
||||||
#include <utils/SystemClock.h>
|
#include <utils/SystemClock.h>
|
||||||
@ -528,6 +529,8 @@ void MediaPlayerService::Client::disconnect()
|
|||||||
p->reset();
|
p->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnectNativeWindow();
|
||||||
|
|
||||||
IPCThreadState::self()->flushCommands();
|
IPCThreadState::self()->flushCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,13 +792,67 @@ status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface)
|
|||||||
return p->setVideoSurface(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(
|
status_t MediaPlayerService::Client::setVideoSurfaceTexture(
|
||||||
const sp<ISurfaceTexture>& surfaceTexture)
|
const sp<ISurfaceTexture>& surfaceTexture)
|
||||||
{
|
{
|
||||||
LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
|
LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
|
||||||
sp<MediaPlayerBase> p = getPlayer();
|
sp<MediaPlayerBase> p = getPlayer();
|
||||||
if (p == 0) return UNKNOWN_ERROR;
|
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,
|
status_t MediaPlayerService::Client::invoke(const Parcel& request,
|
||||||
|
@ -318,6 +318,9 @@ private:
|
|||||||
// @param type Of the metadata to be recorded.
|
// @param type Of the metadata to be recorded.
|
||||||
void addNewMetadataUpdate(media::Metadata::Type type);
|
void addNewMetadataUpdate(media::Metadata::Type type);
|
||||||
|
|
||||||
|
// Disconnect from the currently connected ANativeWindow.
|
||||||
|
void disconnectNativeWindow();
|
||||||
|
|
||||||
mutable Mutex mLock;
|
mutable Mutex mLock;
|
||||||
sp<MediaPlayerBase> mPlayer;
|
sp<MediaPlayerBase> mPlayer;
|
||||||
sp<MediaPlayerService> mService;
|
sp<MediaPlayerService> mService;
|
||||||
@ -329,6 +332,8 @@ private:
|
|||||||
int32_t mConnId;
|
int32_t mConnId;
|
||||||
int mAudioSessionId;
|
int mAudioSessionId;
|
||||||
uid_t mUID;
|
uid_t mUID;
|
||||||
|
sp<ANativeWindow> mConnectedWindow;
|
||||||
|
sp<IBinder> mConnectedWindowBinder;
|
||||||
|
|
||||||
// Metadata filters.
|
// Metadata filters.
|
||||||
media::Metadata::Filter mMetadataAllow; // protected by mLock
|
media::Metadata::Filter mMetadataAllow; // protected by mLock
|
||||||
|
Reference in New Issue
Block a user