diff options
30 files changed, 268 insertions, 638 deletions
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index cce2400..1e29d82 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -156,6 +156,7 @@ public: MODE_NORMAL = 0, MODE_RINGTONE, MODE_IN_CALL, + MODE_IN_COMMUNICATION, NUM_MODES // not a valid entry, denotes end-of-list }; diff --git a/include/media/EffectApi.h b/include/media/EffectApi.h index 16fb43c..b97c22e 100644 --- a/include/media/EffectApi.h +++ b/include/media/EffectApi.h @@ -602,9 +602,9 @@ enum audio_device_e { // Audio mode enum audio_mode_e { - AUDIO_MODE_NORMAL, // phone idle - AUDIO_MODE_RINGTONE, // phone ringing - AUDIO_MODE_IN_CALL // phone call connected + AUDIO_MODE_NORMAL, // device idle + AUDIO_MODE_RINGTONE, // device ringing + AUDIO_MODE_IN_CALL // audio call connected (VoIP or telephony) }; // Values for "accessMode" field of buffer_config_t: diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index 3d77278..bba7ed7 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -34,7 +34,6 @@ public: virtual void disconnect() = 0; - virtual status_t setVideoISurface(const sp<ISurface>& surface) = 0; virtual status_t setVideoSurface(const sp<Surface>& surface) = 0; virtual status_t prepareAsync() = 0; virtual status_t start() = 0; diff --git a/include/media/IOMX.h b/include/media/IOMX.h index fa775e7..cb36bbb 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -120,30 +120,6 @@ public: node_id node, const char *parameter_name, OMX_INDEXTYPE *index) = 0; - - virtual sp<IOMXRenderer> createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) = 0; - - // Note: These methods are _not_ virtual, it exists as a wrapper around - // the virtual "createRenderer" method above facilitating extraction - // of the ISurface from a regular Surface or a java Surface object. - sp<IOMXRenderer> createRenderer( - const sp<Surface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight); - - sp<IOMXRenderer> createRendererFromJavaSurface( - JNIEnv *env, jobject javaSurface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight); }; struct omx_message { @@ -190,13 +166,6 @@ public: virtual void onMessage(const omx_message &msg) = 0; }; -class IOMXRenderer : public IInterface { -public: - DECLARE_META_INTERFACE(OMXRenderer); - - virtual void render(IOMX::buffer_id buffer) = 0; -}; - //////////////////////////////////////////////////////////////////////////////// class BnOMX : public BnInterface<IOMX> { @@ -213,13 +182,6 @@ public: uint32_t flags = 0); }; -class BnOMXRenderer : public BnInterface<IOMXRenderer> { -public: - virtual status_t onTransact( - uint32_t code, const Parcel &data, Parcel *reply, - uint32_t flags = 0); -}; - } // namespace android #endif // ANDROID_IOMX_H_ diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 2d55a55..672931e 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -106,7 +106,6 @@ public: const KeyedVector<String8, String8> *headers = NULL) = 0; virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; - virtual status_t setVideoISurface(const sp<ISurface>& surface) = 0; virtual status_t setVideoSurface(const sp<Surface>& surface) = 0; virtual status_t prepare() = 0; virtual status_t prepareAsync() = 0; diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h index 4fd281b..17908b4 100644 --- a/include/media/stagefright/HardwareAPI.h +++ b/include/media/stagefright/HardwareAPI.h @@ -19,8 +19,6 @@ #define HARDWARE_API_H_ #include <media/stagefright/OMXPluginBase.h> -#include <media/stagefright/VideoRenderer.h> -#include <surfaceflinger/ISurface.h> #include <ui/android_native_buffer.h> #include <utils/RefBase.h> @@ -91,13 +89,6 @@ struct UseAndroidNativeBufferParams { } // namespace android -extern android::VideoRenderer *createRenderer( - const android::sp<android::ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); - extern android::OMXPluginBase *createOMXPlugin(); #endif // HARDWARE_API_H_ diff --git a/include/media/stagefright/VideoRenderer.h b/include/media/stagefright/VideoRenderer.h deleted file mode 100644 index f80b277..0000000 --- a/include/media/stagefright/VideoRenderer.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef VIDEO_RENDERER_H_ - -#define VIDEO_RENDERER_H_ - -#include <sys/types.h> - -namespace android { - -class VideoRenderer { -public: - virtual ~VideoRenderer() {} - - virtual void render( - const void *data, size_t size, void *platformPrivate) = 0; - -protected: - VideoRenderer() {} - - VideoRenderer(const VideoRenderer &); - VideoRenderer &operator=(const VideoRenderer &); -}; - -} // namespace android - -#endif // VIDEO_RENDERER_H_ diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 1a46715..c287c0a 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -29,7 +29,6 @@ namespace android { enum { DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, SET_VIDEO_SURFACE, - SET_VIDEO_ISURFACE, PREPARE_ASYNC, START, STOP, @@ -65,15 +64,6 @@ public: remote()->transact(DISCONNECT, data, &reply); } - status_t setVideoISurface(const sp<ISurface>& surface) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeStrongBinder(surface->asBinder()); - remote()->transact(SET_VIDEO_ISURFACE, data, &reply); - return reply.readInt32(); - } - status_t setVideoSurface(const sp<Surface>& surface) { Parcel data, reply; @@ -245,12 +235,6 @@ status_t BnMediaPlayer::onTransact( disconnect(); return NO_ERROR; } break; - case SET_VIDEO_ISURFACE: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder()); - reply->writeInt32(setVideoISurface(surface)); - return NO_ERROR; - } break; case SET_VIDEO_SURFACE: { CHECK_INTERFACE(IMediaPlayer, data, reply); sp<Surface> surface = Surface::readFromParcel(data); diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index f975217..9ce6738 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -31,48 +31,9 @@ enum { FILL_BUFFER, EMPTY_BUFFER, GET_EXTENSION_INDEX, - CREATE_RENDERER, OBSERVER_ON_MSG, - RENDERER_RENDER, }; -sp<IOMXRenderer> IOMX::createRenderer( - const sp<Surface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) { - return createRenderer( - surface->getISurface(), - componentName, colorFormat, encodedWidth, encodedHeight, - displayWidth, displayHeight); -} - -sp<IOMXRenderer> IOMX::createRendererFromJavaSurface( - JNIEnv *env, jobject javaSurface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) { - jclass surfaceClass = env->FindClass("android/view/Surface"); - if (surfaceClass == NULL) { - LOGE("Can't find android/view/Surface"); - return NULL; - } - - jfieldID surfaceID = env->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - if (surfaceID == NULL) { - LOGE("Can't find Surface.mSurface"); - return NULL; - } - - sp<Surface> surface = (Surface *)env->GetIntField(javaSurface, surfaceID); - - return createRenderer( - surface, componentName, colorFormat, encodedWidth, - encodedHeight, displayWidth, displayHeight); -} - class BpOMX : public BpInterface<IOMX> { public: BpOMX(const sp<IBinder> &impl) @@ -395,28 +356,6 @@ public: return err; } - - virtual sp<IOMXRenderer> createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - - data.writeStrongBinder(surface->asBinder()); - data.writeCString(componentName); - data.writeInt32(colorFormat); - data.writeInt32(encodedWidth); - data.writeInt32(encodedHeight); - data.writeInt32(displayWidth); - data.writeInt32(displayHeight); - - remote()->transact(CREATE_RENDERER, data, &reply); - - return interface_cast<IOMXRenderer>(reply.readStrongBinder()); - } }; IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); @@ -767,33 +706,6 @@ status_t BnOMX::onTransact( return OK; } - case CREATE_RENDERER: - { - CHECK_INTERFACE(IOMX, data, reply); - - sp<ISurface> isurface = - interface_cast<ISurface>(data.readStrongBinder()); - - const char *componentName = data.readCString(); - - OMX_COLOR_FORMATTYPE colorFormat = - static_cast<OMX_COLOR_FORMATTYPE>(data.readInt32()); - - size_t encodedWidth = (size_t)data.readInt32(); - size_t encodedHeight = (size_t)data.readInt32(); - size_t displayWidth = (size_t)data.readInt32(); - size_t displayHeight = (size_t)data.readInt32(); - - sp<IOMXRenderer> renderer = - createRenderer(isurface, componentName, colorFormat, - encodedWidth, encodedHeight, - displayWidth, displayHeight); - - reply->writeStrongBinder(renderer->asBinder()); - - return OK; - } - default: return BBinder::onTransact(code, data, reply, flags); } @@ -839,44 +751,4 @@ status_t BnOMXObserver::onTransact( } } -//////////////////////////////////////////////////////////////////////////////// - -class BpOMXRenderer : public BpInterface<IOMXRenderer> { -public: - BpOMXRenderer(const sp<IBinder> &impl) - : BpInterface<IOMXRenderer>(impl) { - } - - virtual void render(IOMX::buffer_id buffer) { - Parcel data, reply; - data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)buffer); - - // NOTE: Do NOT make this a ONE_WAY call, it must be synchronous - // so that the caller knows when to recycle the buffer. - remote()->transact(RENDERER_RENDER, data, &reply); - } -}; - -IMPLEMENT_META_INTERFACE(OMXRenderer, "android.hardware.IOMXRenderer"); - -status_t BnOMXRenderer::onTransact( - uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { - switch (code) { - case RENDERER_RENDER: - { - CHECK_INTERFACE(IOMXRenderer, data, reply); - - IOMX::buffer_id buffer = (void*)data.readIntPtr(); - - render(buffer); - - return NO_ERROR; - } - - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - } // namespace android diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 34e41a1..54b292c 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -198,13 +198,6 @@ status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface) Mutex::Autolock _l(mLock); if (mPlayer == 0) return NO_INIT; - status_t err = mPlayer->setVideoISurface( - surface == NULL ? NULL : surface->getISurface()); - - if (err != OK) { - return err; - } - return mPlayer->setVideoSurface(surface); } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index e84c2dc..00e510b 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -864,14 +864,6 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64 return mStatus; } -status_t MediaPlayerService::Client::setVideoISurface(const sp<ISurface>& surface) -{ - LOGV("[%d] setVideoISurface(%p)", mConnId, surface.get()); - sp<MediaPlayerBase> p = getPlayer(); - if (p == 0) return UNKNOWN_ERROR; - return p->setVideoISurface(surface); -} - status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface) { LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get()); diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index e197cde..184324c 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -206,7 +206,6 @@ private: // IMediaPlayer interface virtual void disconnect(); - virtual status_t setVideoISurface(const sp<ISurface>& surface); virtual status_t setVideoSurface(const sp<Surface>& surface); virtual status_t prepareAsync(); virtual status_t start(); diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h index 06e4b70..aa8f3f0 100644 --- a/media/libmediaplayerservice/MidiFile.h +++ b/media/libmediaplayerservice/MidiFile.h @@ -35,7 +35,6 @@ public: const char* path, const KeyedVector<String8, String8> *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); - virtual status_t setVideoISurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; } virtual status_t setVideoSurface(const sp<Surface>& surface) { return UNKNOWN_ERROR; } virtual status_t prepare(); virtual status_t prepareAsync(); diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp index e0957f6..58ef99b 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.cpp +++ b/media/libmediaplayerservice/StagefrightPlayer.cpp @@ -44,13 +44,6 @@ status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length return mPlayer->setDataSource(dup(fd), offset, length); } -status_t StagefrightPlayer::setVideoISurface(const sp<ISurface> &surface) { - LOGV("setVideoISurface"); - - mPlayer->setISurface(surface); - return OK; -} - status_t StagefrightPlayer::setVideoSurface(const sp<Surface> &surface) { LOGV("setVideoSurface"); diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h index 3899447..c4a2588 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.h +++ b/media/libmediaplayerservice/StagefrightPlayer.h @@ -35,7 +35,6 @@ public: const char *url, const KeyedVector<String8, String8> *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); - virtual status_t setVideoISurface(const sp<ISurface> &surface); virtual status_t setVideoSurface(const sp<Surface> &surface); virtual status_t prepare(); virtual status_t prepareAsync(); diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h index 5eaf592..6abd8e3 100644 --- a/media/libmediaplayerservice/TestPlayerStub.h +++ b/media/libmediaplayerservice/TestPlayerStub.h @@ -75,9 +75,6 @@ class TestPlayerStub : public MediaPlayerInterface { // All the methods below wrap the mPlayer instance. - virtual status_t setVideoISurface(const android::sp<android::ISurface>& s) { - return mPlayer->setVideoISurface(s); - } virtual status_t setVideoSurface(const android::sp<android::Surface>& s) { return mPlayer->setVideoSurface(s); } diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 41f5f30..538e7bf 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -79,39 +79,18 @@ private: AwesomeEvent &operator=(const AwesomeEvent &); }; -struct AwesomeRemoteRenderer : public AwesomeRenderer { - AwesomeRemoteRenderer(const sp<IOMXRenderer> &target) - : mTarget(target) { - } - - virtual void render(MediaBuffer *buffer) { - void *id; - if (buffer->meta_data()->findPointer(kKeyBufferID, &id)) { - mTarget->render((IOMX::buffer_id)id); - } - } - -private: - sp<IOMXRenderer> mTarget; - - AwesomeRemoteRenderer(const AwesomeRemoteRenderer &); - AwesomeRemoteRenderer &operator=(const AwesomeRemoteRenderer &); -}; - struct AwesomeLocalRenderer : public AwesomeRenderer { AwesomeLocalRenderer( - bool previewOnly, - const char *componentName, OMX_COLOR_FORMATTYPE colorFormat, - const sp<ISurface> &isurface, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight) - : mTarget(NULL), - mLibHandle(NULL) { - init(previewOnly, componentName, - colorFormat, isurface, surface, displayWidth, - displayHeight, decodedWidth, decodedHeight); + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees) + : mTarget(NULL) { + init(colorFormat, surface, + displayWidth, displayHeight, + decodedWidth, decodedHeight, + rotationDegrees); } virtual void render(MediaBuffer *buffer) { @@ -127,78 +106,39 @@ protected: virtual ~AwesomeLocalRenderer() { delete mTarget; mTarget = NULL; - - if (mLibHandle) { - dlclose(mLibHandle); - mLibHandle = NULL; - } } private: - VideoRenderer *mTarget; - void *mLibHandle; + SoftwareRenderer *mTarget; void init( - bool previewOnly, - const char *componentName, OMX_COLOR_FORMATTYPE colorFormat, - const sp<ISurface> &isurface, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees); AwesomeLocalRenderer(const AwesomeLocalRenderer &); AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);; }; void AwesomeLocalRenderer::init( - bool previewOnly, - const char *componentName, OMX_COLOR_FORMATTYPE colorFormat, - const sp<ISurface> &isurface, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight) { - if (!previewOnly) { - // We will stick to the vanilla software-color-converting renderer - // for "previewOnly" mode, to avoid unneccessarily switching overlays - // more often than necessary. - - mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW); - - if (mLibHandle) { - typedef VideoRenderer *(*CreateRendererFunc)( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); - - CreateRendererFunc func = - (CreateRendererFunc)dlsym( - mLibHandle, - "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20" - "OMX_COLOR_FORMATTYPEjjjj"); - - if (func) { - mTarget = - (*func)(isurface, componentName, colorFormat, - displayWidth, displayHeight, - decodedWidth, decodedHeight); - } - } - } - - if (mTarget == NULL) { - mTarget = new SoftwareRenderer( - colorFormat, surface, displayWidth, displayHeight, - decodedWidth, decodedHeight); - } + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees) { + mTarget = new SoftwareRenderer( + colorFormat, surface, displayWidth, displayHeight, + decodedWidth, decodedHeight, rotationDegrees); } struct AwesomeNativeWindowRenderer : public AwesomeRenderer { - AwesomeNativeWindowRenderer(const sp<ANativeWindow> &nativeWindow) + AwesomeNativeWindowRenderer( + const sp<ANativeWindow> &nativeWindow, + int32_t rotationDegrees) : mNativeWindow(nativeWindow) { + applyRotation(rotationDegrees); } virtual void render(MediaBuffer *buffer) { @@ -220,6 +160,22 @@ protected: private: sp<ANativeWindow> mNativeWindow; + void applyRotation(int32_t rotationDegrees) { + uint32_t transform; + switch (rotationDegrees) { + case 0: transform = 0; break; + case 90: transform = HAL_TRANSFORM_ROT_90; break; + case 180: transform = HAL_TRANSFORM_ROT_180; break; + case 270: transform = HAL_TRANSFORM_ROT_270; break; + default: transform = 0; break; + } + + if (transform) { + CHECK_EQ(0, native_window_set_buffers_transform( + mNativeWindow.get(), transform)); + } + } + AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &); AwesomeNativeWindowRenderer &operator=( const AwesomeNativeWindowRenderer &); @@ -863,58 +819,65 @@ void AwesomePlayer::notifyVideoSize_l() { CHECK(meta->findInt32(kKeyWidth, &decodedWidth)); CHECK(meta->findInt32(kKeyHeight, &decodedHeight)); - notifyListener_l(MEDIA_SET_VIDEO_SIZE, decodedWidth, decodedHeight); + int32_t rotationDegrees; + if (!mVideoTrack->getFormat()->findInt32( + kKeyRotation, &rotationDegrees)) { + rotationDegrees = 0; + } + + if (rotationDegrees == 90 || rotationDegrees == 270) { + notifyListener_l( + MEDIA_SET_VIDEO_SIZE, decodedHeight, decodedWidth); + } else { + notifyListener_l( + MEDIA_SET_VIDEO_SIZE, decodedWidth, decodedHeight); + } } void AwesomePlayer::initRenderer_l() { - if (mSurface != NULL || mISurface != NULL) { - sp<MetaData> meta = mVideoSource->getFormat(); + if (mSurface == NULL) { + return; + } - int32_t format; - const char *component; - int32_t decodedWidth, decodedHeight; - CHECK(meta->findInt32(kKeyColorFormat, &format)); - CHECK(meta->findCString(kKeyDecoderComponent, &component)); - CHECK(meta->findInt32(kKeyWidth, &decodedWidth)); - CHECK(meta->findInt32(kKeyHeight, &decodedHeight)); + sp<MetaData> meta = mVideoSource->getFormat(); - mVideoRenderer.clear(); + int32_t format; + const char *component; + int32_t decodedWidth, decodedHeight; + CHECK(meta->findInt32(kKeyColorFormat, &format)); + CHECK(meta->findCString(kKeyDecoderComponent, &component)); + CHECK(meta->findInt32(kKeyWidth, &decodedWidth)); + CHECK(meta->findInt32(kKeyHeight, &decodedHeight)); - // Must ensure that mVideoRenderer's destructor is actually executed - // before creating a new one. - IPCThreadState::self()->flushCommands(); + int32_t rotationDegrees; + if (!mVideoTrack->getFormat()->findInt32( + kKeyRotation, &rotationDegrees)) { + rotationDegrees = 0; + } - if (mSurface != NULL) { - if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) { - // Hardware decoders avoid the CPU color conversion by decoding - // directly to ANativeBuffers, so we must use a renderer that - // just pushes those buffers to the ANativeWindow. - mVideoRenderer = new AwesomeNativeWindowRenderer(mSurface); - } else { - // Other decoders are instantiated locally and as a consequence - // allocate their buffers in local address space. This renderer - // then performs a color conversion and copy to get the data - // into the ANativeBuffer. - mVideoRenderer = new AwesomeLocalRenderer( - false, // previewOnly - component, - (OMX_COLOR_FORMATTYPE)format, - mISurface, - mSurface, - mVideoWidth, mVideoHeight, - decodedWidth, decodedHeight); - } - } else { - // Our OMX codecs allocate buffers on the media_server side - // therefore they require a remote IOMXRenderer that knows how - // to display them. - mVideoRenderer = new AwesomeRemoteRenderer( - mClient.interface()->createRenderer( - mISurface, component, - (OMX_COLOR_FORMATTYPE)format, - decodedWidth, decodedHeight, - mVideoWidth, mVideoHeight)); - } + mVideoRenderer.clear(); + + // Must ensure that mVideoRenderer's destructor is actually executed + // before creating a new one. + IPCThreadState::self()->flushCommands(); + + if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) { + // Hardware decoders avoid the CPU color conversion by decoding + // directly to ANativeBuffers, so we must use a renderer that + // just pushes those buffers to the ANativeWindow. + mVideoRenderer = + new AwesomeNativeWindowRenderer(mSurface, rotationDegrees); + } else { + // Other decoders are instantiated locally and as a consequence + // allocate their buffers in local address space. This renderer + // then performs a color conversion and copy to get the data + // into the ANativeBuffer. + mVideoRenderer = new AwesomeLocalRenderer( + (OMX_COLOR_FORMATTYPE)format, + mSurface, + mVideoWidth, mVideoHeight, + decodedWidth, decodedHeight, + rotationDegrees); } } @@ -958,12 +921,6 @@ bool AwesomePlayer::isPlaying() const { return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN); } -void AwesomePlayer::setISurface(const sp<ISurface> &isurface) { - Mutex::Autolock autoLock(mLock); - - mISurface = isurface; -} - void AwesomePlayer::setSurface(const sp<Surface> &surface) { Mutex::Autolock autoLock(mLock); @@ -1897,18 +1854,16 @@ status_t AwesomePlayer::resume() { mFlags = state->mFlags & (AUTO_LOOPING | LOOPING | AT_EOS); - if (state->mLastVideoFrame && (mSurface != NULL || mISurface != NULL)) { + if (state->mLastVideoFrame && mSurface != NULL) { mVideoRenderer = new AwesomeLocalRenderer( - true, // previewOnly - "", (OMX_COLOR_FORMATTYPE)state->mColorFormat, - mISurface, mSurface, state->mVideoWidth, state->mVideoHeight, state->mDecodedWidth, - state->mDecodedHeight); + state->mDecodedHeight, + 0); mVideoRendererIsPreview = true; diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 2e94a12..bb929fd 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -27,11 +27,11 @@ #include <stdlib.h> #include <string.h> +#include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/DataSource.h> #include "include/ESDS.h" #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaBufferGroup.h> -#include <media/stagefright/MediaDebug.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaSource.h> #include <media/stagefright/MetaData.h> @@ -766,55 +766,11 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { case FOURCC('t', 'k', 'h', 'd'): { - if (chunk_data_size < 4) { - return ERROR_MALFORMED; - } - - uint8_t version; - if (mDataSource->readAt(data_offset, &version, 1) < 1) { - return ERROR_IO; - } - - uint64_t ctime, mtime, duration; - int32_t id; - uint32_t width, height; - - if (version == 1) { - if (chunk_data_size != 36 + 60) { - return ERROR_MALFORMED; - } - - uint8_t buffer[36 + 60]; - if (mDataSource->readAt( - data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { - return ERROR_IO; - } - - ctime = U64_AT(&buffer[4]); - mtime = U64_AT(&buffer[12]); - id = U32_AT(&buffer[20]); - duration = U64_AT(&buffer[28]); - width = U32_AT(&buffer[88]); - height = U32_AT(&buffer[92]); - } else if (version == 0) { - if (chunk_data_size != 24 + 60) { - return ERROR_MALFORMED; - } - - uint8_t buffer[24 + 60]; - if (mDataSource->readAt( - data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { - return ERROR_IO; - } - ctime = U32_AT(&buffer[4]); - mtime = U32_AT(&buffer[8]); - id = U32_AT(&buffer[12]); - duration = U32_AT(&buffer[20]); - width = U32_AT(&buffer[76]); - height = U32_AT(&buffer[80]); + status_t err; + if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { + return err; } - mLastTrack->meta->setInt32(kKeyTrackID, id); *offset += chunk_size; break; } @@ -1275,6 +1231,93 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { return OK; } +status_t MPEG4Extractor::parseTrackHeader( + off_t data_offset, off_t data_size) { + if (data_size < 4) { + return ERROR_MALFORMED; + } + + uint8_t version; + if (mDataSource->readAt(data_offset, &version, 1) < 1) { + return ERROR_IO; + } + + size_t dynSize = (version == 1) ? 36 : 24; + + uint8_t buffer[36 + 60]; + + if (data_size != (off_t)dynSize + 60) { + return ERROR_MALFORMED; + } + + if (mDataSource->readAt( + data_offset, buffer, data_size) < (ssize_t)data_size) { + return ERROR_IO; + } + + uint64_t ctime, mtime, duration; + int32_t id; + + if (version == 1) { + ctime = U64_AT(&buffer[4]); + mtime = U64_AT(&buffer[12]); + id = U32_AT(&buffer[20]); + duration = U64_AT(&buffer[28]); + } else { + CHECK_EQ((unsigned)version, 0u); + + ctime = U32_AT(&buffer[4]); + mtime = U32_AT(&buffer[8]); + id = U32_AT(&buffer[12]); + duration = U32_AT(&buffer[20]); + } + + mLastTrack->meta->setInt32(kKeyTrackID, id); + + size_t matrixOffset = dynSize + 16; + int32_t a00 = U32_AT(&buffer[matrixOffset]); + int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); + int32_t dx = U32_AT(&buffer[matrixOffset + 8]); + int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); + int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); + int32_t dy = U32_AT(&buffer[matrixOffset + 20]); + +#if 0 + LOGI("x' = %.2f * x + %.2f * y + %.2f", + a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); + LOGI("y' = %.2f * x + %.2f * y + %.2f", + a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); +#endif + + uint32_t rotationDegrees; + + static const int32_t kFixedOne = 0x10000; + if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { + // Identity, no rotation + rotationDegrees = 0; + } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { + rotationDegrees = 90; + } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { + rotationDegrees = 270; + } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { + rotationDegrees = 180; + } else { + LOGW("We only support 0,90,180,270 degree rotation matrices"); + rotationDegrees = 0; + } + + if (rotationDegrees != 0) { + mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); + } + +#if 0 + uint32_t width = U32_AT(&buffer[dynSize + 52]); + uint32_t height = U32_AT(&buffer[dynSize + 56]); +#endif + + return OK; +} + status_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { if (size < 4) { return ERROR_MALFORMED; @@ -1588,7 +1631,7 @@ MPEG4Source::MPEG4Source( const uint8_t *ptr = (const uint8_t *)data; CHECK(size >= 7); - CHECK_EQ(ptr[0], 1); // configurationVersion == 1 + CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 // The number of bytes used to encode the length of a NAL unit. mNALLengthSize = 1 + (ptr[4] & 3); @@ -1736,7 +1779,7 @@ status_t MPEG4Source::read( } uint32_t sampleTime; - CHECK_EQ(OK, mSampleTable->getMetaDataForSample( + CHECK_EQ((status_t)OK, mSampleTable->getMetaDataForSample( sampleIndex, NULL, NULL, &sampleTime)); if (mode == ReadOptions::SEEK_CLOSEST) { @@ -1783,7 +1826,7 @@ status_t MPEG4Source::read( err = mGroup->acquire_buffer(&mBuffer); if (err != OK) { - CHECK_EQ(mBuffer, NULL); + CHECK(mBuffer == NULL); return err; } } diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp index 662a84a..3d507ca 100644 --- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp +++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp @@ -35,7 +35,8 @@ SoftwareRenderer::SoftwareRenderer( OMX_COLOR_FORMATTYPE colorFormat, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight) + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees) : mColorFormat(colorFormat), mConverter(NULL), mYUVMode(None), @@ -95,6 +96,20 @@ SoftwareRenderer::SoftwareRenderer( CHECK_EQ(0, native_window_set_buffers_geometry( mSurface.get(), mDecodedWidth, mDecodedHeight, halFormat)); + + uint32_t transform; + switch (rotationDegrees) { + case 0: transform = 0; break; + case 90: transform = HAL_TRANSFORM_ROT_90; break; + case 180: transform = HAL_TRANSFORM_ROT_180; break; + case 270: transform = HAL_TRANSFORM_ROT_270; break; + default: transform = 0; break; + } + + if (transform) { + CHECK_EQ(0, native_window_set_buffers_transform( + mSurface.get(), transform)); + } } SoftwareRenderer::~SoftwareRenderer() { diff --git a/media/libstagefright/httplive/LiveSource.cpp b/media/libstagefright/httplive/LiveSource.cpp index 39e3e75..f9d27eb 100644 --- a/media/libstagefright/httplive/LiveSource.cpp +++ b/media/libstagefright/httplive/LiveSource.cpp @@ -278,7 +278,19 @@ bool LiveSource::switchToNext() { } if (mLastFetchTimeUs < 0) { - mPlaylistIndex = 0; + if (isSeekable()) { + mPlaylistIndex = 0; + } else { + // This is live streamed content, the first seqnum in the + // various bandwidth' streams may be slightly off, so don't + // start at the very first entry. + // With a segment duration of 6-10secs, this really only + // delays playback up to 30secs compared to real time. + mPlaylistIndex = 3; + if (mPlaylistIndex >= mPlaylist->size()) { + mPlaylistIndex = mPlaylist->size() - 1; + } + } } else { if (nextSequenceNumber < mFirstItemSequenceNumber || nextSequenceNumber diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 302a1ba..4e63b7a 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -79,7 +79,6 @@ struct AwesomePlayer { bool isPlaying() const; - void setISurface(const sp<ISurface> &isurface); void setSurface(const sp<Surface> &surface); void setAudioSink(const sp<MediaPlayerBase::AudioSink> &audioSink); status_t setLooping(bool shouldLoop); @@ -130,7 +129,6 @@ private: bool mQueueStarted; wp<MediaPlayerBase> mListener; - sp<ISurface> mISurface; sp<Surface> mSurface; sp<MediaPlayerBase::AudioSink> mAudioSink; diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h index 4e31059..bc2e4dc 100644 --- a/media/libstagefright/include/MPEG4Extractor.h +++ b/media/libstagefright/include/MPEG4Extractor.h @@ -88,6 +88,8 @@ private: bool mIsDrm; status_t parseDrmSINF(off_t *offset, off_t data_offset); + status_t parseTrackHeader(off_t data_offset, off_t data_size); + MPEG4Extractor(const MPEG4Extractor &); MPEG4Extractor &operator=(const MPEG4Extractor &); }; diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h index 5a6c96f..5fed98a 100644 --- a/media/libstagefright/include/OMX.h +++ b/media/libstagefright/include/OMX.h @@ -97,13 +97,6 @@ public: const char *parameter_name, OMX_INDEXTYPE *index); - virtual sp<IOMXRenderer> createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight); - virtual void binderDied(const wp<IBinder> &the_late_who); OMX_ERRORTYPE OnEvent( diff --git a/media/libstagefright/include/SoftwareRenderer.h b/media/libstagefright/include/SoftwareRenderer.h index 8d58056..9cafc68 100644 --- a/media/libstagefright/include/SoftwareRenderer.h +++ b/media/libstagefright/include/SoftwareRenderer.h @@ -19,25 +19,24 @@ #define SOFTWARE_RENDERER_H_ #include <media/stagefright/ColorConverter.h> -#include <media/stagefright/VideoRenderer.h> #include <utils/RefBase.h> namespace android { class Surface; -class MemoryHeapBase; -class SoftwareRenderer : public VideoRenderer { +class SoftwareRenderer { public: SoftwareRenderer( OMX_COLOR_FORMATTYPE colorFormat, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees); - virtual ~SoftwareRenderer(); + ~SoftwareRenderer(); - virtual void render( + void render( const void *data, size_t size, void *platformPrivate); private: diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index f9f638f..4e9920b 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -24,14 +24,11 @@ #include <sys/resource.h> #include "../include/OMX.h" -#include "OMXRenderer.h" #include "../include/OMXNodeInstance.h" -#include "../include/SoftwareRenderer.h" #include <binder/IMemory.h> #include <media/stagefright/MediaDebug.h> -#include <media/stagefright/VideoRenderer.h> #include <utils/threads.h> #include "OMXMaster.h" @@ -442,110 +439,4 @@ void OMX::invalidateNodeID_l(node_id node) { mNodeIDToInstance.removeItem(node); } -//////////////////////////////////////////////////////////////////////////////// - -struct SharedVideoRenderer : public VideoRenderer { - SharedVideoRenderer(void *libHandle, VideoRenderer *obj) - : mLibHandle(libHandle), - mObj(obj) { - } - - virtual ~SharedVideoRenderer() { - delete mObj; - mObj = NULL; - - dlclose(mLibHandle); - mLibHandle = NULL; - } - - virtual void render( - const void *data, size_t size, void *platformPrivate) { - return mObj->render(data, size, platformPrivate); - } - -private: - void *mLibHandle; - VideoRenderer *mObj; - - SharedVideoRenderer(const SharedVideoRenderer &); - SharedVideoRenderer &operator=(const SharedVideoRenderer &); -}; - -sp<IOMXRenderer> OMX::createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) { - Mutex::Autolock autoLock(mLock); - - VideoRenderer *impl = NULL; - - void *libHandle = dlopen("libstagefrighthw.so", RTLD_NOW); - - if (libHandle) { - typedef VideoRenderer *(*CreateRendererFunc)( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); - - CreateRendererFunc func = - (CreateRendererFunc)dlsym( - libHandle, - "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20" - "OMX_COLOR_FORMATTYPEjjjj"); - - if (func) { - impl = (*func)(surface, componentName, colorFormat, - displayWidth, displayHeight, encodedWidth, encodedHeight); - - if (impl) { - impl = new SharedVideoRenderer(libHandle, impl); - libHandle = NULL; - } - } - - if (libHandle) { - dlclose(libHandle); - libHandle = NULL; - } - } - - if (!impl) { -#if 0 - LOGW("Using software renderer."); - impl = new SoftwareRenderer( - colorFormat, - surface, - displayWidth, displayHeight, - encodedWidth, encodedHeight); -#else - CHECK(!"Should not be here."); - return NULL; -#endif - } - - return new OMXRenderer(impl); -} - -OMXRenderer::OMXRenderer(VideoRenderer *impl) - : mImpl(impl) { -} - -OMXRenderer::~OMXRenderer() { - delete mImpl; - mImpl = NULL; -} - -void OMXRenderer::render(IOMX::buffer_id buffer) { - OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; - - mImpl->render( - header->pBuffer + header->nOffset, - header->nFilledLen, - header->pPlatformPrivate); -} - } // namespace android diff --git a/media/libstagefright/omx/OMXRenderer.h b/media/libstagefright/omx/OMXRenderer.h deleted file mode 100644 index 4d194ce..0000000 --- a/media/libstagefright/omx/OMXRenderer.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OMX_RENDERER_H_ - -#define OMX_RENDERER_H_ - -#include <media/IOMX.h> - -namespace android { - -class VideoRenderer; - -class OMXRenderer : public BnOMXRenderer { -public: - // Assumes ownership of "impl". - OMXRenderer(VideoRenderer *impl); - virtual ~OMXRenderer(); - - virtual void render(IOMX::buffer_id buffer); - -private: - VideoRenderer *mImpl; - - OMXRenderer(const OMXRenderer &); - OMXRenderer &operator=(const OMXRenderer &); -}; - -} // namespace android - -#endif // OMX_RENDERER_H_ diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h index fafd221..900b517 100644 --- a/media/mtp/MtpDatabase.h +++ b/media/mtp/MtpDatabase.h @@ -42,6 +42,7 @@ public: virtual void endSendObject(const char* path, MtpObjectHandle handle, MtpObjectFormat format, + int64_t size, bool succeeded) = 0; virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID, diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 6cf70ec..ca13636 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -624,6 +624,7 @@ MtpResponseCode MtpServer::doSendObjectInfo() { mData.getString(modified); // date modified // keywords follow + LOGD("name: %s format: %04X\n", (const char *)name, format); time_t modifiedTime; if (!parseDateTime(modified, modifiedTime)) modifiedTime = 0; @@ -663,6 +664,7 @@ MtpResponseCode MtpServer::doSendObject() { MtpResponseCode result = MTP_RESPONSE_OK; mode_t mask; int ret; + uint64_t actualSize = -1; if (mSendObjectHandle == kInvalidObjectHandle) { LOGE("Expected SendObjectInfo before SendObject"); @@ -692,6 +694,7 @@ MtpResponseCode MtpServer::doSendObject() { mfr.offset = 0; mfr.length = mSendObjectFileSize; + LOGD("receiving %s\n", (const char *)mSendObjectFilePath); // transfer the file ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); close(mfr.fd); @@ -704,11 +707,18 @@ MtpResponseCode MtpServer::doSendObject() { result = MTP_RESPONSE_TRANSACTION_CANCELLED; else result = MTP_RESPONSE_GENERAL_ERROR; + } else if (mSendObjectFileSize == 0xFFFFFFFF) { + // actual size is likely > 4 gig so stat the file to compute actual length + struct stat s; + if (lstat(mSendObjectFilePath, &s) == 0) { + actualSize = s.st_size; + LOGD("actualSize: %lld\n", actualSize); + } } done: mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat, - result == MTP_RESPONSE_OK); + actualSize, result == MTP_RESPONSE_OK); mSendObjectHandle = kInvalidObjectHandle; mSendObjectFormat = 0; return result; diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index cd9b07e..84dd022 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -5808,7 +5808,8 @@ uint32_t AudioFlinger::EffectModule::deviceAudioSystemToEffectApi(uint32_t devic const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = { AUDIO_MODE_NORMAL, // AudioSystem::MODE_NORMAL AUDIO_MODE_RINGTONE, // AudioSystem::MODE_RINGTONE - AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_CALL + AUDIO_MODE_IN_CALL, // AudioSystem::MODE_IN_CALL + AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_COMMUNICATION, same conversion as for MODE_IN_CALL }; int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode) diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp index b17584a..e3b5db1 100644 --- a/services/audioflinger/AudioPolicyManagerBase.cpp +++ b/services/audioflinger/AudioPolicyManagerBase.cpp @@ -246,7 +246,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) // if leaving call state, handle special case of active streams // pertaining to sonification strategy see handleIncallSonification() - if (mPhoneState == AudioSystem::MODE_IN_CALL) { + if (isInCall()) { LOGV("setPhoneState() in call state management: new state is %d", state); for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { handleIncallSonification(stream, false, true); @@ -259,16 +259,21 @@ void AudioPolicyManagerBase::setPhoneState(int state) bool force = false; // are we entering or starting a call - if ((oldState != AudioSystem::MODE_IN_CALL) && (state == AudioSystem::MODE_IN_CALL)) { + if (!isStateInCall(oldState) && isStateInCall(state)) { LOGV(" Entering call in setPhoneState()"); // force routing command to audio hardware when starting a call // even if no device change is needed force = true; - } else if ((oldState == AudioSystem::MODE_IN_CALL) && (state != AudioSystem::MODE_IN_CALL)) { + } else if (isStateInCall(oldState) && !isStateInCall(state)) { LOGV(" Exiting call in setPhoneState()"); // force routing command to audio hardware when exiting a call // even if no device change is needed force = true; + } else if (isStateInCall(state) && (state != oldState)) { + LOGV(" Switching between telephony and VoIP in setPhoneState()"); + // force routing command to audio hardware when switching between telephony and VoIP + // even if no device change is needed + force = true; } // check for device and output changes triggered by new phone state @@ -290,7 +295,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) // force routing command to audio hardware when ending call // even if no device change is needed - if (oldState == AudioSystem::MODE_IN_CALL && newDevice == 0) { + if (isStateInCall(oldState) && newDevice == 0) { newDevice = hwOutputDesc->device(); } @@ -298,7 +303,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) // immediately and delay the route change to avoid sending the ring tone // tail into the earpiece or headset. int delayMs = 0; - if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) { + if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) { // delay the device change command by twice the output latency to have some margin // and be sure that audio buffers not yet affected by the mute are out when // we actually apply the route change @@ -311,7 +316,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) // if entering in call state, handle special case of active streams // pertaining to sonification strategy see handleIncallSonification() - if (state == AudioSystem::MODE_IN_CALL) { + if (isStateInCall(state)) { LOGV("setPhoneState() in call state management: new state is %d", state); // unmute the ringing tone after a sufficient delay if it was muted before // setting output device above @@ -586,7 +591,7 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, setOutputDevice(output, getNewDevice(output)); // handle special case for sonification while in call - if (mPhoneState == AudioSystem::MODE_IN_CALL) { + if (isInCall()) { handleIncallSonification(stream, true, false); } @@ -611,7 +616,7 @@ status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); // handle special case for sonification while in call - if (mPhoneState == AudioSystem::MODE_IN_CALL) { + if (isInCall()) { handleIncallSonification(stream, false, false); } @@ -1478,7 +1483,7 @@ uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fro // use device for strategy media // 4: the strategy DTMF is active on the hardware output: // use device for strategy DTMF - if (mPhoneState == AudioSystem::MODE_IN_CALL || + if (isInCall() || outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { @@ -1533,7 +1538,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, switch (strategy) { case STRATEGY_DTMF: - if (mPhoneState != AudioSystem::MODE_IN_CALL) { + if (!isInCall()) { // when off call, DTMF strategy follows the same rules as MEDIA strategy device = getDeviceForStrategy(STRATEGY_MEDIA, false); break; @@ -1546,7 +1551,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, // of priority switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { case AudioSystem::FORCE_BT_SCO: - if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) { + if (!isInCall() || strategy != STRATEGY_DTMF) { device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; if (device) break; } @@ -1566,7 +1571,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, if (device) break; #ifdef WITH_A2DP // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP - if (mPhoneState != AudioSystem::MODE_IN_CALL) { + if (!isInCall()) { device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; if (device) break; device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; @@ -1580,14 +1585,14 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, break; case AudioSystem::FORCE_SPEAKER: - if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) { + if (!isInCall() || strategy != STRATEGY_DTMF) { device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; if (device) break; } #ifdef WITH_A2DP // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to // A2DP speaker when forcing to speaker output - if (mPhoneState != AudioSystem::MODE_IN_CALL) { + if (!isInCall()) { device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; if (device) break; } @@ -1604,7 +1609,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by // handleIncallSonification(). - if (mPhoneState == AudioSystem::MODE_IN_CALL) { + if (isInCall()) { device = getDeviceForStrategy(STRATEGY_PHONE, false); break; } @@ -1971,6 +1976,16 @@ void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, } } +bool AudioPolicyManagerBase::isInCall() +{ + return isStateInCall(mPhoneState); +} + +bool AudioPolicyManagerBase::isStateInCall(int state) { + return ((state == AudioSystem::MODE_IN_CALL) || + (state == AudioSystem::MODE_IN_COMMUNICATION)); +} + bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream, uint32_t samplingRate, uint32_t format, |